WebForms and lies
I made the comment several times that I feel that WebForms lies to me, Joe Young asks what do I mean by that. Here is a small reproduction that I just created, that demonstrate the problem. Put this in an ASP.Net page, and run, select another value, and see what you get.
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Test.DataSource = new string[]{ "London", "Paris", "Tel Aviv" };
DataBind();
}
protected void SelectedIndexChanged(object sender, EventArgs e)
{
string msg = string.Format(@"alert('What the contol say: {0}; What the request says {1}');",
Test.SelectedValue, Request[Test.ClientID]);
ClientScript.RegisterStartupScript(GetType(),"blah",msg,true);
}
</script>
<asp:DropDownList ID="Test" EnableViewState="false" AutoPostBack="true" AppendDataBoundItems="true"
runat="server" OnSelectedIndexChanged="SelectedIndexChanged">
<asp:ListItem>nothing selected</asp:ListItem>
</asp:DropDownList>
Before you would jump to explain to me why this is happening, assume that I have spent a bit of time on this issue, I understand what the page life cycle is and can figure out what happen when.
Nevertheless, as it stands, here is a control that flat out lies to me about its state. I can go and query the Request and get the correct result back. For more fun and games, remove the AppendDataBoundItems and see what happens then.
I run into this kind of things fairly often, from view state that arrive to the wrong control (and what fun it was to find that out) to control naming rules to 101 little things that if you don't get just right, would silently break the code.
I will try to post about the rest of Joe's comment (and Jeremy Boyd's post) shortly.
Comments
I can see your point, who among us has not made the same mistake at some point, I sure have. The asp.net model that exists now is not the most intuitive in the world, but much better than the classic asp model.
The point however; is that the control is not lying to you, it is being quite honest IMHO. Its telling you the state, and under these conditions, it has none. This is not the control's fault or the framework's, it's quite frankly, the developer's.
I just read Jeremy's post and his thoughts are exactly mine in terms of the entire rails "movement". I guess I am with the WCSF camp and personally feel that I can get the same abstraction / separation of concerns and still keep the power of the underlying .NET engine.
Select * from [MonoRail].[Customers] [Via: Ayende Rahien ] Implementing Linq for NHibernate: A How To...
I have to disagree with Joe Young. IMHO, ASP.NET is better than classic ASP in a sense that it is easier to write clean logics, it is easier to separate out concerns, ... etc., but definitely not in the areas of viewstate and data binding.
I do believe that including viewstate support is a huge mistake, and we are still paying for that.
Can you explain to me what you ever lost this power?
Joe,
This is a simple scenario, where what the controls says and what it should says differs. I understand why it is doing it.
I still consider this a bug.
Depending on where on the stack you look at it.
From performance, scalability, architecture, no question that it is much better.
But ASP was much simpler to work with, IMO, and it worked much more closely with the model that you are actually working with
I'm sorry, as you usually very much respect your opinion, but to me this is very much a case of you intentionally trying to muddy the water. Anyone that really understands any framework, as you do in this case, can come up with an example to prove that it "lies" under the types of circumstances that its not really laid out for. That said, I can agree that I don't love a lot of the standard approaches either, but the typical ASP.NET dev would not ever think to do what you've done here, so this is not a typical problem at all!
This is a bug I actually run into recently. Let me walk you how it got there:
I don't believe in view state, never have, so it is disabled at the web.config level. I consider it a best practice. Certainly you won't see __VIEWSTATE in live.com, or any of the big MS sites.
I enable AutoPostBack because I need to refresh a part of the page.
I used AppendDataBoundItems because I want the "do something" to appear.
I data bind to the list
At which point I am doing something that ASP.Net is not designed to do? What would a typical ASP.Net developer not do?
I can give a more complex scenario where I do have view state, and it ends up in the wrong control, and I have no way of figuring it out. My dislike of view state has a foundation in many days of trying to understand what the **** thing work work right.
I don't have any problem at all with you avoiding viewstate -- I actually turn it off in web.config for a lot of my sites too. I have no problem with your other desires that you've stated here either -- i.e. using autopostback, appenddatabounditems, and databind.
The problem that I see is that if you choose to disable viewstate, since it is the default, then you should also expect to change "something" else to compensate. Certainly the trivial thing to change you have in your code, which is to no longer only load the data when its not a postback, instead you load the data every time.
But is that really enough to "overcome" the fact that you are avoiding viewstate? That depends on whether or not you also expect the restoration of control state to work completely -- and you apparently do here. And if you want that benefit of ASP.NET, restored control state, without the overhead of viewstate, then you will need to understand the page lifecycle and load your date in Init instead of Load -- in which case your example will work just fine.
I have a feeling you'll say that's expecting too much, but I disagree. Yes a good framework gives you options, like avoiding viewstate, but you also have to expect that when you choose the non-default option that you will have a little more work to do. It is true that many would never think about switching to Init instead of using Load, but its a very simple conclusion if you understand the framework you're working in.
As for other more complex scenarios, where the restoration of state gets mis-matched to the wrong controls, I assume you're working with dynamic controls. That certainly is another case that does require a little more care, but again the solutions are very simple once you understand the framework -- i.e. the page lifecycle. Yes again that may be asking for too much in your opinion, but there's always a tradeoff between what is automatic and what requires more work.
I can just say, a good framework is easy to understand. What these asp.net tricks is not. You need 20 state events to do something only if 20 state events bringing you advantage. And for asp.net, I dont see the point.
This is simply called- over-engineering.
Ayende, in regards to losing power of the .NET engine.
I probably should have said ASP.NET engine. :D
All the examples and documentation that I have seen from a .NET rails implementation uses raw html with some form of scripting language. I have not seen any use of server controls and I trust a GridView as such to render correctly without me having to hand code the html and script to get the same functionality. The same goes for having 3rd party controls that I can use and get an awful lot of functionality without having to do too much work. We use the Telerik controls alot and I would hate to have to write the code in some form of view rendering engine to get the same type of functionality that I can get by just dropping a control on the form and setting a few properties.
Perhaps I am completely mistaken here and I would appreciate someone clarifying it.
I think Paul nailed it. Disabling a feature means losing some functionality. Asp.net is flexible enough to handle that and still work --- are you?
' I trust a GridView as such to render correctly without me having to hand code the html and script to get the same functionality'
I personally think, this statement is not true. To me rendering a table correctly using NVelocity (or even ASP) is easier. The real problem is too many cases you need very close fix to the HTML/DHTML/JS stuff, and if GridView does not work, sorry you have to create your entire control- in most case UserControl doesn't work to the target due to the lifecycle design, and writing a control in asp.net is way too much difficult than writing ViewComponent in monorail.
I always think, try before you say its hard. I bought Agile Web Development with Rails book too, and I tried. Guess what? I got a web shop with a working ajax cart within 1.5 hours, plus Scriptaculous script to do new row highlight. Just this feature I feel is going to take me days if I dont have js generator script like RoR/MR has.
And to be fair, I tried ASP.NET, I even completed couple projects in ASP.NET, and I don't think its satisfactory. Its just not designed for doing the business good enough- have you tried to put validator control on your web page and found how many validator controls you have to modify when you change a single business rule? That DOESN'T work. All people who ever studied MVC would know it should be the model guarding the invalid issue, and sorry, ASP.NET just not one of those who knows how to do it property- otherwise why somebody in MS start to do MVC'lization on ASP.NET?
http://codebetter.com/blogs/jeffrey.palermo/archive/2007/03/16/Big-News-_2D00_-MVC-framework-for-ASP.NET-in-the-works-_2D00_-level-300.aspx
I discuss this kind of issue a lot with MS programmers who stick with MS technology. The real problem I found is- usually they are not really looking things detail enough before they comment. I mean, put yourself into the pool and swim for a while, thats what I call enough when talk about framework evaluations.
Ayende,
I have wrote what you want me to wrote about, see if you like it :P
http://bugthis.blogspot.com/2007/03/why-aspnet-is-leaky-example-of-over.html
This combo box "bug" bit me quite hard when I was just starting with ASP.NET and had decided to do away with viewstate. My question is this: is there a reasonable way to prevent use of DropDownList properties that require data to be populated, perhaps by throwing an exception? SelectedValue is the only Selected* property one should be allowed to read from if EnableViewState == false and no items were added. At the time, I was majorly confused, as I could read .Text from textboxes with viewstate turned off with absolutely no problem (I didn't use the *Changed events).
To what extent is this just a problem with ASP.NET's postback model? I ask because I find I often want to load less data if I'm processing a postback than if I'm churning out a page. I haven't found an elegant method for doing this, especially when some of the data loaded for processing a postback is also required for non-postbacks. What I'd really like to see is an analysis of how to know to load what data when; in other words, a paper on stateless programming. Enough of the "ASP.NET is crappy, use MVC" -- tell me exactly why MVC is better in technical terms I can appreciate and understand. I've started to seriously wonder to what extent MVC is better because separating model and view and controller is good, and to what extent it's better because the postback model isn't so hot (at least in its current version).
Dear Luke,
I think you are a programmer right? Start with MonoRail samples. Very soon you will find your way out- I bet 4 hours trial will make you shine.
Its just not easy to pursuade someone, especially a programmer, with simple words. I could spend the whole day speaking about the advantage but still you could not be touched at all. So why not just do it? :)
If you really want an example, maybe goto my web page (i.e. a blog) I put some comparsion scenario, which might already show you some of the pain you had in ASP.NET and the resolution in MonoRail.
Comment preview