0

だから、私は 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().Contains のすべてのインスタンスを HttpContext.User.IsInRole に置き換えましたが、「SQL への接続を確立中にネットワーク関連またはインスタンス固有のエラーが発生しました」というエラーが発生しました。サーバー。サーバーが見つからなかったか、アクセスできませんでした。インスタンス名が正しいこと、および SQL Server がリモート接続を許可するように構成されていることを確認してください。(プロバイダ: SQL ネットワーク インターフェイス、エラー: 26 - 指定されたサーバー/インスタンスの検索エラー)"

さらに多くの検索を行った後、これを見つけましこれは、最初にリダイレクトが必要なため、どちらの試行も機能しないことを示しています。とはいえ、彼はどうやら別のことを話しているようですが、かなり似ているように見えます.

同じコードを含む Index3 にリダイレクトされた Index2 に Index をリダイレクトしようとしましたが、同じエラーが発生しました。クリック可能なリンクを Index から Index2 から Index3 に取得しようとしましたが、同じエラーが発生しました。WebSecurity.Logout(); を配置してログオフを強制しようとしました。エラーの原因となるコード行の直前に、別のエラーが表示されます。「「WebSecurity」クラスの他のメソッドを呼び出す前に、「WebSecurity.InitializeDatabaseConnection」メソッドを呼び出す必要があります。この呼び出しは、_AppStartサイトのルートにある .cshtml ファイル。」しかし、組み込みの logoff メソッドはそれを呼び出しているようには見えません。別のことが起こっています。

    @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 を削除すると問題が解決することがわかりました。私はまだそれを毎回する必要はありません。解決策が見つからない場合は、ログイン ページに移動するログオフ リンクをクリックするようユーザーに強制するだけです。

4

2 に答える 2

1

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();
于 2013-09-27T01:03:50.590 に答える
1

わかりました、ついにそれを理解しました。ロモクの答えは役に立ちましたが、投票するのに十分な評判がまだありません:(

try/catch ブロックは機能しますが、接続を試みている間にしばらくハングし、「SQL Server データベースに接続できません」というメッセージで HttpException ブロックにヒットします。次に、ログイン ページにルーティングされますが、私にとって奇妙なのは、ログイン ページで、ログインしているユーザーを検出できることです。さらに良いことに、_Layout.cshtml ファイル [@if (Roles. GetRolesForUser().Contains("Admin"))] を使用してメニュー オプションをフィルタリングし、ログイン ページでそれらを正しく実行します。以前に Index2 と Index3 にリダイレクトしようとしたことがありましたが、運がなかったので、これは本当に奇妙です。だから、別のコントローラーにリダイレクトする必要があるかもしれないと考え、「テスター」コントローラーを追加しました。サイコロはありません。

AccountController クラスには [InitializeSimpleMembership] 属性があり、元のコードを意図したとおりに機能させるために必要なことは、それを HomeController クラスの上に追加し、さらに「using MyProject.Filters;」を追加することだけです。声明。

さらに面白いのは、以前に対応するエラーが発生したときはいつでも「WebSecurity.InitializeDatabaseConnection」のソリューションを検索し、Filters フォルダーの「SimpleMembershipInitializer()」でステートメントを見つけてから、「SimpleMembershipInitializer」のソリューションを検索し、見つからなかったことです。その他のヒット。[InitializeSimpleMembership] 属性に隠されていることを誰が知っていましたか。

于 2013-09-27T15:48:49.923 に答える