Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Last week we published the RC2 build of ASP.NET MVC 3.  I blogged a bunch of details about it here.

One of the reasons we publish release candidates is to help find those last “hard to find” bugs. So far we haven’t seen many issues reported with the RC2 release (which is good) - although we have seen a few reports of a metadata caching bug that manifests itself in at least two scenarios:

  • Nullable parameters in action methods have problems: When you have a controller action method with a nullable parameter (like int? – or a complex type that has a nullable sub-property), the nullable parameter might always end up being null - even when the request contains a valid value for the parameter.
  • [AllowHtml] doesn’t allow HTML in model binding: When you decorate a model property with an [AllowHtml] attribute (to turn off HTML injection protection), the model binding still fails when HTML content is posted to it.

Both of these issues are caused by an over-eager caching optimization we introduced very late in the RC2 milestone.  This issue will be fixed for the final ASP.NET MVC 3 release.  Below is a workaround step you can implement to fix it today.

Workaround You Can Use Today

You can fix the above issues with the current ASP.NT MVC 3 RC2 release by adding one line of code to the Application_Start() event handler within the Global.asax class of your application:

image

The above code sets the ModelMetaDataProviders.Current property to use the DataAnnotationsModelMetadataProvider.  This causes ASP.NET MVC 3 to use a meta-data provider implementation that doesn’t have the more aggressive caching logic we introduced late in the RC2 release, and prevents the caching issues that cause the above issues to occur. 

You don’t need to change any other code within your application.  Once you make this change the above issues are fixed.  You won’t need to have this line of code within your applications once the final ASP.NET MVC 3 release ships (although keeping it in also won’t cause any problems).

Hope this helps – and please keep any reports of issues coming our way,

Scott

P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

Published Tuesday, December 14, 2010 4:53 PM by ScottGu
Filed under: , , ,

Comments

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 8:06 PM by Kalbe.Zhao

Thanks,i like mvc!

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 8:19 PM by Sean

And now my website is working again.

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 8:44 PM by webdiyer

Thanks for the fix!

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 8:53 PM by Sam

Thanks for the update.  I can't get approval using it around here till it has RTMed.  Any idea when the final bits will be released??

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 9:01 PM by rockinthesixstring

Works like a champ! Thanks.

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 9:02 PM by paxer

Thanks !!! I've spent 3 days trying to understand is it EF Code First CTP 5 error or not, because if you try to request any DB context inside Action with untellable parameter, Asp.Net MVC 3 RC 2 will return very wired exception. Now - all fixed. Thanks again !

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 10:00 PM by ScottGu

@Sam,

>>>>>>>> Thanks for the update.  I can't get approval using it around here till it has RTMed.  Any idea when the final bits will be released??

We'll ship the final "RTM" release of ASP.NET MVC 3 the middle of January - so not too long away now.

Hope this helps,

Scott

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, December 14, 2010 10:01 PM by edwatki

ViewModel in RC1 has been changed to ViewBag in RC2.

I'm a newbie and will probably always be, but I do greatly appreciate having this framework to help me have fun developing web sites.

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Wednesday, December 15, 2010 3:43 AM by tugberk_ugurlu_

Thanks for the job you and your team have done for mvc. it is such a perfect job that the mvc framework has developed so quickly.

The changes are perfect. Html.Raw is so smooth. My blog page was full of @MvcHtmlString.Create which was making my app look crowded.

For the record, I am a little dissapointed that this change breaks a lot of thing in my app and I took 15 minutes to upgrade this.

Also it would be nice to collepse razor syntax code inside the view. for instance;

@using(Html.BeginForm()) {

...

...

...

}

that would be so useful to collapse it like we do with div, p, blackquote and so on..

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Wednesday, December 15, 2010 7:34 AM by Abdullah Saqib

Thanks Sir,

It is really very helpful moreover the way you explain make it more easy :P

Abdullah Saqib Pakistan

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Wednesday, December 15, 2010 3:31 PM by simeyla2

do you have a workaround for my bug yet :-)

connect.microsoft.com/.../630568

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Wednesday, December 15, 2010 9:14 PM by vietgeek

I think we should add an option to enable or disable html encoding of RazorViewengine, all my project always render html string, and I dont want add Html.Raw to all my output @..., I have some functions to clean html and prevent XSS already, I dont want html encoding by default and I decoding again.

Html Encoding with unicode like Vietnamese language is terrible for SEO, I want it encoding utf-8 but it encoding with 1252.

Thanks

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Thursday, December 16, 2010 2:16 AM by Eric

Thanks,I like mvc!

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Saturday, December 18, 2010 5:41 AM by Radim Köhler

Hi Scott

I guess that it is correct to put a bug report here. After short google searching, this seems to be the right place.

Below are listed 3 bugs really breaking MVC 3 functionality.

Almost every other new "feature" (e.g. TempDataDictionary is not serializable ...) we managed to fix outside your code.

But these are crucial.

Tested on ASP.NET MVC 3, RC2

1) Bug on your caching mechanism (I guess)

public abstract class ValueController<TID> : Controller

   where TID: struct

{

   public virtual ActionResult Detail(TID? id) {

       return View("Detail");

   }

}

public class LongController : ValueController<long>{}

public class IntController : ValueController<int>{}

Run "Int" first then "Long"

Int.mvc/Detail/2

Long.mvc/Detail/2

The parameters dictionary contains an invalid entry for parameter 'id'

for method 'System.Web.Mvc.ActionResult Detail(System.Nullable`1[System.Int64])'

in 'ValueController`1[System.Int64]'.

The dictionary contains a value of type 'System.Int32',

but the parameter requires a value of type 'System.Nullable`1[System.Int64]'.

Run Long first then int

Long.mvc/Detail/2

Int.mvc/Detail/2

The parameters dictionary contains an invalid entry for parameter 'id'

for method 'System.Web.Mvc.ActionResult Detail(System.Nullable`1[System.Int32])'

in 'ValueController`1[System.Int32]'.

The dictionary contains a value of type 'System.Int64',

but the parameter requires a value of type 'System.Nullable`1[System.Int32]'.

2) Fatal bug in .cshtml/razor generated compile code

Let's have this statement

@if(Model.Name.IsEmpty())

{

}

C:\Path\Home.cshtml(7): error CS0121:

The call is ambiguous between the following methods or properties:

'MyOwn.Extensions.IsEmpty(string)' and

'System.Web.WebPages.StringExtensions.IsEmpty(string)'

It is a trap to insert using statement referencing your extensions. Remove it.

If there will be used even only one same extension (e.g. IsEmpty()) coming from your code

and from CORRECTLY referenced code done by user(developer)

(@using or web.config)

everything will fail.

(web.config setting <remove namespace="System.Web.WebPages.StringExtensions" /> does not help)

3) There is simply missing equivalent to the <%= providing not encoded string.

Even for the simpliest stuff which cannot be encoded we (developers) will start to introduce ower own ways how to do it (extensions, methods)...

Everything is worse, then to provide it directly by the Razor engine (@=) and make it as a standard

(As an example (few frustrating minutes to find it):

@culture.NumberFormat.NumberDecimalSeparator

provides unusable "&#160;" instead of " ".

Well but we need to pass it correctly and use int in JS,

so I had to hack your incomplete syntax)

Have a nice day

Radim Köhler

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Saturday, December 18, 2010 6:44 AM by Martin

@vietgeek: I agree with you. I would appreciate if they didn't encode by default.

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Saturday, December 18, 2010 8:03 AM by Radim Köhler

Hi Scott

I guess that it is correct to put a bug report here. After short google searching, this seems to be the right place.

Below are listed 3 bugs really breaking MVC 3 functionality.

Almost every other new "feature" (e.g. TempDataDictionary is not serializable ...) we managed to fix outside your code.

But these are crucial.

Tested on ASP.NET MVC 3, RC2

1) Bug on your caching mechanism (I guess)

public abstract class ValueController<TID> : Controller

   where TID: struct

{

   public virtual ActionResult Detail(TID? id) {

       return View("Detail");

   }

}

public class LongController : ValueController<long>{}

public class IntController : ValueController<int>{}

Run "Int" first then "Long"

Int.mvc/Detail/2

Long.mvc/Detail/2

The parameters dictionary contains an invalid entry for parameter 'id'

for method 'System.Web.Mvc.ActionResult Detail(System.Nullable`1[System.Int64])'

in 'ValueController`1[System.Int64]'.

The dictionary contains a value of type 'System.Int32',

but the parameter requires a value of type 'System.Nullable`1[System.Int64]'.

Run Long first then int

Long.mvc/Detail/2

Int.mvc/Detail/2

The parameters dictionary contains an invalid entry for parameter 'id'

for method 'System.Web.Mvc.ActionResult Detail(System.Nullable`1[System.Int32])'

in 'ValueController`1[System.Int32]'.

The dictionary contains a value of type 'System.Int64',

but the parameter requires a value of type 'System.Nullable`1[System.Int32]'.

2) Fatal bug in .cshtml/razor generated compile code

Let's have this statement

@if(Model.Name.IsEmpty())

{

}

C:\Path\Home.cshtml(7): error CS0121:

The call is ambiguous between the following methods or properties:

