17

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 })
nVentimiglia
  • 1,888
  • 4
  • 21
  • 37
  • 5
    I having the exact same issue. Pretty weird. – par Oct 29 '13 at 18:04
  • 1
    I managed to get around the issue by simply passing the action string on its own and using ViewBag.ReturnUrl direct within the _ExternalLoginsListPartial - rather than creating a new ViewModel. – par Oct 29 '13 at 21:19
  • 1
    Did you figure out what the underlying issue is? I remember I had that issue as well, but it was because my ViewModels weren't being referenced in the cshtml correctly; but now it's occurring again, and I can't figure out whats wrong! – teh0wner Nov 11 '13 at 20:59
  • No I did not. I wish I did, but suspect this may be a bug. I have moved on.... The work arounds published by par and myself work. – nVentimiglia Nov 11 '13 at 21:28
  • The way I fixed it before was that I had to completely clean the solution and build agian; however that doesn't seem to work any more. – teh0wner Nov 12 '13 at 16:32
  • 2
    This is most certainly a bug because I have changed absolutely nothing in my project and it "just broke" from outta nowhere. – PussInBoots Nov 21 '13 at 13:07

7 Answers7

4

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.

AKhooli
  • 1,285
  • 1
  • 13
  • 11
  • My namespaces are correct. The error occurs in a partial view without a model. – nVentimiglia Nov 06 '13 at 20:07
  • @nVentimiglia - the error happens in this line: string action = Model.Action of _ExternalLoginsListPartial.cshtml file and Model.Action has the correct value in debug. Check views that have models and make sure their m parameters are correct (even if they compile ok). – AKhooli Nov 07 '13 at 11:56
  • Confirm my namespaces are correct.... That said I commented out my model declaration and the problem disappeared. That said, I had a broken version of the project (before my fix above) saved. I can confirm the project models are default, in the correct namespace and with a valid model declaration in Login.cshtml. – nVentimiglia Nov 07 '13 at 17:46
  • I had this issue and, after fixing the bad namespace, I had to shut down IIS Express and start debugging again before it started working. – jfren484 Apr 04 '14 at 16:46
  • This resolved the same issue for me on VS2012 (update 3), note that I previously created the explicit view model (ExternalLoginViewModel) that nVentimiglia suggests, but after fixing a different view in the Accounts folder where the model namespace was wrong, I then reverted back to using a dynamic model for the _ExternalLoginsListPartial.cshtml view and it all worked ok. – David_001 Apr 28 '14 at 11:18
3

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

Amy
  • 154
  • 3
  • 9
1

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.

PussInBoots
  • 11,028
  • 9
  • 52
  • 84
1

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.

Kevin.A
  • 134
  • 1
  • 4
  • 13
1

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!

Piers Lawson
  • 747
  • 2
  • 5
  • 18
1

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.

Ed Kaim
  • 45
  • 6
0

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 }))
user2918406
  • 139
  • 2
  • 9
  • 1
    This is useless if you want to reuse the view with multiple actions (As the initial internet project [and mine] does). It is not addressing the underlying problem. – nVentimiglia Nov 04 '13 at 20:09
  • I got this fixed (string action = Model.Action;) is working fine for me , i rechecked all the models in cshtmls those are used in login and registration functionality and I found my problem fix in Register.cshtml.BTW i got this issue while upgrading from MVC 4 to MVC 5. – user2918406 Nov 04 '13 at 22:44
  • 2
    And the solution was ? – nVentimiglia Nov 04 '13 at 23:05