我刚刚发现基本上 ASP Core 只支持将标头值绑定到字符串和字符串集合! (而路由值、查询字符串和正文的绑定支持任何复杂类型)
您可以查看HeaderModelBinderProvider source in Github 并亲自查看:
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.BindingInfo.BindingSource != null &&
context.BindingInfo.BindingSource.CanAcceptDataFrom(BindingSource.Header))
{
// We only support strings and collections of strings. Some cases can fail
// at runtime due to collections we can't modify.
if (context.Metadata.ModelType == typeof(string) ||
context.Metadata.ElementType == typeof(string))
{
return new HeaderModelBinder();
}
}
return null;
}
我已经提交了new issue,但同时我建议您绑定到字符串或创建自己的特定模型绑定器(将[FromHeader] 和[ModelBinder] 组合到您自己的绑定器中)
编辑
示例模型绑定器可能如下所示:
public class GuidHeaderModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(Guid)) return Task.CompletedTask;
if (!bindingContext.BindingSource.CanAcceptDataFrom(BindingSource.Header)) return Task.CompletedTask;
var headerName = bindingContext.ModelName;
var stringValue = bindingContext.HttpContext.Request.Headers[headerName];
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, stringValue, stringValue);
// Attempt to parse the guid
if (Guid.TryParse(stringValue, out var valueAsGuid))
{
bindingContext.Result = ModelBindingResult.Success(valueAsGuid);
}
return Task.CompletedTask;
}
}
这是一个使用它的例子:
public IActionResult SampleAction(
[FromHeader(Name = "my-guid")][ModelBinder(BinderType = typeof(GuidHeaderModelBinder))]Guid foo)
{
return Json(new { foo });
}
您可以尝试一下,例如在浏览器中使用 jquery:
$.ajax({
method: 'GET',
headers: { 'my-guid': '70e9dfda-4982-4b88-96f9-d7d284a10cb4' },
url: '/home/sampleaction'
});