绑定asp.net mvc核心中的Guid参数

gho*_*tie 8 c# asp.net-core-mvc asp.net-core

我想将Guid参数绑定到我的ASP.NET MVC Core API:

[FromHeader] Guid id
Run Code Online (Sandbox Code Playgroud)

但它总是空的.如果我将参数更改为字符串并手动解析字符串中的Guid,那么我认为它不会将Guid视为可转换类型.

文档中

在MVC中,简单类型是任何.NET基元类型或带有字符串类型转换器的类型.

Guids(GuidConverter)有一个类型转换器,但是ASP.NET MVC Core可能不知道它.

有谁知道如何将Guid参数与ASP.NET MVC Core绑定或如何告诉它使用GuidConverter?

Dan*_*.G. 12

我刚刚发现,基本上ASP Core只支持将字符串绑定到字符串和字符串集合!(而从路由值绑定,查询字符串和正文支持任何复杂类型)

您可以HeaderModelBinderProvider 在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;
}
Run Code Online (Sandbox Code Playgroud)

我已经提交了新的问题,但在此期间,我建议您绑定至一个字符串或创建自己的具体型号粘合剂(东西结合[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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将是一个使用它的例子:

public IActionResult SampleAction(
    [FromHeader(Name = "my-guid")][ModelBinder(BinderType = typeof(GuidHeaderModelBinder))]Guid foo)
{
    return Json(new { foo });
}
Run Code Online (Sandbox Code Playgroud)

您可以尝试使用,例如在浏览器中使用jquery:

$.ajax({
  method: 'GET',
  headers: { 'my-guid': '70e9dfda-4982-4b88-96f9-d7d284a10cb4' }, 
  url: '/home/sampleaction'
});
Run Code Online (Sandbox Code Playgroud)