Archive for September 2009
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:
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:
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:
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:
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:
Here is an example for a field or property template would look like:
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:
I know I don’t have many readers if any – but maybe someone out there will pick this up. Maybe there are people out there who are listening.
I once had a person ask me if I was voting Democratic? I told him no. He told me that he was, because ‘he was smart’ and by implication I wasn’t. It was offensive, and I told him so, especially because he was working for a local school district and I was working in free enterprise. And then came the excuses about no WMD’s in Iraq, the ‘stay the course’ as a strategy speech, Katrina, lack of determined action on health care, excuses about firing Rumsfeld, the banking bust and then TARP. In the last election I voted for Bob Barr. I couldn’t trust Obama with my wallet, and the Republicans become something out of a Monty Python skit.
Now as a brief tangent – I want to look at scene from recent global political history. In the late 1930’s Europe was dominated by Nazi Germany and their chief rival in the region was the USSR. It was Hitler vs. Stalin. Left vs. Right. Surely there was one side to cheer for? From all that we know – no. Here is what they did:
- Directly killed over 50 million in 10 year window thru war or non-sustainable imprisonment.
- Actively enslaved their own country mean (through direct or indirect means? who really cares) to forward their own personal ambitions.
- Almost destroyed their own countries.
Neither country was worth supporting. When we defeated Nazi Germany, many Nazi officials and officers actually tried to compel us to take up arms with them to defeat the Communists, seeming to not understand that they were are as corrupted and diabolical as their opponent. It’s only out of circumstances that we had a brief military alliance with Russia – a kind of ‘the enemy of my enemy is my friend’ thing. If you’ve been alive for more than 30 years you know for certain just how bad the cold war aftermath was.
The point is that you can have two opposed groups and neither one is with supporting.
The far right is now what I call a ‘Schoolyard Bully’ fringe. They intimidate others, attempt to keep people in line by scaring the hell out of them or reminding them why the should be scared. They don’t believe in rational government regulation because they don’t want to get caught swindling others. And when the chips are down they are far less likely to be reasonable, rational, principled or consistent, and they are not ashamed of this. They are actually soft.
The far left is the ‘Confidence Man’ fringe. It’s taken me a long time, but after watching enough episodes of Lost I’ve figured it out. They are con artists. They want you to think that all the things they want to do are really your idea. They take their time. They flash some cash. They say nice things about you. They get a supporting actor to play the victim part. And when you bite on their ideas, just remember they are not to blame when you are stuck with the bill. After all – you are the one that said yes. Try to expose them for what they are and these ‘thoughtful, patient, intellectual types’ will try to tear you to pieces. They are actually vicious.
And just to be fair, the far right has held more than a few in their ‘confidence’, and the far left has bulled more than their share as well. But in general this is the way they act. Both support classical un-American positions such as nationalization of entire industries or getting a bailout when their financial empires come crashing down. They believe that corporations exist to be used as hosts and drained until they go bankrupt, or that those that cannot afford health care are just losers – there is no problem.
They tend to both be takers, not makers. They wouldn’t have their place with out the creators such as Jobs and Gates, Ford and Durant, Edison and Bell and all of the other countless men and women that worked with them or like them to make their lives better by making others more productive. This is the real American Way. It’s the Win-Win scenario and it’s not easy. This is what people are striving for. And this is what is at stake.
Yesterday, well really earlier today, I went on an on about the problems with DisplayFor and my initial hack. Then I updated the post highlighting a post from Matt Hidinger that covers an expression-based alternative. Here is the link:
But then sleep called and then to work and I let the idea brew. I really like Matt’s use of expressions but I didn’t like the fact that I could not control write flow. So I took his code and morphed it into what I’ll call ‘DisplayItemFor’. It’s quite simple: it requires and enumerable expression from the model and item from the same enumerable. At that point setting up a foreach loop and calling ‘DisplayItemFor’ is a fairly straight forward. Here’s an implementation example:
Download the source:
(using .docx due to wordpress limitations)
Asp.net MVC 2 Peview 1 – Work Around for ‘Templates can be used only with field and property accessor expressions.’ Exception When Calling ‘DisplayFor’ and Using a List
Update 1 – Looks like Matt Hidinger of matthidinger.com has a much better solution. How about ‘HtmlDisplayForMany’. Yeah. That’s right. It works like a charm. Have a look:
Nice work! 🙂 Looks like it pays to understand lambdas.
Update 2 – Looks like it works, but his implementation is a bit off. Looks like the ‘DisplayFor’ method always returns ‘String.Empty’. This is because the ‘DisplayFor’ method is a facade that calls a single ‘TemplateHelper’ method and this method writes directly to the HttpResponse output. So if you want to write tags around it you have to call response.write. I’ll try to have an updated version of Matt’s code that supports a WrapTag later this evening. For now, it’s time to take a nap and then to work.
One of the new features in Asp.Net MVC 2 is the support for setting a default value for an action method inside a controller. Here is an example:
All you need to do is apply the ‘DefaultValue’ attribute with a constant value. But, if you have a DateTime value to set as a default there is a small trick. Here is what does not work:
That won’t compile because the DateTime is never a constant value. You can’t even make a constant. But you can do this:
This works because the string and type are constants.
Dear Asp.net Web Forms,
I have for the most part enjoyed working with you. You have been a good friend, a constant companion, a great enabler. You allowed me to be far more productive than your ancestor, in revision now known as Classic ASP. Even now, right now, as I right this late at night you and I are engaged in a long battle at work – cranking out an eCommerce project using your latest and most greatest features such as Dynamic Data. And yet, even now while we are so closely engaged – I have to admit that your darling first cousin has caught my eye, you know her – ASP.net MVC.
You see Web Forms – for all of your power and ease of development, you are not simple to deal with in large projects. Your pattern is fairly rigid – and breaking out is, well, painful. So while am am enamored by all of your curvy controls, you make it hard for me to do what I really want in large applications. And what I want to do is control everything that my app does: I want to easily swap out page views for mobile devices with out configuring multiple web sites, I want my links to be application contextual, I want to be able to configure any point in the app pipeline, I want to be the master of all routes, and I want to use multiple forms on a page – please. For all of your programming ease you make this really hard to do, yet MVC makes this easy. And did I fail to mention that I don’t need you to do styles or simulate client events anymore? The browsers have gone and gotten all grown up – and that jQuery guy does some serious kung fu which makes programming cross-browser exponentially easier than it use to be. Oh – and dude – your HTML and CSS markup up is so late 90’s! I know you know ….
Sure – MVC is not fully grown up and doesn’t have controls yet, if ever. But – it has some great features you don’t and won’t ever have (model binding), it’s taking on a few of your more recent tricks in its forthcoming new version (data annotations and field templates), but most importantly it’s just going to let me make that app I’ve been wanting to make with out all of the crazy hacking you would require (and not to mention the waiting for your next release). It’s not always easy to use MVC, like when trying to make a grid with sorting and paging, but most of it’s ‘magic’ is simple and easily extensible – and Web Forms that’s just not in your make up.
But, were not done yet, and the truth is that hopefully an end is a long time in coming. MVC does take a bit more work to get started, and in some places it just won’t work because it’s not what the customer needs. And it looks like sometimes I will just need you to get along with MVC in the same app. So in the coming months ahead you are just going to have to learn to work side by side. Sometimes Web Forms you will lead, and other times MVC will. But I will need to work with both of you. You’re both valuable. So let’s just call it a rearrangement.