webentwicklung-frage-antwort-db.com.de

'object' enthält keine Definition für 'Action', wenn IdentityUser mit OAuth verwendet wird

Ich bin nicht sicher, wie oder warum dies geschieht, aber nachdem ich einen Tag mit google und stackoverflow verbracht habe, brauche ich Hilfe, was das Problem ist.

Das ist der Fehler ...

Server Error in '/' Application.

    'object' does not contain a definition for 'Action'

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

    Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'Action'

    Source Error: 


    Line 15:     else
    Line 16:     {
    Line 17:         string action = **Model.Action**;
    Line 18:         string returnUrl = Model.ReturnUrl;
    Line 19:         using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }))

    Source File: c:\Users\Developer\Source\Repos\Zenwire-Master\Zenwire\Views\Account\_ExternalLoginsListPartial.cshtml    Line: 17 

~/Controller/AccountController

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using Zenwire.Models;

namespace Zenwire.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        public AccountController()
            : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new IdentityDbContext())))
        {
        }

        public AccountController(UserManager<ApplicationUser> userManager)
        {
            UserManager = userManager;
        }

        public UserManager<ApplicationUser> UserManager { get; private set; }

        //
        // GET: /Account/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }

        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var user = await UserManager.FindAsync(model.UserName, model.Password);
                if (user != null)
                {
                    await SignInAsync(user, model.RememberMe);
                    return RedirectToLocal(returnUrl);
                }
                else
                {
                    ModelState.AddModelError("", "Invalid username or password.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/Register
        [AllowAnonymous]
        public ActionResult Register()
        {
            return View();
        }

        //
        // POST: /Account/Register
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser()
                {
                    UserName = model.UserName,
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    Address = model.Address,
                    City = model.City,
                    PostalCode = model.PostalCode,
                    Province = model.Province,
                    Phone = model.Phone,
                    Email = model.Email
                };

                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    AddErrors(result);
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // POST: /Account/Disassociate
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Disassociate(string loginProvider, string providerKey)
        {
            ManageMessageId? message = null;
            IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
            if (result.Succeeded)
            {
                message = ManageMessageId.RemoveLoginSuccess;
            }
            else
            {
                message = ManageMessageId.Error;
            }
            return RedirectToAction("Manage", new { Message = message });
        }

        //
        // GET: /Account/Manage
        public ActionResult Manage(ManageMessageId? message)
        {
            ViewBag.StatusMessage =
                message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
                : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
                : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
                : message == ManageMessageId.Error ? "An error has occurred."
                : "";
            ViewBag.HasLocalPassword = HasPassword();
            ViewBag.ReturnUrl = Url.Action("Manage");
            return View();
        }

        //
        // POST: /Account/Manage
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Manage(ManageUserViewModel model)
        {
            bool hasPassword = HasPassword();
            ViewBag.HasLocalPassword = hasPassword;
            ViewBag.ReturnUrl = Url.Action("Manage");
            if (hasPassword)
            {
                if (ModelState.IsValid)
                {
                    IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
                    if (result.Succeeded)
                    {
                        return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
                    }
                    else
                    {
                        AddErrors(result);
                    }
                }
            }
            else
            {
                // User does not have a password so remove any validation errors caused by a missing OldPassword field
                ModelState state = ModelState["OldPassword"];
                if (state != null)
                {
                    state.Errors.Clear();
                }

                if (ModelState.IsValid)
                {
                    IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
                    if (result.Succeeded)
                    {
                        return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
                    }
                    else
                    {
                        AddErrors(result);
                    }
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // POST: /Account/ExternalLogin
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult ExternalLogin(string provider, string returnUrl)
        {
            // Request a redirect to the external login provider
            return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
        }

        //
        // GET: /Account/ExternalLoginCallback
        [AllowAnonymous]
        public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
        {
            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
            if (loginInfo == null)
            {
                return RedirectToAction("Login");
            }

            // Sign in the user with this external login provider if the user already has a login
            var user = await UserManager.FindAsync(loginInfo.Login);
            if (user != null)
            {
                await SignInAsync(user, isPersistent: false);
                return RedirectToLocal(returnUrl);
            }
            else
            {
                // If the user does not have an account, then Prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName });
            }
        }

        //
        // POST: /Account/LinkLogin
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LinkLogin(string provider)
        {
            // Request a redirect to the external login provider to link a login for the current user
            return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId());
        }

        //
        // GET: /Account/LinkLoginCallback
        public async Task<ActionResult> LinkLoginCallback()
        {
            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
            if (loginInfo == null)
            {
                return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
            }
            var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
            if (result.Succeeded)
            {
                return RedirectToAction("Manage");
            }
            return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
        }

        //
        // POST: /Account/ExternalLoginConfirmation
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
        {
            if (User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Manage");
            }

            if (ModelState.IsValid)
            {
                // Get the information about the user from the external login provider
                var info = await AuthenticationManager.GetExternalLoginInfoAsync();
                if (info == null)
                {
                    return View("ExternalLoginFailure");
                }
                var user = new ApplicationUser()
                {
                    UserName = model.UserName,
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    Address = model.Address,
                    City = model.City,
                    PostalCode = model.PostalCode,
                    Province = model.Province,
                    Phone = model.Phone,
                    Email = model.Email
                };

                var result = await UserManager.CreateAsync(user);
                if (result.Succeeded)
                {
                    result = await UserManager.AddLoginAsync(user.Id, info.Login);
                    if (result.Succeeded)
                    {
                        await SignInAsync(user, isPersistent: false);
                        return RedirectToLocal(returnUrl);
                    }
                }
                AddErrors(result);
            }

            ViewBag.ReturnUrl = returnUrl;
            return View(model);
        }

        //
        // POST: /Account/LogOff
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff()
        {
            AuthenticationManager.SignOut();
            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/ExternalLoginFailure
        [AllowAnonymous]
        public ActionResult ExternalLoginFailure()
        {
            return View();
        }

        [ChildActionOnly]
        public ActionResult RemoveAccountList()
        {
            var linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId());
            ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1;
            return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && UserManager != null)
            {
                UserManager.Dispose();
                UserManager = null;
            }
            base.Dispose(disposing);
        }

        #region Helpers
        // Used for XSRF protection when adding external logins
        private const string XsrfKey = "XsrfId";

        private IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContext.GetOwinContext().Authentication;
            }
        }

        private async Task SignInAsync(ApplicationUser user, bool isPersistent)
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
        }

        private void AddErrors(IdentityResult result)
        {
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error);
            }
        }

        private bool HasPassword()
        {
            var user = UserManager.FindById(User.Identity.GetUserId());
            if (user != null)
            {
                return user.PasswordHash != null;
            }
            return false;
        }

        public enum ManageMessageId
        {
            ChangePasswordSuccess,
            SetPasswordSuccess,
            RemoveLoginSuccess,
            Error
        }

        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }

        private class ChallengeResult : HttpUnauthorizedResult
        {
            public ChallengeResult(string provider, string redirectUri)
                : this(provider, redirectUri, null)
            {
            }

            public ChallengeResult(string provider, string redirectUri, string userId)
            {
                LoginProvider = provider;
                RedirectUri = redirectUri;
                UserId = userId;
            }

            public string LoginProvider { get; set; }
            public string RedirectUri { get; set; }
            public string UserId { get; set; }

            public override void ExecuteResult(ControllerContext context)
            {
                var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
                if (UserId != null)
                {
                    properties.Dictionary[XsrfKey] = UserId;
                }
                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }
        }
        #endregion
    }
}

