Framework Madness!

And other adventures C# and asp.net …

Posts Tagged ‘linq

Asp.net MVC 2 – Of(T).Item for Html.DisplayFor

with one comment

Sometimes the easiest solutions are not always obvious. Take for example  if you try to call against the indexer of a list when calling ‘Html.DisplayFor’ such as:

   1: <%
   1: for (int i = 0; i < Model.Elements.Count; i++){

%>

   2:       <%
   1: =Html.DisplayFor(m => m.Elements[i])  

%>

   3: <%
   1: }

%>

You get the following error:

System.InvalidOperationException: Templates can be used only with field and property accessor expressions.

 

Well – that sucks. And so I went and made workarounds such as DisplayItemFor, and yet found it wanting. And I explored into the bowels of lambda expressions, and I wanted out.

And then it hit me. You can only return expressions that are for properties or fields. Okay – so let’s say I do something like call the indexer and then a property on the returned object:

   1: <%
   1: =Html.DisplayFor(m => m.Elements[i].Title)  

%>

Okay – that actually works because we end with a property expression. But what if you use a foreach loop instead. Here is the ‘Html.DisplayFor’ call:

   1: <%
   1: =Html.DisplayFor(m => m.Elements[m.Elements.IndexOf(element)].Title)  

%>

And that works to … but who wants to write that? I don’t. And you still don’t have the capability of calling an object template for just the element after all of that work.

Okay – so what about using Linq? Actually, you can make that happen if you just remember to end with a field or property expression:

   1: <%
   1: =Html.DisplayFor(m => m.Elements.Where( e=> e == element ).Select( e=> new{item=e}).FirstOrDefault().item)  

%>

That actually works for the object template and the field and property templates out of the box. But who wants this much Linq fun when all you want is an element tied to an expression of the ViewModel? (I don’t).

So why not try an extension method – just make for any enumerable. It needs to be simple to call, and we need to get element back in the for ofm a callable property.

Here is an example for an object template would look like:

   1: <%
   1: =Html.DisplayFor(m => m.Elements.Of(element).Item)  

%>

Here is an example for a field or property template would look like:

   1: <%
   1: =Html.DisplayFor(m => m.Elements.Of(element).Item.Title)  

%>

And below is the code. It is simple and works. When you call the ‘Of’ extension method it does the following:

  • Verifies that the element passed in is in the enumerable (in this case m.Elements).
  • Returns a simple wrapper object that contains the element passed.
  • The element is returned by the wrapper property ‘Item’, making easy to get an object template.

Here’s the code:

   1: public class EnumerableItemOf<T>

   2: {

   3:     internal EnumerableItemOf(T Value)

   4:     {

   5:         this.Item = Value;

   6:     }

   7:     

   8:     public T Item { get; private set; }

   9: }

  10:  

  11:  

  12: public static class LinqUtility

  13: {

  14:     public static EnumerableItemOf<T> Of<T>(this IEnumerable<T> Enumerable, T Item)

  15:     {

  16:     

  17:         if (Enumerable != null && Enumerable.Contains(Item))

  18:         {

  19:             return new EnumerableItemOf<T>(Item);

  20:         }

  21:     

  22:         return new EnumerableItemOf<T>(default(T));    

  23:     }

  24: }

Written by Lynn Eriksen

September 20, 2009 at 2:37 am

Posted in Uncategorized

Tagged with ,

XElement and XPath: Covalent Bonding

leave a comment »

Yes. It’s true. You can use XElement and XPath together.

I was working on an applet today using XElement and was having a hard time getting at nested elements. I kept searching the XElement members in VS intellisense but couldn’t get anything that even hinted at XPath like support. Well a trip to the XElement members documentation enlightened me. (http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement_members.aspx) It looks like if you import the System.Xml.XPath name space you get full XPath support for returning single or multiple XElement vis-à-vis extension methods. That makes things SO much easier working with XElements. Saved a TON of time!

Written by Lynn Eriksen

March 7, 2009 at 2:48 am

Posted in Uncategorized

Tagged with