【问题标题】:Asp.Net Core MVC - Complex Model not binding on Get Controller actionAsp.Net Core MVC - 复杂模型未绑定到获取控制器操作
【发布时间】:2019-11-05 14:49:06
【问题描述】:

我的视图和控制器之间的某个地方不匹配,导致后者接收到一个复杂的对象,其中充满了空值。

[HttpGet("find")]
[ProducesResponseType(typeof(PagableResults<UserDetails>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[SwaggerOperation("FindUsers")]
public async Task<IActionResult> FindUsers([FromQuery]FindUsersSearchFilter searchFilters)

而 searchFilters 对象是这样定义的:

public class FindUsersSearchFilter
{
    public int? Page { get; set; }

    public string Username { get; set; }

    public string Firstname { get; set; }

    public string Surname { get; set; }
}

View 在查询字符串中发送数据(因为它是一个 get 方法),如下所示:

/find?SearchFilters.Page=1&SearchFilters.Firstname=foo&SearchFilters.Surname=bar&SearchFilters.Username=

但是,如果您调试控制器操作,则会遇到断点,但该方法接收到的 FindUsersSearchFilter 对于每个属性都有一个空值。

我尝试过的事情:

  • 在控制器操作上绑定(Prefix="SearchFilters")。
  • 在控制器操作上绑定("Page,Firstname,Surname,Username")
  • 手动更改 URL 以删除前缀并更改大小写
  • 正在删除 [FromQuery]

不知道下一步该去哪里。关于我做错了什么有什么建议吗?

【问题讨论】:

  • 这种类型的请求通常作为POST 而不是GET 更容易。
  • @nurdyguy 是的,但这绝对是一个 GET,因为它是一个搜索功能。复杂对象是传递多个参数的便捷方式。
  • @BobTway 我明白你的意思。这当然可以通过任何一种方式完成,只需 更简单 和 cleaner 作为POST。

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


【解决方案1】:

请求错误。应该是:

/find?Page=1&Firstname=foo&Surname=bar&Username=

当您为所有属性添加 SearchFilters 前缀时,绑定引擎很可能会寻找嵌套属性,例如 searchFilters.SearchFilters.FirstName。

所以删除前缀应该可以工作。

如果您确实需要在查询中使用该语法;然后像这样创建另一个类:

public class SearchFilterContainer
{
    public FindUsersSearchFilter SearchFilters { get; set; } = new FindUsersSearchFilter();
}

并将其作为参数传递给操作,而不是像这样:

[HttpGet("find")]
[ProducesResponseType(typeof(PagableResults<UserDetails>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[SwaggerOperation("FindUsers")]
public async Task<IActionResult> FindUsers([FromQuery]SearchFilterContainer searchFilters)

然后在您的控制器中,您可以像这样访问模型searchFilters.SearchFilters.FirstName

【讨论】:

  • 我很确定它有效。当我创建了一个演示应用程序并且它工作得很好......至于“未能通过流体验证”我不确定这意味着什么。因为 HTTP 和 ASP.NET Core 都不需要它......如果你真的需要那个不必要的前缀,那么你将不得不将你的类嵌套在另一个类中
  • 我给了你一个保留前缀的解决方案。
猜你喜欢
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-28
相关资源
最近更新 更多