3

MEF コンテナーからインターフェイスの実装をプルするカスタム モデル バインダーがあります。次のように実装されます。

public class PetViewModelBinder : DefaultModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var petId = bindingContext.ValueProvider.GetValue("id");
        var container = controllerContext.HttpContext.Application[MvcApplication.PLUGINS] as CompositionContainer;
        Lazy<IPet, IPetMetadata> pet = null;
        try
        {
            pet = container.GetExport(typeof(IPet), petId);
            var petVM = new Models.PetViewModel(pet);
            bindingContext.ModelMetadata.Model = petVM;

            return base.BindModel(controllerContext, bindingContext);
        }
        catch (Exception)
        {

            throw;
        }
        finally
        {
            container.ReleaseExport(pet);
        }

    }

これは、MEF が petId のエクスポートを持っている場合はうまく機能しますが、エクスポートが存在しない場合は http ステータス 500 (サーバー エラー) を返します。エラー メッセージの難読化要件により、http ステータス 403 (禁止) が返される必要があります。

エラーをトラップし、応答ステータスを変更し、コンテンツを返さないか、この状態を処理するためにアクションを再ルーティングするにはどうすればよいですか?

4

1 に答える 1

5

特定の http ステータス コードを返したい場合は、コントローラーまたはアクション フィルターからそれを行う必要があります。

これを行う 1 つの方法は、モデル バインダーから null を返し、それをコントローラーで処理することです。ただし、これは少し粗いため、さまざまなエラーを区別することはできません。

それを行う別の方法は、特定の例外をスローし、それを (グローバル) エラー処理で処理することです。カスタマイズされた HandleError アクション フィルターは、これを行うことができます。

public class CustomHandleErrorAttribute : HandleErrorAttribute
{
  public int StatusCode { get; set; }

  public override void OnException( ExceptionContext filterContext )
  {
     base.OnException( filterContext );
     if ( StatusCode > 0 )
     {
        filterContext.HttpContext.Response.StatusCode = StatusCode;
     }
  }
}

コントローラーで、アクションを次の属性で装飾します。

[CustomHandleError( ExceptionType = typeof (NotAllowedException), View = "~/Views/Shared/Error.cshtml",
     StatusCode = 403 )]
public ActionResult Index( FancyModel model )
{
   return View( model );
}

最後に、モデル バインダーで NotAllowedException をスローします。これは、定義する必要があるカスタム例外タイプです。

これは、web.config ファイルでカスタム エラーを有効にしている場合にのみ、開発セットアップで機能することに注意してください。

于 2012-06-25T07:13:56.633 に答える