nVentimiglia
nVentimiglia

Reputation: 1908

MVC5 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException

Ive been working on converting a MVC4 project over to MVC5. The first day I ran into an 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' but was able to resolve it by starting my conversion over. I'm not sure what the fix was which is a bummer, because its happened again.

The Error occurs in _ExternalLoginsListPartial.cshtml when I load the Login.cshtml page. The error is thrown on line 15. (string action = Model.Action;)

@using Microsoft.Owin.Security

@{
    var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes();
    var authenticationDescriptions = loginProviders as AuthenticationDescription[] ?? loginProviders.ToArray();
    if (!authenticationDescriptions.Any())
    {
        <div>
            <p>There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkId=313242">this article</a>
            for details on setting up this ASP.NET application to support logging in via external services.</p>
        </div>
    }
    else
    {
        string action = Model.Action;
        string returnUrl = Model.ReturnUrl;
        using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }))
        {
            @Html.AntiForgeryToken()
            <div id="socialLoginList">
                <p>
                @foreach (AuthenticationDescription p in authenticationDescriptions)
                {
                    <button type="submit" class="btn btn-default padded-8 margin-8" id="@p.AuthenticationType" name="provider" 
                            value="@p.AuthenticationType" title="Log in using your @p.Caption account">

                        <img src="@Url.Content("~/Content/Brands/"+p.Caption+".png")" alt="Microsoft" class="img-responsive" />
                        <br/>
                        <b>@p.Caption</b>
                    </button>
                }
                </p>
            </div>
        }
    }
}

The error thrown is

An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code

Additional information: 'object' does not contain a definition for 'Action'

The snapshot says

Message : object' does not contain a definition for 'Action' Source : Anonymously Hosted DynamicMethods Assembly

Now this is double weird because when I set a breakpoint Model.Action is not null. I can see the value.

This is really frustrating. The app was working 5 min ago.. I had changed the html on a non related page.. and now it wont work.

Hackish Fix I would rather know why this error is happening. That said, I have a quick fix in case anyone else comes across this (Because this is part of part of the default solution). The solution is to not use dynamics. Create your own viewmodel and pass that.

  public class ExternalLoginViewModel
{
    [Display(Name = "ReturnUrl")]
    public string ReturnUrl { get; set; }

    [Required]
    [Display(Name = "Action")]
    public string Action { get; set; }
}

 @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginViewModel { Action = "ExternalLogin", ReturnUrl = ViewBag.ReturnUrl })

Upvotes: 17

Views: 18638

Answers (7)

Ed Kaim
Ed Kaim

Reputation: 45

I also hit this issue with VS 2013 U3. I had just added an email field to RegisterViewModel with the [EmailAddress] attribute, and it was crashing when I tried visiting the Register page. Commenting out the [EmailAddress] attribute fixed the issue. However, it continued working after I added the attribute back in, so this is probably a broader issue that could have to do with changes to the model classes.

Upvotes: 1

Amy
Amy

Reputation: 154

This bug is verified by Microsoft, and they are working on fixing it.

So anyone from the future who reads this: try updating visual studio 2013 to at least update 2.

https://connect.microsoft.com/VisualStudio/feedback/details/813133/bug-in-mvc-5-framework-asp-net-identity-modules

Upvotes: 3

Piers Lawson
Piers Lawson

Reputation: 747

For me I had changed the contents of the ManageUserViewModel to add a property... I then started getting the error. When I changed the Manage.cshtml from not using an explicit model to using:

@model XYZ.Models.ManageUserViewModel

and removed the using statements, it started working again. One hour wasted!

Upvotes: 1

Kevin.A
Kevin.A

Reputation: 144

I got the same error after replacing account models to another folder. When I double checked each view under the Account folder I found out my "Manage.cshtml" referenced to old namespace. I changed it to correct namespace for my models and the error fixed.

Upvotes: 1

PussInBoots
PussInBoots

Reputation: 12343

Found a solution for my own (mvc5) project after some experimenting.

I had a _ExternalLoginsListShoppingCartPartial.cshtml (from my mvc4 project) with @model ICollection<AuthenticationClientData> at the top. I commented it out and rebuild the solution and suddenly it works. I'm not even using that partial view in any view so it's a pretty nasty bug imo.

So check in your project. You may have some mvc4/simplemembership stuff that is messing up your mvc5 project.

Upvotes: 1

AKhooli
AKhooli

Reputation: 1295

Check the views in the Account folder and for each one that has an explicit model, make sure the (view)model is in the right namespace. Mouse over the m parameter (m => m.UserName ... etc) and make sure it is referencing the correct (view)model. In my case, I moved AccountViewModels to a different folder and the app broke as above. It appears the views are sort of "caching" the model from the original namespace. I used a silly fix (commented out the @model line and un-commented it back). Got warning that m is dynamic but when built and ran it worked. Looks like a glitch in VS 2013 RTM.

Upvotes: 4

user2918406
user2918406

Reputation: 149

yeah, I replaced the "else" code with the following and its working but still trying to see why it didn't work when using Model.Action ?

//string action = Model.Action;
//string returnUrl = Model.ReturnUrl;
//using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }))
using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = ViewBag.ReturnUrl }))

Upvotes: 0

Related Questions