对象引用未设置为对象的实例.- 应用程序启动时角色不存在

本文关键字:启动 应用程序 角色 不存在 实例 设置 对象 对象引用 | 更新日期: 2023-09-27 18:32:55

所以,我有一个MVC4应用程序,我正在使用默认的登录和注册系统。在主页上,我想根据用户的角色重定向或更改邮件。这是我在控制器中得到的内容:

    public ActionResult Index()
    {
        if (Roles.GetRolesForUser().Contains("Admin"))
            ViewBag.Message = "Click on a link to get started.";
        else if (Roles.GetRolesForUser().Contains("Authorized"))
            ViewBag.Message = "Click on Organizations or Interfaces to get started.";
        else if (Roles.GetRolesForUser().Contains("Unauthorized"))
            ViewBag.Message = "An administrator must activate your account before you can use this tool.";
        else
            return RedirectToAction("Login", "Account");
        return View();
    }

通常,这工作正常,但是如果我在登录时重新启动应用程序,并且在进行代码更改后,则会收到错误"对象引用未设置为对象的实例"。它指向角色,显然还不存在。

经过太多的搜索,我发现了一个有同样问题的人。我在那里尝试了建议的解决方案,并替换了Roles.GetRolesForUser((的所有实例。包含 HttpContext.User.IsInRole,但后来我收到此错误:"与 SQL Server 建立连接时发生与网络相关或特定于实例的错误。找不到服务器或无法访问服务器。验证实例名称是否正确,以及 SQL Server 是否配置为允许远程连接。(提供程序:SQL 网络接口,错误:26 - 查找指定的服务器/实例时出错(">

经过一堆搜索,我找到了这个,它把我指向了这里,它说我的尝试都不起作用,因为我首先需要重定向。虽然,他显然在谈论别的东西,但它看起来很相似。

我尝试将索引重定向到 Index2,它重定向到 Index3,包含相同的代码,但遇到了相同的错误。我尝试了可单击的链接从索引到索引 2 再到索引 3,同样的错误。我尝试通过放置 WebSecurity.Logout(( 强制注销;就在导致错误的代码行之前,我得到一个不同的错误:"在调用"WebSecurity"类的任何其他方法之前,您必须调用"WebSecurity.InitializeDatabaseConnection"方法。此调用应放置在站点根目录下的 _AppStart.cshtml 文件中。但是内置的注销方法似乎并没有调用它,它有一个不同的事情:

    @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) {
        @Html.AntiForgeryToken()
        <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
    }

单击时,立即调用 WebSecurity.Logout((;

这就是我所知道的极限。我想我需要一种方法在启动应用程序时强制注销,如果它绑定到索引页甚至没关系,因为我几乎可以在登录后避免索引页。或者,如果有一种方法可以让它识别登录用户,那就更好了。

为了解决这个问题,起初我注释掉所有有问题的代码,重新启动它,单击注销,然后取消注释并重新启动。然后我发现删除浏览器中的cookie可以修复它。我仍然不想每次都这样做。如果我找不到解决方案,我只会强制用户单击将他们带到登录页面的注销链接。

对象引用未设置为对象的实例.- 应用程序启动时角色不存在

代码可能会抛出NullReferenceException,因为您没有检查Roles.GetRolesForUser的结果。

尝试:

string[] roles;
try
{
    roles = Roles.GetRolesForUser();
}
catch(HttpException)
{
    return RedirectToAction("Login", "Account");
}
if(roles == null) return RedirectToAction("Login", "Account");
if(roles.Contains("Admin")
{
    ViewBag.Message = "Click on a link to get started.";
}
else if (roles.Contains("Authorized"))
{
    ViewBag.Message = "Click on Organizations or Interfaces to get started.";
}
else if (roles.Contains("Unauthorized"))
{
    ViewBag.Message = "An administrator must activate your account before you can use this tool.";
}
else
{
    return RedirectToAction("Login", "Account");
}
return View();

如果使用Roles.IsUserInRole则代码可以简化为:

try
{
    if(Roles.IsUserInRole("Admin"))
    {
        ViewBag.Message = "Click on a link to get started.";
    }
    else if(Roles.IsUserInRole("Authorized"))
    {
        ViewBag.Message = "Click on Organizations or Interfaces to get started.";
    }
    else if (Roles.IsUserInRole("Unauthorized"))
    {
        ViewBag.Message = "An administrator must activate your account before you can use this tool.";
    }
    else
    {
        return RedirectToAction("Login", "Account");
    }
}
catch(ArgumentNullException)
{
    // No user is currently logged in
    return RedirectToAction("Login", "Account");
}
catch(HttpException)
{
    // There is no current logged on user. Role membership cannot be verified.
    return RedirectToAction("Login", "Account");
}
return View();

好的,终于想通了。Romoku的回答很有帮助,但我没有足够的声誉来投票:(

try/catch 块可以工作,但它在尝试连接时仍然挂起一段时间,然后它命中 HttpException 块,并显示消息"无法连接到 SQL Server 数据库"。然后它路由到登录页面,但对我来说奇怪的是,在登录页面上,它能够检测谁登录了,更好的是,我在 _Layout.cshtml 文件 [@if (Roles.GetRolesForUser(( 中也有类似的代码。包含("管理员"((]来过滤菜单选项,并在登录页面上正确运行这些选项。这真的很奇怪,因为我之前已经尝试过重定向到 Index2 和 Index3,但没有运气。所以我想也许我只需要重定向到不同的控制器,我添加了一个"测试器"控制器,没有骰子。

事实证明,AccountController 类在其上方有一个 [InitializeSimpleMembership] 属性,为了使原始代码按预期工作,我所要做的就是在 HomeController 类上方添加它,加上"using MyProject.Filters;"语句。

更有趣的是,每当我之前遇到相应的错误时,我都会搜索"WebSecurity.InitializeDatabaseConnection"的解决方案,在Filters文件夹中的"SimpleMemberInitializer(("中找到该语句,然后在解决方案中搜索"SimpleMemberInitializer",没有找到任何其他命中。谁知道它隐藏在[InitializeSimpleMember]属性中。