如何在嵌套模型中使用FromQuery?

huangapple go评论105阅读模式
英文:

How to use FromQuery with nested models?

问题

以下是翻译的内容:

我有一个类似于这样的主页视图模型:

public class LandingViewModel : BaseHomeViewModel
{
    public List<Country> Countries { get; set; } = null!;

    public List<MissionCardViewModel> MissionCards { get; set; } = null!;

    // 搜索模型
    public SearchViewModel Search { get; set; } = new SearchViewModel();
}

正如您所看到的,我们有一个嵌套模型 `Search`,用于搜索。它包含以下字段:

public class SearchViewModel
{
    public string? Query { get; set; }

    public Country SelectedCountry { get; set; } = null!;
    
    [FromQuery(Name = "sortBy")]
    public SortBy SortMissionsBy { get; set; } = SortBy.None;

    public List<Filter> Cities { get; set; } = null!;
    public List<Filter> Themes { get; set; } = null!;
    public List<Filter> Skills { get set; } = null!;
}

正如您所看到的,我已将 `[FromQuery]` 属性应用于 SortMissionsBy 字段。而在 HTML 部分,我还为输入字段指定了 `name="sortBy"`。然而,模型绑定不起作用。如果使用通常的 `asp-for="Search.SortMissionsBy"`,它将生成一个名称为 **Search.SortMissionsBy** 的名称,这太长了,不适合 URL

那么,我如何在查询字符串中使用一个简单的名称,比如 **sortBy**,同时绑定嵌套模型 `SearchViewModel` 中的数据呢?我不想扁平化我的 `LandingViewModel` 类。
英文:

I have a view model for Home page like this:

public class LandingViewModel : BaseHomeViewModel
{
    public List&lt;Country&gt; Countries { get; set; } = null!;

    public List&lt;MissionCardViewModel&gt; MissionCards { get; set; } = null!;

    // Search model
    public SearchViewModel Search { get; set; } = new SearchViewModel();
}

Here as you can see we have a nested model Search which will be used for searching. It contains the following fields:

public class SearchViewModel
{
    public string? Query { get; set; }

    public Country SelectedCountry { get; set; } = null!;
    
    [FromQuery(Name = &quot;sortBy&quot;)]
    public SortBy SortMissionsBy { get; set; } = SortBy.None;

    public List&lt;Filter&gt; Cities { get; set; } = null!;
    public List&lt;Filter&gt; Themes { get; set; } = null!;
    public List&lt;Filter&gt; Skills { get; set; } = null!;
}

As you can see I have applied the [FromQuery] attribute to SortMissionsBy field. And in the html side I've also given the input field a name=&quot;sortBy&quot;. However, the model binding does not work. It works perfectly if use the usual asp-for=&quot;Search.SortMissionsBy&quot; which will generate a name of Search.SortMissionsBy, which I don't want as it's too big for a URL.

So, how can I use a simple name for query string like sortBy while also binding the data present in a nested Model like SearchViewModel? I don't want to flatten my LandingViewModel class.

答案1

得分: 0

我终于找到了解决方案。所以,它的工作原理如下:

  1. 给嵌套的视图模型一个空的名称,如 [FromQuery(Name = "")]。这样,可以在不写视图模型名称的情况下访问嵌套属性。例如,我们只需写 cityId,而不是 Search.cityId
  2. 在嵌套的视图模型中给属性任意名称,例如 cityId

现在,我们可以轻松地使用 ?cityId=<some-id> 进行 GET 请求,并将其绑定到嵌套视图模型的属性 Search.cityId

如果这对你也有效,请在评论中告诉我。

完整代码

public class LandingViewModel : BaseHomeViewModel
{
    public List<Country> Countries { get; set; } = null!;

    public List<MissionCardViewModel> MissionCards { get; set; } = null!;

    // 搜索模型
    
    // 步骤:1
    [FromQuery(Name = "")]
    public SearchViewModel Search { get; set; } = new SearchViewModel();
}
public class SearchViewModel
{
    public string? Query { get; set; }

    public Country SelectedCountry { get to  set; } = null!;
    
    // 步骤:2
    [FromQuery(Name = "sortBy")]
    public SortBy SortMissionsBy { get; set; } = SortBy.None;

    ...
}
英文:

I've finally found the solution. So, it works like this:

  1. Give an empty name to the nested viewmodel like [FromQuery(Name = &quot;&quot;)]. In this way the nested properties will be accessible without writing the name of viewmodel. For e.g., We can just write cityId instead of Search.cityId.
  2. Give the properties in nested viewmodel whatever name you like. For e.g., cityId.

Now we can easily make a GET request with ?cityId=&lt;some-id&gt; and it will be bound to the nested viewmodel's property Search.cityId.

Please tell me in comments if it works for you as well.

Full code

public class LandingViewModel : BaseHomeViewModel
{
    public List&lt;Country&gt; Countries { get; set; } = null!;

    public List&lt;MissionCardViewModel&gt; MissionCards { get; set; } = null!;

    // Search model
    
    // Step: 1
    [FromQuery(Name = &quot;&quot;)]
    public SearchViewModel Search { get; set; } = new SearchViewModel();
}
public class SearchViewModel
{
    public string? Query { get; set; }

    public Country SelectedCountry { get; set; } = null!;
    
    // Step: 2
    [FromQuery(Name = &quot;sortBy&quot;)]
    public SortBy SortMissionsBy { get; set; } = SortBy.None;

    ...
}

huangapple
  • 本文由 发表于 2023年3月9日 19:04:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683726.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定