如何返回HTTP状态代码的形式自定义模型绑定

问题描述:

我有拉从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来处理这种情况?

如果你想返回一个特定的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