ASP.NET 6 MVC通过从枚举选择列表传递到控制器操作的枚举筛选器

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

ASP.NET 6 MVC Filter by enum passed into controller action from enum select list

问题

我在视图中有一个基于枚举的选择列表。我可以将选择列表中选择的值传递给控制器操作,但在筛选枚举值时遇到了困难。

换句话说,我有一个博客中的帖子列表,这些帖子具有"已准备就绪"的状态。我只想根据"已准备就绪"的状态筛选帖子。

问题是,帖子模型中的readyStatus属性记录的是枚举的索引,而不是它的值。例如,枚举中的"Production Ready"值以"2"的值记录,这是它的索引。

因此,我已经尝试了一些选项。

1.) 从将传递到控制器操作的选择列表中获取索引值。

2.) 将选择列表的值(字符串),例如"ProductionReady",转换为枚举列表中的相应索引,然后根据该索引进行筛选。

在控制器操作的逻辑中,我尝试比较从选择列表传递的值。

任何帮助将不胜感激!

相关代码如下:

帖子模型

public ReadyStatus ReadyStatus { get; set; }

枚举

public enum ReadyStatus
{
    Incomplete,
    PreviewReady,
    ProductionReady
}

控制器

public async Task<IActionResult> IndexFilter(string? readyStatus)
{
    var posts = new List<Post>();
    if (readyStatus is null)
    {
        posts = await _context.Posts
        .Include(p => p.Blog)
        .Include(p => p.BlogUser)
        .OrderByDescending(p => p.Updated != null)
        .ThenByDescending(p => p.Updated)
        .ThenByDescending(p => p.Created)
        .ToListAsync();
    }
    else
    {
        //int readyStatusInt = (int)ReadyStatus.$"{readyStatus}";
        posts = await _context.Posts?
        //.Where(p => p.ReadyStatus == readyStatusInt)
        .Where(p => p.ReadyStatus.Equals(readyStatus))
        .Include(p => p.Blog)
        .Include(p => p.BlogUser)
        .OrderByDescending(p => p.Updated != null)
        .ThenByDescending(p => p.Updated)
        .ThenByDescending(p => p.Created)
        .ToListAsync();
    }

    ViewData["ReadyStatus"] = new SelectList(Enum.GetValues(typeof(ReadyStatus)).Cast<ReadyStatus>().ToList());
    return View(posts);
}

视图

<form asp-action="IndexFilter" asp-controller="Posts">
    <div class="input-group d-flex flex-md-row">
        {{-- <label class="form-label me-2">Filter by Category:</label> --}}
        <select name="readyStatus" asp-items="@ViewBag.ReadyStatus" class="form-select w-50"
                onchange="this.form.submit()" onfocus="this.selectedIndex=-1;">
            <option value="" selected disabled hidden>Filter By Status</option>
        </select>
    </div>
</form>
英文:

I have a select list in my view based on an enum. I can pass the value chosen in the select list to the controller action ok, but am having difficulty filtering on that enum value.

In other words. I have a list of posts in a blog that have a ready status. I just want to filter the posts by the ready status.

The thing is, the readyStatus property in the post model records the index of the enum, not its value. For example, the "Production Ready" value in the enum, is recorded with the value of "2", which is its index.

So I've been playing with a few options.

1.)Get the index value from the select list that will be passed into the controller action.

2.) Convert the select list value(string), for example "ProductionReady" and find its corresponding index in the enum list, then filter by that.

In the logic in the controller action, I am trying to compare the passed in value from the select list.

Any help would be greatly appreciated!

Relevant code below

Post model

public ReadyStatus ReadyStatus { get; set; }

Enum

    public enum ReadyStatus
    {
        Incomplete,
        PreviewReady,
        ProductionReady
    }

Controller

public async Task&lt;IActionResult&gt; IndexFilter(string? readyStatus)
        {
            
            var posts = new List&lt;Post&gt;();
            if (readyStatus is null)
            {
                posts = await _context.Posts
                .Include(p =&gt; p.Blog)
                .Include(p =&gt; p.BlogUser)
                .OrderByDescending(p =&gt; p.Updated != null)
                .ThenByDescending(p =&gt; p.Updated)
                .ThenByDescending(p =&gt; p.Created)
                .ToListAsync();
            }
            else
            {
                //int readyStatusInt = (int)ReadyStatus.$&quot;{readyStatus}&quot;;
                posts = await _context.Posts?
                //.Where(p =&gt; p.ReadyStatus == readyStatusInt)
                .Where(p =&gt; p.ReadyStatus.Equals(readyStatus))
                .Include(p =&gt; p.Blog)
                .Include(p =&gt; p.BlogUser)
                .OrderByDescending(p =&gt; p.Updated != null)
                .ThenByDescending(p =&gt; p.Updated)
                .ThenByDescending(p =&gt; p.Created)
                .ToListAsync();
            }

            ViewData[&quot;ReadyStatus&quot;] = new SelectList(Enum.GetValues(typeof(ReadyStatus)).Cast&lt;ReadyStatus&gt;().ToList());
            return View(posts);
        }

View

    &lt;form asp-action=&quot;IndexFilter&quot; asp-controller=&quot;Posts&quot;&gt;
        &lt;div class=&quot;input-group  d-flex flex-md-row&quot;&gt;
            @*&lt;label class=&quot;form-label me-2&quot;&gt;Filter by Category:&lt;/label&gt;*@
            &lt;select name=&quot;readyStatus&quot; asp-items=&quot;@ViewBag.ReadyStatus&quot; class=&quot;form-select w-50&quot;
                    onchange=&quot;this.form.submit()&quot; onfocus=&quot;this.selectedIndex=-1;&quot;&gt;
                &lt;option value=&quot;&quot; selected disabled hidden&gt;Filter By Status&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
    &lt;/form&gt;

答案1

得分: 1

你可以尝试以下方式将你收到的字符串转换为ReadyStatus:

ReadyStatus readyStatus = (ReadyStatus)Enum.Parse(typeof(ReadyStatus), "PreviewReady");

尝试:

.Where(x => x.ReadyStatus == ReadyStatus.PreviewReady)

现在在我的一侧可以正常工作。

英文:

You could try as below to convert the string you received to ReadyStatus :

ReadyStatus readyStatus = (ReadyStatus)Enum.Parse(typeof(ReadyStatus), &quot;PreviewReady&quot;);

Try

.Where(x =&gt; x.ReadyStatus== ReadyStatus.PreviewReady)

It works on myside now:

ASP.NET 6 MVC通过从枚举选择列表传递到控制器操作的枚举筛选器

huangapple
  • 本文由 发表于 2023年6月15日 12:41:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76479167.html
匿名

发表评论

匿名网友

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

确定