1

我从头开始创建了一个 VS 2012 MVC API 项目,加载了 Nuget“WebApiContrib.Formatting.Jsonp”,添加了一个路由格式化程序,并尝试将参数作为序列化 JSON 作为 JSONP 请求发送。如何识别或访问控制器中的这些参数?

WebApiConfig:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}/{format}",
    defaults: new { id = RouteParameter.Optional, 
        format = RouteParameter.Optional }
);
config.Formatters.Insert(0, new JsonpMediaTypeFormatter());

接口方法:

public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

查询:

$.ajax({
    type: 'GET',
    url: '/api/Values',
    data: JSON.stringify({ "message": "\"Hello World\"" }),
    contentType: "application/json; charset=utf-8",
    dataType: 'jsonp',
    success: function (json) {
        console.dir(json.sites);
    },
    error: function (e) {
        console.log(e.message);
    }
});

我尝试修改 Api 方法以包括:

Get( [FromUri] string value)
Get( [FromBody] string value)
Get( CustomClass stuff)
Get( [FromUri] CustomClass stuff)
Get( [FromBody] CustomClass stuff)

其中 CustomClass 定义为:

public class CustomClass
{
    public string message { get; set; }
}

到目前为止,这些都没有为参数产生任何东西,但 null 。我应该如何从查询字符串中发布的对象连接这些参数?

编辑:

我可以通过将 JQuery ajax 修改为:

data: {"value":JSON.stringify({ "message": "\"Hello World\"" })}

为此,我可以取消字符串化[FromUri] string value并获取我的强类型对象。

不过,我希望数据绑定器将参数反序列化为强类型对象。什么技术使这种情况发生?

4

1 回答 1

1

您正在发出GET请求,如果有GET请求,则没有正文,只有 URI。您为$.ajax()调用提供的所有数据都将放入 URI,例如您的 EDIT 版本将生成如下 URI:

.../api/Values?value=%7B%22message%22%3A%22%5C%22Hello%20World%5C%22%22%7D

(请注意,JSON 也将进行 URL 编码)。

现在 Web API 中的 URI 参数使用 绑定ModelBinderParameterBinding,这意味着 Web API 将不使用任何MediaTypeFormatter(输出复杂类型),而是使用ModelBinder/ ValueProvider(在这种情况下将输出简单类型 - 字符串)。

您可以通过实现自定义来处理您的方案ModelBinder(请记住使用来自 ASP.NET Web API 命名空间而不是 ASP.NET MVC 命名空间的适当类和接口):

public class JsonModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == null)
            return false;

        bindingContext.Model = JsonConvert.DeserializeObject(valueProviderResult.AttemptedValue, bindingContext.ModelType);

        return true;
    }
}

public class JsonModelBinderProvider : ModelBinderProvider
{
    public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        return new JsonModelBinder();
    }
}

并将其附加到您的参数ModelBinderAttribute

public IEnumerable<string> Get([ModelBinder(typeof(JsonModelBinderProvider))]CustomClass value)
{
    return new string[] { "value1", "value2" };
}

您可以在此处找到有关该主题的更多详细信息:

于 2013-04-29T09:41:40.640 回答