~/View

@using Microsoft.Owin.Security
<h4>Use another service to log in.</h4>
<hr />
@{
    var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes();
    if (loginProviders.Count() == 0)
    {
        <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 loginProviders)
                    {
                        <button type="submit" class="btn btn-default" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Log in using your @p.Caption account">@p.AuthenticationType</button>
                    }
                </p>
            </div>
        }
    }
}

~/Models/IdentityModels

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using Microsoft.AspNet.Identity.EntityFramework;

namespace Zenwire.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.Microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Province { get; set; }
        public string PostalCode { get; set; }

        [DataType(DataType.PhoneNumber)]
        public string Phone { get; set; }

        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }

        public virtual string Fullname { get { return FirstName + " " + LastName; } }
    }
}

~/App_Start/IdentityConfig

using Zenwire.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Zenwire.Repositories;

namespace Zenwire
{
    public class IdentityInitializer : DropCreateDatabaseAlways<ZenwireContext>
    {
        protected override void Seed(ZenwireContext context)
        {
            var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
            var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

            const string username = "Admin";
            const string password = "123456";

            //Create Role
            roleManager.Create(new IdentityRole("Admin"));
            userManager.Create(new ApplicationUser() { UserName = username });

            //Create Role Admin if it does not exist
            if (!roleManager.RoleExists("Admin"))
            {
                roleManager.Create(new IdentityRole("Admin"));
            }

            //Create User=Admin with password=123456
            var user = new ApplicationUser { UserName = username };
            var adminresult = userManager.Create(user, password);

            //Add User Admin to Role Admin
            if (adminresult.Succeeded)
            {
                userManager.AddToRole(user.Id, username);
            }

            base.Seed(context);
        }
    }
}
28
devfunkd

Dieses Problem scheint in MVC 5-Projekten zufällig aufzutreten. Ohne Grund zu ergründen, hört es bisher einfach auf, die Verwendung dynamischer/anonymer Typen in Teilansichten zuzulassen.