'MyOwn.Extensions.IsEmpty(string)' and

'System.Web.WebPages.StringExtensions.IsEmpty(string)'

It is a trap to insert using statement referencing your extensions. Remove it.

If there will be used even only one same extension (e.g. IsEmpty()) coming from your code

and from CORRECTLY referenced code done by user(developer)

(@using or web.config)

everything will fail.

(web.config setting <remove namespace="System.Web.WebPages.StringExtensions" /> does not help)

3) There is simply missing equivalent to the <%= providing not encoded string.

Even for the simpliest stuff which cannot be encoded we (developers) will start to introduce ower own ways how to do it (extensions, methods)...

Everything is worse, then to provide it directly by the Razor engine (@=) and make it as a standard

(As an example (few frustrating minutes to find it):

@culture.NumberFormat.NumberDecimalSeparator

provides unusable "&#160;" instead of " ".

Well but we need to pass it correctly and use int in JS,

so I had to hack your incomplete syntax)

Have a nice day

Radim Köhler

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Wednesday, December 22, 2010 10:08 AM by Steve Hobbs

Hi Scott,

I have a separate issue which this workaround does not seem to solve. Reverting to RC1 seems to fix the issue which makes me think that a bug in RC2 is causing the issue. I realise the following is just an overview of what is going on, but will be happy to provide detailed information if needed.

When issuing a POST request to "/publish/content/entityview" where the action has two parameters: a Guid, and List<TypeA>. JSON data is being posted, and the content type header is correctly set to "application/json".

The issue is that, during the model binding phase, the model binder is trying to invoke the action with a Guid, and an instance of List<TypeB>, which of course throws an exception complaining that "The parameters dictionary contains an invalid entry for parameter 'parameters'" (referring to the parameter of type List<TypeA>.

The strange this is, I have a completely unrelated controller elsewhere which contains an action which takes a parameter of List<TypeB>. However, when the model binder is asked to bind the incoming data to the parameters on this action, it tries to create an instance of List<TypeA> and of course I get the same exception (just the reversal of types). This particular action is being invoked via a normal GET request through the browser.

The other weird thing is that these issues seem to be exclusive - when the first problem arises, the second doesn't (and vice-versa). As a test, I put a new entry into my routing table to point directly to "/publish/content/entityview" and that fixes the first issue but raises the second. Putting in a route to handle the second issue as well has no effect. Taking this custom route out again fixes the second issue but the first remains (confusing, I know!).

The problem is it is difficult for me to see exactly what is going on, and why the model binder is getting confused between these two types in particular. The types aren't even similar in construction. They don't have the same properties, they don't inherit from one another (in fact, one is a class and the other is a struct).

As I said, my colleague went through the pains of reverting to RC1 and re-ran the code, which all works as normal. RC2 however breaks the behaviour.

Sorry this is a bit long - is this something your team have come across and/or can you provide any guidance?

Many thanks

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Wednesday, December 22, 2010 6:03 PM by adam selene

After installing MVC3 RC2 I am unable to open Silverlight class projects.

It wants me to (re)install Silverlight 4.0 Tools for Visual Studio 2010, but that does not fix the problem.

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Thursday, December 23, 2010 8:41 AM by NickD

i believe i have seen the same issue in ASP.NET MVC2. Can you confirm this?

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Thursday, December 23, 2010 9:17 AM by K

I am using ViewBag for getting dynamic types to the view.The page renders without any issues. But when posting the values it throws Runtimebinderexception if the code in the view is like this.

@if (Viewbag.something))

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Thursday, December 30, 2010 6:40 AM by jalchr

I'm using RC2 and it appeared also in RC1 ...

whenever I make some changes to my code and Press F5 to start up the project I get this error:

Storage scopes cannot be created when _AppStart is executing.

Unfortuntely, I can't tell how to reproduce this, since it happens at random moments...

I thought you might spend some time checking this bug ...

Thanks

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, January 11, 2011 12:13 PM by brother ink

I have used this and find lot of ease in MVC 3 to use as meta-data provider

Its well work in all environment.

# re: Update on ASP.NET MVC 3 RC2 (and a workaround for a bug in it)

Tuesday, January 11, 2011 6:56 PM by Andrey Kuleshov

Hi, just for your info.

I found that by some reason line 142 in jquery.unobtrusive-ajax.js

$("form[data-ajax=true] :submit").live("click", function (evt) {

causes problem in IE 8 (which looks like javascript errors in jquery itself, jquery-1.4.4.js, line 3619, pos 4 and line 3635, pos 4).

However, changing to

$("form[data-ajax=true]").find(":submit").live("click", function (evt) {

fixed my problem, and everything still look working for me.