Asp.net mvc ASP.NETMVC4通用主要困难

Asp.net mvc ASP.NETMVC4通用主要困难,asp.net-mvc,razor,asp.net-mvc-4,authorization,Asp.net Mvc,Razor,Asp.net Mvc 4,Authorization,我正在开发一个ASP.Net MVC 4web应用程序。以前我的MVC应用程序是使用MVC 3开发的,有了这个新的MVC 4应用程序,我刚刚从以前的应用程序复制/重用了我的身份验证和授权代码 当用户登录到我的站点时,我会执行以下操作 客户控制员 public ActionResult Login(LoginModel model, string returnUrl) { if (ModelState.IsValid) { User user = _userServ

我正在开发一个ASP.Net MVC 4web应用程序。以前我的MVC应用程序是使用MVC 3开发的,有了这个新的MVC 4应用程序,我刚刚从以前的应用程序复制/重用了我的身份验证和授权代码

当用户登录到我的站点时,我会执行以下操作

客户控制员

public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        User user = _userService.GetUser(model.Email.Trim());

        //Create Pipe Delimited string to store UserID and Role(s)
        var userData = user.ApplicantID.ToString();

        foreach (var role in user.UserRoles)
        {
            userData = userData + "|" + role.description;
        }

        _formAuthService.SignIn(user.ApplicantFName, false, userData);

        return RedirectToAction("Index", "Portfolio");
        }

        return View(model);
    }
FormsAuthenticationService

public class FormsAuthenticationService : IFormsAuthenticationService
{
    public void SignIn(string userName, bool createPersistentCookie, string UserData)
    {
        if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");

        // Create and tuck away the cookie
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddDays(15), createPersistentCookie, UserData);
        // Encrypt the ticket.
        string encTicket = FormsAuthentication.Encrypt(authTicket);

        //// Create the cookie.
        HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        HttpContext.Current.Response.Cookies.Add(faCookie);
    }
}
Global.asax

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{

    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];

    // If the cookie can't be found, don't issue the ticket
    if (authCookie == null) return;

    // Get the authentication ticket and rebuild the principal
    // & identity
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

    string[] UserData = authTicket.UserData.Split(new Char[] { '|' });

    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
    GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity, UserData);
    Context.User = userPrincipal;

}
这段代码在我以前的MVC 3应用程序中运行良好,但在这个MVC 4应用程序中,在Razor视图中,下面的代码似乎没有访问IsInRole属性来执行角色检查

@if (HttpContext.Current.User.IsInRole("Applicant"))
{
    <p>text</text>
}
@if(HttpContext.Current.User.IsInRole(“申请人”))
{
正文
}
同样,这在我的MVC3应用程序中非常有效

有没有人对我的MVC4应用程序为什么不起作用有什么想法或建议

非常感谢您的帮助

谢谢

额外信息

我的MVC4应用程序使用.NETFramework 4.0

下面的屏幕截图显示了分配给Context.User的我的通用主体。您可以看到,对于该用户,m_roles包含两个字符串,UserID(100170)和他们的Role(申请人)。但是由于某些原因,IsInRoles无法在我的MVC4Razor视图中访问或查看,但是,它可以在我相同的MVC3Razor视图中访问或查看。

在MVC 4中,您可以从
WebPagerUnderingBase
访问
用户,因此在razor语法中,您可以直接访问
用户
实例:

@if (Request.IsAuthenticated && User.IsInRole("Applicant"))
{
    <p>text</p>
}
您还需要将
Application\u AuthenticateRequest
更改为
Application\u OnPostAuthenticateRequest

protected void Application_OnPostAuthenticateRequest(Object sender, EventArgs e)

在MVC4HttpContext.Current.User中,未公开,因此无法使用它。我所做的是创建一个自定义BaseViewPage并在其中添加以下代码

    public abstract class BaseViewPage : WebViewPage
    {
        public virtual new Principal User
        {
            get { return base.User as Principal; }
        }
    }

    public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
    {
        public virtual new Principal User
        {
            get { return base.User as Principal; }
        }
    }
公共抽象类BaseViewPage:WebViewPage
{
公共虚拟新主体用户
{
获取{返回base.User作为主体;}
}
}
公共抽象类BaseViewPage:WebViewPage
{
公共虚拟新主体用户
{
获取{返回base.User作为主体;}
}
}
然后对视图文件夹中的system.web.webPages.razor/pages部分进行以下更改

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="WebApp.Views.BaseViewPage">
  <namespaces>
    ...
  </namespaces>
</pages>

...

希望这能解决您的问题。

各位

我终于解决了这个问题。默认情况下,当您创建新的ASP.NET MVC 4应用程序时,SimpleMembershipProvider将启用。在这种情况下,我不想使用SimpleMembershipProvider,但是,我需要在我的web配置中使用以下行禁用它

<appSettings>
    <add key="enableSimpleMembership" value="false" />
</appSettings>

我对User.IsInRole的调用现在效果很好


希望这对其他人有帮助。

有人对此有什么建议吗?谢谢。谢谢,但不幸的是它仍然不起作用,在我的Razor视图中的代码,即使有你的建议,仍然忽略了IsInRole检查。请提供帮助。@tgriffiths您已在asp.net管理工具中配置/包括此角色,对吗?而您正在测试的用户似乎正处于这样一个角色中?我是在这个帮助下发现的posthttp://stackoverflow.com/questions/13425163/create-custom-memebership-provider-in-mvc-4-always-get-error@我发现了同样的事情。我会用这个更新我的答案。这为我解决了这个问题。一点也不直观。我将一个站点从mvc3升级到mvc4。我甚至在web.config中没有这个密钥,但我的委托人不正确。添加上述内容对我来说很有效。为什么即使缺少应用程序设置键,它也默认为true。。。
<appSettings>
    <add key="enableSimpleMembership" value="false" />
</appSettings>