18

この投稿を示唆するような方法で、 ASP.NET MVC サイトにエラー処理を実装しました。

404 エラーで、すべて正常に動作します。しかし、 401エラーに対してユーザーフレンドリーな画面をどのように正しく表示するのでしょうか? それらは通常、内部で処理できる例外をスローしませんApplication_Error()が、アクションは HttpUnauthorizedResult を返します。Application_EndRequest()考えられる方法の 1 つは、メソッドの最後に次のコードを追加することです。

if (Context.Response.StatusCode == 401)
{
    throw new HttpException(401, "You are not authorised");
    // or UserFriendlyErrorRedirect(new HttpException(401, "You are not authorised")), witout exception
}

ただしApplication_EndRequest()、Context.Session == null内でerrorController.Execute()は、デフォルトの TempDataProvider を使用できないため失敗します。

  // Call target Controller and pass the routeData.
  IController errorController = new ErrorController();
  errorController.Execute(new RequestContext(    
       new HttpContextWrapper(Context), routeData)); // Additional information: The SessionStateTempDataProvider requires SessionState to be enabled.

では、ASP.NET MVC アプリケーションで 401 を「ユーザー フレンドリーに処理」するためのベスト プラクティスをいくつか提案できますか?

ありがとう。

4

4 に答える 4

14

HandleErrorAttribute を見てください。そこからサブクラス化するか、関心のあるすべてのステータス コードを処理する独自の実装を追加します。エラー タイプごとに個別のエラー ビューを返すようにすることができます。

ハンドル エラー例外フィルターを作成する方法のアイデアを次に示します。必要なものだけに集中するために、ほとんどのものを捨てました。元の実装を見て、引数のチェックやその他の重要なことを追加してください。

public class HandleManyErrorsAttribute : FilterAttribute, IExceptionFilter
{
    public virtual void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            return;

        Exception exception = filterContext.Exception;

        string viewName = string.Empty;
        object viewModel = null;
        int httpCode = new HttpException(null, exception).GetHttpCode();
        if (httpCode == 500)
        {
            viewName = "Error500View";
            viewModel = new Error500Model();
        }
        else if (httpCode == 404)
        {
            viewName = "Error404View";
            viewModel = new Error404Model();
        }
        else if (httpCode == 401)
        {
            viewName = "Error401View";
            viewModel = new Error401Model();
        }

        string controllerName = (string)filterContext.RouteData.Values["controller"];
        string actionName = (string)filterContext.RouteData.Values["action"];
        filterContext.Result = new ViewResult
        {
            ViewName = viewName,
            MasterName = Master,
            ViewData = viewModel,
            TempData = filterContext.Controller.TempData
        };
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = httpCode;

        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

次に、この属性を使用してコントローラー アクションを「装飾」します。

[HandleManyErrors]
public ActionResult DoSomethingBuggy ()
{
    // ...
}
于 2009-11-05T11:20:51.467 に答える
6

私はこれを非常に簡単な方法で解決することができました。ログインしているユーザー向けのカスタム ページを表示し ("you have no permission bla bla...")、認証されていないユーザーをログイン ページ (デフォルトの動作) にリダイレクトしたいと考えました。したがって、ユーザーが認証された場合に、filterContext 引数の Result プロパティを ViewResult (Shared フォルダー内) と呼ばれる AccessDenied.aspx に設定するように、HandleUnauthorizedRequest メソッドを上書きしてカスタム AuthorizeAttribute (CustomAuthorizeAttribute など) を実装しました。

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
    else
    {
        filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
    }
}

次に、代わりにこの新しい属性を使用する必要があります。よろしく。

于 2010-01-22T12:54:52.380 に答える
0

ASP.NET MVCを使用している場合は、IISを使用する可能性が高いので、そのWebアプリケーション/仮想ディレクトリのカスタム401エラーページを使用するようにIISを設定してみませんか?

于 2009-11-05T11:40:41.300 に答える
-1

私のプロジェクトの 1 つで、uvitaのコードを使用しています。

ASP.NET MVC2があり、ログイン ページなしでActive Directory認証を使用しています。サイト マスター ページを使用するNoAuth.aspxページがあり、Web アプリケーション レイアウトを統合します。

これは web.config です。

<system.web>
    <authentication mode="Windows" />
    <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
       <providers>
          <clear />
          <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider"
          applicationName="/" />
      </providers>
    </roleManager>
</system.web>

新しいクラス CustomAutorizeAttribute

using System.Web.Mvc;
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        else
        {
           filterContext.Result = new ViewResult { ViewName = "NoAuth"};
        }
    }
}

そしてコントローラー

[CustomAuthorize(Roles = "ADRole")]
public class HomeController : Controller
{
    public HomeController()
    {
    }
}
于 2015-10-19T14:15:58.890 に答える