我在同时从自定义标头和请求正文绑定模型时遇到问题。
这是我的模型:
public class TestModel
{
public int Id { get; set; }
public string Name { get; set; }
public HeaderModel HeaderModel { get; set; }
}
public class HeaderModel
{
public int Version { get; set; }
public string Test { get; set; }
}
我有一个简单的测试页面,其中发布了以下内容:
$(function() {
var go = function() {
$.ajax({
type: 'POST',
url: '/api/values',
data: { id: 1, name: 'theValue2' },
headers: { HeaderModel: JSON.stringify({version: 1, test:"roar"}) }
}).always();
};
$('input').click(go);
});
我创建了以下标头值提供程序:
public class HeaderValueProvider<T> : IValueProvider where T : class
{
private readonly HttpRequestHeaders _headers;
public HeaderValueProvider(HttpRequestHeaders headers)
{
_headers = headers;
}
public bool ContainsPrefix(string prefix)
{
var test = typeof (T).Name == prefix;
return test;
}
public ValueProviderResult GetValue(string key)
{
if (typeof (T).Name == key)
{
IEnumerable<string> headerStrings;
_headers.TryGetValues(key, out headerStrings);
var strings = headerStrings.ToArray();
if (headerStrings != null && strings.Any())
{
var value = strings.First();
var obj = JsonConvert.DeserializeObject<T>(value,
new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
return new ValueProviderResult(obj, value, CultureInfo.InvariantCulture);
}
}
return null;
}
}
public class HeaderValueProviderFactory<T> : ValueProviderFactory where T : class
{
public override IValueProvider GetValueProvider(HttpActionContext actionContext)
{
var headers = actionContext.ControllerContext.Request.Headers;
return new HeaderValueProvider<T>(headers);
}
}
它已在配置中注册:
config.Services.Add(typeof(ValueProviderFactory), new HeaderValueProviderFactory<HeaderModel>());
如果我像下面这样使用我的控制器,我会得到我的模型绑定,但不是我的标题。它使用媒体格式化程序:
public IHttpActionResult Post(TestModel model)
{
return Ok(model);
}
如果我包含 ModelBinder 属性,我会得到 HeaderModel 绑定,但不是来自请求正文的模型的其余部分:
public IHttpActionResult Post([ModelBinder]TestModel model)
{
return Ok(model);
}
让两者都工作的最干净的方法是什么?