čtvrtek 21. července 2011

System.Web.Mvc.UpdateModel() throws exceptions after succeeding to update an object

Yes, the message is right. Even though the docs claim that it throws "System.InvalidOperationException: The model was not successfully updated."

The catch is that it throws the exception even if the model was successfully updated. Even if there was nothing to update at all. Even if there is a custom model binder for the type of the object you are trying to update, you step through the code and everything in the update works fine, all the properties are updated as they should, everything validates, the last line of your code returns exactly what it should and then KABOOOOM.

The model of type 'XXXXXX' could not be updated

Luckily in this particular case the source code is available so after some time with the sources of ASP.Net MVC you can find the reason. The (censored) who wrote the code decided to throw the exception whenever there is an error in the ModelState dictionary after updating the model. Sounds right, or not? Wait! What if there was something already before the UpdateModel() call? What if some other model failed, was handled and now I need to import some of the data into another object ... no way, as soon as there's an error, you get an exception. Your error, his error, their error, who the heck cares. Kabooom. Hooooray, we have an excuse to throw an exception!

Now if you don't really mind whether the update worked or not you can just use TryUpdateModel() and ignore the incorrect result. If you do care ... good luck.

čtvrtek 14. července 2011


OK. So you can set which day of the week is the "first" and then the DATEPART(weekday,@date) returns a number from 1 to 7 with the specified day being "1". The documentation is rather convoluted, but well ... what would you expect. So everything is nice and dandy isn't it?

No it is not. The catch is that the SET DATEFIRST is not stored with the stored procedure or function, but rather taken from the current connection. So you write for example a function that returns the first Monday at least N days after a specified date and ... pray that someone for whatever reason doesn't set DATEFIRST to anything else than it was set to when you tested the function. Cause the function doesn't remember what it was set to when it was parsed, you can't set it from within the function and there is no way to pass that option to DATEPART() explicitely.

Now that's what I call a stupid interface.

CREATE FUNCTION dbo.GetWeekDay(@Date datetime) RETURNS int
Declare @day int
set @day = 1 + ((@@DATEFIRST + DATEPART( weekday, @Date) - 2) % 7);
return @day

At last something that's consistent. Agrrrrrr.