2

我有拉從MEF容器的接口的實現自定義模型粘合劑。它的實現如下:如何返回HTTP狀態代碼的形式自定義模型綁定

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(禁止)。

可以做些什麼來捕獲錯誤,更改響應狀態,並且不返回內容,或重新路由Action來處理這種情況?

回答

4

如果你想返回一個特定的http狀態代碼,你應該從控制器或動作過濾器來完成。要做到這一點

一種方法是從你的模型綁定返回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文件中啓用了自定義錯誤,則這隻適用於您的開發設置。

+1

謝謝!這當然給了我一個不同的方式來看問題。全局錯誤處理在這個項目上不起​​作用,但是,自定義錯誤處理程序應該工作。 – psaxton