在ASP.NET MVC核心中绑定Guid参数 [英] binding a Guid parameter in asp.net mvc core

查看:84
本文介绍了在ASP.NET MVC核心中绑定Guid参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to bind a Guid parameter to my ASP.NET MVC Core API:

[FromHeader] Guid id

,但始终为空.如果我将参数更改为字符串并手动从字符串中解析Guid,那么它将起作用,因此我认为它不会将Guid检测为可转换类型.

but it's always null. If I change the parameter to a string and parse the Guid from the string manually it works, so I think it's not detecting Guid as a convertable type.

文档中说,

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

In MVC simple types are any .NET primitive type or type with a string type converter.

有一个Guid的类型转换器(

There is a type converter for Guids (GuidConverter) but maybe ASP.NET MVC Core doesn't know about it.

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

Does anyone know how to bind a Guid parameter with ASP.NET MVC Core or how to tell it to use GuidConverter?

推荐答案

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

I have just found out that basically ASP Core only supports binding header values to strings and collections of strings! (whereas binding from route values, query string and body supports any complex type)

您可以检查HeaderModelBinderProvider

You can check the HeaderModelBinderProvider source in Github and see for yourself:

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;
}

我已经提交了新问题,但与此同时,我建议您要么绑定到字符串或创建您自己的特定模型活页夹(将[FromHeader][ModelBinder]组合到您自己的活页夹中的东西)

I have submitted a new issue, but in the meantime I would suggest you either bind to a string or create your own specific model binder (something that combines [FromHeader] and [ModelBinder] into your own binder)

修改

样本模型联编程序可能如下所示:

The sample model binder could look like this:

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;
    }
}

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

And this would be an example using it:

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

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

Which you can try, for example with jquery in the browser:

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

这篇关于在ASP.NET MVC核心中绑定Guid参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