为了账号安全,请及时绑定邮箱和手机立即绑定

为模型绑定到集合类型指定相等比较器

为模型绑定到集合类型指定相等比较器

C#
呼如林 2021-11-07 20:21:11
我有一个 API,您可以在其中指定要获取的名称列表。不允许出现重复名称,如果两个名称仅因大小写不同而被视为重复名称。GET /api/people?names=john&names=alice在我自己的 .NET 代码中,我将HashSet使用自定义相等比较器将所有这些名称收集到一个中。var names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);但我认为 ASP.NET Core 模型绑定不够灵活。// GET /api/people?names=john&names=JOHN[HttpGet("api/people")]public GetPeople([FromQuery] HashSet<string> names){    // this works but names contains both john and JOHN}我必须更改什么才能使该names集合仅包含 john 而不是 JOHN?
查看完整描述

3 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

您可以List<string>在方法头中使用 a ,然后根据您的规则将其加载到 HashSet 中:


public GetPeople([FromQuery] List<string> names)

{

    var hashed = new HashSet<string>(names, StringComparer.OrdinalIgnoreCase);

}

作为替代方案,您可以查看自定义模型绑定,但只有在多个地方需要它时才值得付出努力。


查看完整回答
反对 回复 2021-11-07
?
智慧大石

TA贡献1946条经验 获得超3个赞

您可以使用HashSet<string>设置为始终使用的导数StringComparer.OrdinalIgnoreCase:


// Case Insensitive String HashSet, or CIStringSet for short.

public class CIStringSet : HashSet<string>

{

    public CIStringSet() : base(StringComparer.OrdinalIgnoreCase)

    {

    }

}

使用它非常简单,如下所示:


public object GetPeople([FromQuery] CIStringSet names)

{

    return Json(names);

}

经过测试,它有效:

//img1.sycdn.imooc.com//6187c4e600012c4005110069.jpg

查看完整回答
反对 回复 2021-11-07
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

一个完全没有错误处理的静态解决方案,但有效的是以下


粘合剂:


public Task BindModelAsync(ModelBindingContext bindingContext)

{

    var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);


    bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);


    var values = valueProviderResult.Values.Select(value => value).ToHashSet(StringComparer.OrdinalIgnoreCase);


    bindingContext.Result = ModelBindingResult.Success(values);


    return Task.CompletedTask;

}

端点:


[HttpGet]

public IActionResult Test([ModelBinder(typeof(HashSetBinder))] IEnumerable<string> values)

{

    return Ok(new

    {

        values

    });

}

然后像这样打开网址:


http://localhost:5000/api/mycontroller?values=1&values=1&values=1&values=2


结果将是 {"values":["1","2"]}


这可以通过模型绑定提供程序全局注册,但为此它需要实现更多检查。


查看完整回答
反对 回复 2021-11-07
  • 3 回答
  • 0 关注
  • 169 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信