Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NETMVC中对绑定接受头建模的最干净方法_C#_Json_Asp.net Mvc 3_Model Binding - Fatal编程技术网

C# 在.NETMVC中对绑定接受头建模的最干净方法

C# 在.NETMVC中对绑定接受头建模的最干净方法,c#,json,asp.net-mvc-3,model-binding,C#,Json,Asp.net Mvc 3,Model Binding,我正在.NETMVC3中实现一个REST层。我正在寻找一种干净的方法来获取Accept头,以确定是否应该返回Json或Xml 我还希望能够使用GET参数欺骗此标头以进行调试(我希望它也能持久化到prod) 以下是我目前检测到的情况: if (Request.AcceptTypes.Contains("application/json") || Request.Url.Query.Contains("application/json")) 这是我的控制器代码中唯一直接接触请求对象的地方。我想要一

我正在.NETMVC3中实现一个REST层。我正在寻找一种干净的方法来获取Accept头,以确定是否应该返回Json或Xml

我还希望能够使用GET参数欺骗此标头以进行调试(我希望它也能持久化到prod)

以下是我目前检测到的情况:

if (Request.AcceptTypes.Contains("application/json") || Request.Url.Query.Contains("application/json"))
这是我的控制器代码中唯一直接接触请求对象的地方。我想要一个更干净,更可测试的方式来阅读这个。我的理想解决方案是控制器上的一个参数

我尝试了几个关键字,看看默认的模型绑定器是否能找到它,但我尝试的都没有效果


那么获取这些信息最干净的方法是什么?定制模型活页夹?你能提供一个例子吗?

一个动作过滤器属性将是一个好的、干净的解决方案


这里有一个很好的教程:

我没有看到比自定义模型活页夹更好的替代品。我将在这里发布我的活页夹实现,以防其他人看到。使用模型绑定器可以将Accept标头强绑定到操作的直接输入,从而允许直接测试返回类型,并且不会强制您人为地执行超出需要的操作,也不会导致动态类型的viewdata/bag

以下是支持枚举类型的模型绑定器:

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;
    }
}
public ActionResult Index(RequestAcceptType acceptType)
以下是应用程序启动方法中Global.asax中的相关位:

ModelBinders.Binders[typeof(RequestAcceptType)] = new RequestAcceptTypeModelBinder();
然后,要在操作中使用它,只需使用枚举类型创建一个参数(任何名称):

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;
    }
}
public ActionResult Index(RequestAcceptType acceptType)

如果几天内没有人用更好的方法回应,我会接受这个答案。

如果你不反对mvc4 webapi,你可以自己处理。更不用说在将来的某个时候,当你将你的应用迁移到mvc4+时,你将成为MVC已经为你做的事情的客户。搜索mvc4内容类型协商以获取更多信息。我注意到了这一点,对此感到非常兴奋,但不幸的是,我无法在RC下交付此项目,而且从我所知,4没有发布日期。@Mark,这与我现在用一个基本控制器和一对访问请求对象的两个助手类似,你特别要求模型绑定,但是你可以考虑创建一个自定义路由对象。重写GetRouteData,您可以在其中检查accept头并设置应执行的操作方法名称。请参阅“谢谢”以获得答案,但如果我理解正确,我将需要复制每个操作——一个用于Xml,一个用于Json。就封装性和可测试性而言,这似乎有点过分。或者我遗漏了什么?您可以将其注册为全局操作筛选器,并在一个筛选器中处理Xml和Json。。这不是你想要的吗?您仍然需要将其存储在ViewData/包中,我想这不是“干净的”。。