2017-02-24 156 views
4

结合一个GUID参数我想一个GUID参数绑定到我的ASP.NET MVC核心API:在asp.net mvc的核心

[FromHeader] Guid id 

但它总是空。如果我将参数更改为字符串并手动解析字符串中的Guid,它会起作用,所以我认为它没有将Guid检测为可转换类型。

the documentation它说

在MVC简单类型与字符串类型转换器任何.NET基本类型或类型。

Guid有一个类型转换器(GuidConverter),但也许ASP.NET MVC核心不知道它。

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

+0

怎么样使用FromBody属性? –

+0

我使用的FromHeader属性,因为我想要的值是在标题不是正文 – ghosttie

+0

只是为了澄清,这似乎是''[FromHeader]'绑定源特定的问题。我可以从查询字符串和正文中正确绑定Guid。 –

回答

7

我刚刚发现,基本上ASP核心只支持字符串和字符串集合的绑定标题值! (而来自路径的值,查询字符串和身体的结合支持任何复杂类型)

您可以检查HeaderModelBinderProvidersource 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' 
});