我正在.NET MVC 3中实现REST层。我正在寻找一种干净的方法来获取Accept标头以确定我是否应该返回Json或Xml。
我还希望能够使用GET参数来欺骗此标头以进行调试(我希望这样做仍然可以生成)。
以下是我目前正在检测到的内容:
if (Request.AcceptTypes.Contains("application/json") || Request.Url.Query.Contains("application/json"))
这是我的控制器代码中唯一直接触及Request对象的地方。我想要一种更清晰,更可测试的方式来阅读它。我理想的解决方案是控制器上的参数。
我尝试了几个关键字来查看默认的模型绑定器是否会接收它,但我尝试过没有尝试过。
那么获取此信息的最简洁方法是什么?自定义模型绑定器?你能提供一个例子吗?
答案 0 :(得分:2)
动作过滤器属性将是一个很好的,干净的解决方案。
答案 1 :(得分:2)
我没有看到任何更好的替代自定义模型绑定器。我会发布我的粘合剂实现,以防其他人看到这个。使用模型绑定器允许Accept标头强烈绑定到操作的直接输入,允许直接测试返回类型,并且不会强制您人为地拥有比您需要的更多操作,也不会导致动态类型视图数据/袋。
这是带有支持枚举类型的Model Binder:
public enum RequestAcceptType
{
NotSpecified,
Json,
Xml
}
public class RequestAcceptTypeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
RequestAcceptType acceptType = RequestAcceptType.NotSpecified;
// Try for Json
if (controllerContext.HttpContext.Request.AcceptTypes.Contains("application/json") || controllerContext.HttpContext.Request.Url.Query.Contains("application/json"))
{
acceptType = RequestAcceptType.Json;
}
// Default to Xml
if (acceptType == RequestAcceptType.NotSpecified)
{
acceptType = RequestAcceptType.Xml;
}
return acceptType;
}
}
这是Application_Start方法中Global.asax中的相关位:
ModelBinders.Binders[typeof(RequestAcceptType)] = new RequestAcceptTypeModelBinder();
然后在你的动作中使用它,只需使用枚举类型:
创建一个参数(任何名称)public ActionResult Index(RequestAcceptType acceptType)
如果没有人在几天内用更好的方法回应,我会接受这个作为答案。