Ich hatte gerade das gleiche Problem, mit der _ExternalLoginsListPartial.cshtml-Seite und selbst das Zurücksetzen von hinzugefügten Projektänderungen machte keinen Unterschied. Einmal gebrochen scheint es gebrochen zu bleiben.

Die einzige Lösung besteht bisher darin, keine anonymen Typen zu verwenden , sondern stattdessen stark typisierte Klassen mit den erforderlichen Eigenschaften hinzuzufügen.

z.B. füge eine neue Klasse hinzu:

namespace Project.Models
{
    public class ExternalLoginViewModel
    {
        public string Action { get; set; }
        public string ReturnUrl { get; set; }
    }
}

und verweisen Sie es in der Teilansicht mit

@model Project.Models.ExternalLoginViewModel

und wo die Teilansicht gerendert wird, wechseln Sie zu:

@Html.Partial("_ExternalLoginsListPartial", new Project.Models.ExternalLoginViewModel() { Action = "ExternalLogin", ReturnUrl = ViewBag.ReturnUrl })
50
Gone Coding
7
PussInBoots

Ich habe das gleiche Problem und konnte es wieder herstellen, indem ich die bin/und obj/-Ordner der Anwendung löschte.

Das bringt dich in Schwung, aber ich mag @ TrueBlueAussies Idee, obwohl ich es noch nicht ausprobiert habe.

4

Dieses Problem scheint nun gemäß Microsoft https://connect.Microsoft.com/VisualStudio/feedback/details/813133/bug-in-mvc-5-framework-asp-net-identity-modules behoben zu sein. _

Ich persönlich habe das Problem mit einem NuGet gelöst: Update-Package für alle Pakete in meiner Lösung. Ich habe das Vorher und Nachher der packages.config als Referenz angehängt.

enter image description here

2
Eric

Dies passiert mir ständig, wenn dynamische Typen in Teilansichten verwendet werden.

Der einfachste Weg, um damit umzugehen, besteht darin, Ihre Lösung zu reinigen und neu zu erstellen.

1
jalexander

das könnte dumm aussehen, aber es ist was ich hatte ..

ich startete eine Web-App, bei der die externe Anmeldefunktion mit Google und Facebook und Twitter funktioniert. Dann entschied ich, dass die Anmeldebuttons hübsch aussehen sollten. Daher verwendete ich den folgenden Link: http: //www.beabigrockstar .com/pretty-social-login-buttons-for-asp-net-mvc-5/

danach stoße ich auf diesen seltsamen Fehler (das Objekt enthält keine Definition für die Aktion) und kam zu diesem Beitrag.

zuerst habe ich die TrueBlueAussie-Lösung ausprobiert und nicht für mich gearbeitet, dann habe ich Antonio Chagoury ausprobiert.

dann setze ich einen Haltepunkt auf die Aktion:

public ActionResult ExternalLogin(string provider, string returnUrl)

dann über dem Provider schweben, zeigt es null? während ich auf Facebook oder Twitter etc klicke.

also ging ich zurück zu meiner Schaltfläche in der _ExternalLoginsListPartial-Ansicht und schaute auf die Schaltfläche, um herauszufinden, dass das Namensattribut einen zusätzlichen Raum hat:

name=" provider" value="@p.AuthenticationType"

diesen Raum zu entfernen arbeitete für mich !!

name="provider" value="@p.AuthenticationType"

Ich weiß nicht, wie ich diesen extraspace vor dem Word "Provider" bekommen habe 

die Lektion, die ich gelernt habe, ist jedoch, dass Sie sorgfältig und vorsichtig sein sollten und an einfache Ursachen denken sollten, bevor Sie lange mit der Fehlersuche beschäftigt waren.

Ich hoffe, dass dies den Leuten helfen wird, die ständig an ihren Haaren ziehen, um festzustellen, dass dies nur ein Tippfehler ist: P

1
stackunderflow

OK, das war wirklich eine frustrierende Sache in meinem Projekt. Nachdem ich Eigenschaften aus dem ExternalLoginConfirmationViewModel-Modell entfernt habe, habe ich den gleichen Fehler erhalten.

Es stellte sich heraus, dass in ExternalLoginConfirmationViewModel.cshtm Fehler aufgetreten sind, die den Build-Fortschritt nicht angehalten haben und nur einmal im Fehlerlistenfenster angezeigt wurden. Danach sind alle Fehler verschwunden und erscheinen nach einer Weile zufällig.

Stellen Sie sicher, dass Sie nicht vorhandene Eigenschaften in ExternalLoginConfirmationViewModel.cshtm referenzieren

so wie das:

 <div class="form-group">
        @Html.LabelFor(m => m.HomeTown, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.HomeTown, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.HomeTown)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.BirthDate, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.BirthDate, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.BirthDate)
        </div>
    </div>   
0
Ronen Festinger