简体   繁体   中英

MVC Application, Orderby not working in Home Controller Index

I am working on sorting an index of books based on the date in which they are published in conjunction with keyword search parameters. I am using a switch statement that selects enum values which would tell the Action to Order search results differently, ascending or descending. However, it seems that Orderby is not working, but the first case statement does work. No matter what, the program would only sort by Newest first. Oldest first does not work.

public IActionResult Index(String SearchString, Classification DateValueSign)
    {


        var query = from r in _db.Books select r;

        if (SearchString != null && SearchString != "")
        {
            query = query.Where(x => x.Title.Contains(SearchString) || x.Author.Contains(SearchString) || x.Genre.GenreName.Contains(SearchString));

        }
        switch (DateValueSign)
        {
            case Classification.NewestFirst:
                query = query.OrderByDescending(x => x.PublicationDate);
                break;
            case Classification.OldestFirst:
                query = query.OrderBy(x => x.PublicationDate);
                break;
            case Classification.MostPopular:
                query = query.OrderByDescending(x => x.AverageRating);
                break;
            case Classification.LeastPopular:
                query = query.OrderBy(x => x.AverageRating);
                break;
        }
        List<Book> SelectedBooks = new List<Book>();
        SelectedBooks = query.ToList();
        ViewBag.SelectedBooks = SelectedBooks.Count();
        ViewBag.TotalBooks = _db.Books.Count();

        return View(SelectedBooks);
    } 

Here is the view for index. The quick search is on the index page.

@model IEnumerable<fa18team16BevoBookStore.Models.Book>
@{
    ViewData["Title"] = "View";
}
@using fa18team16BevoBookStore.Controllers
<!--This is the quick search box code-->
<form asp-action="Index" asp-controller="Home" method="get">
    <p class="form-group">
        Search: <input name="SearchString" class="form-control" /><br />
        <button type="submit" class="btn btn-secondary">Search</button>
        <a asp-action="Index" class="btn btn-danger">Show All</a>
    </p>
</form>
<p>Displaying @ViewBag.SelectedBooks out of @ViewBag.TotalBooks </p>
<h2>View</h2>
<div class="form-group">
    <label class="radio">@Html.RadioButton("DateValueSign", 
Classification.NewestFirst)Newest First</label>
    <label class="radio">@Html.RadioButton("DateValueSign", 
Classification.OldestFirst)Oldest First</label>
    <label class="radio">@Html.RadioButton("DateValueSign", 
Classification.MostPopular)Most Popular</label>
    <label class="radio">@Html.RadioButton("DateValueSign", 
Classification.LeastPopular)Least Popular</label>
</div>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.UniqueID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Author)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Description)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.BookQuantity)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.UniqueID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Author)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Description)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.BookQuantity)
                </td>
                <td>
                    <a asp-action="Details" asp-route- 
id="@item.BookID">Details</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Firstly, the commonest reason why an enum always has the same value is that a value was not rightly assigned so, it is assigned as its default value. The default value of an enum is 0 , that is the very first value you defined inside your Classification enum. In your case, NewestFirst seems to be the default. This behavior means that the DateValueSign value isn't getting passed.

Secondly, for debugging issues that might be related to Razor renders, always check the inspect element to verify the code generated. Thirdly, when tackling such server-side issues like case statements, the debugger is quite handy.

Regarding your issue, MVC needs the number value of your enum, else it defaults to 0. If you check your radio buttons in your inspect element, you would notice the value attribute shows a string like value="LeastPopular" when it is supposed to show something like value="3" . This happens because the RadioButton function takes any enum assigned as a string. To achieve this, simply cast each of your enums in razor as an int .

For example, this:

 <label class="radio">@Html.RadioButton("DateValueSign", Classification.NewestFirst)Newest First</label>

Becomes this:

<label class="radio">@Html.RadioButton("DateValueSign", (int) Classification.NewestFirst)Newest First</label>

For your issue, it is caused by that you are placing <label class="radio">@Html.RadioButton("DateValueSign", Classification.NewestFirst)Newest First</label> outside of <form asp-action="Index" asp-controller="Home" method="get"> , and then no matter what you select for DateValueSign , it is never been passed to controller and uses the default value for Classification .

Move the @Html.RadioButton to form like

<form asp-action="Index" asp-controller="Model" method="get">
    <p class="form-group">
        Search: <input name="SearchString" class="form-control" /><br />
        <div class="form-group">
            <label class="radio">
                @Html.RadioButton("DateValueSign", Classification.NewestFirst)Newest First
            </label>
            <label class="radio">
                @Html.RadioButton("DateValueSign", Classification.OldestFirst)Oldest First
            </label>
            <label class="radio">
                @Html.RadioButton("DateValueSign", Classification.MostPopular)Most Popular
            </label>
            <label class="radio">
                @Html.RadioButton("DateValueSign", Classification.LeastPopular)Least Popular
            </label>
        </div>

        <button type="submit" class="btn btn-secondary">Search</button>
        <a asp-action="Index" class="btn btn-danger">Show All</a>
    </p>
</form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM