将查询参数绑定到ASP.NET Core中的模型

时间:2017-03-21 14:03:13

标签: c# asp.net asp.net-mvc asp.net-core model-binding

我正在尝试使用从查询参数到对象的模型绑定进行搜索。

我的搜索对象是

[DataContract]
public class Criteria 
{
  [DataMember(Name = "first_name")]
  public string FirstName { get; set; }
}

我的控制器有以下操作

[Route("users")]
public class UserController : Controller 
{
  [HttpGet("search")]
  public IActionResult Search([FromQuery] Criteria criteria)
  {
    ...
  }
}

当我按如下.../users/search?first_name=dave调用端点时,控制器操作的criteria属性为null。 但是,我可以将端点称为蛇案例.../users/search?firstName=dave,而criteria属性包含属性值。在这种情况下,模型绑定已经起作用,但是当我使用snake_case时没有。

如何在模型绑定中使用snake_case?

5 个答案:

答案 0 :(得分:29)

您需要将[FromQuery]属性分别添加到模型属性

public class Criteria
{
  [FromQuery(Name = "first_name")]
  public string FirstName { get; set; }
}

答案 1 :(得分:7)

.net core 2.1和2.2的解决方案

或者没有属性,您可以做类似我想更干净的事情(当然,如果模型属性与查询参数相同)。

同时我在.net core 2.1中使用它

public async Task<IActionResult> Get([FromQuery]ReportQueryModel queryModel) 
{ 

}

答案 2 :(得分:3)

对于像我这样从搜索引擎到达这里的人:

要使其在asp.net core 3.1+上正常工作

public async Task<IActionResult> Get([FromQuery] RequestDto request);

public class RequestDto
{
  [FromQuery(Name = "otherName")]
  public string Name { get; set; }
}

将json属性otherName读入RequestDto.Name中,因此基本上您必须在2个地方使用FromQuery。 恕我直言,以上答案对于asp.net框架中已经提供的这种简单操作来说太复杂了。

答案 3 :(得分:0)

根据@Carl Thomas的答案,这是使用蛇格FromQuery名称的更容易且清晰的方法:

CustomFromQuery

public class CustomFromQueryAttribute : FromQueryAttribute
{
    public CustomFromQuery(string name)
    {
        Name = name.ToSnakeCase();
    }
}

StringExtensions

public static class ObjectExtensions
{
  public static string ToSnakeCase(this string o) => Regex.Replace(o, @"(\w)([A-Z])", "$1_$2").ToLower();
}

用法

public class Criteria
{
   [CustomFromQuery(nameof(FirstName))]
   public string FirstName { get; set; }
}

答案 4 :(得分:-1)

如果 public async Task<IActionResult> Get([FromQuery] RequestDto request);

不适合任何人,你可以试试[FromRoute]

public async Task<IActionResult> Get([FromRoute] RequestDto request);

在您的 dto 中,您必须保留 [FromQuery]

public class RequestDto
{
  [FromQuery(Name = "otherName")]
  public string Name { get; set; }
}