在 asp.net mvc core 中绑定 Guid 参数 [英] binding a Guid parameter in asp.net mvc core

查看:10
本文介绍了在 asp.net mvc core 中绑定 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 有一个类型转换器 (GuidConverter) 但也许 ASP.NET MVC Core 不知道.

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 Github 中的源码 自己看看:

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 core 中绑定 Guid 参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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