Добавление ссылок на страницы в представление с использованием нескольких строк поиска ASP.NET Core Visual Studio 2017 — строка поиска не используется

Я разрабатываю представление индекса с разбивкой на страницы, ссылаясь на пример Сортировка, фильтрация, разбиение по страницам и группировка — руководство по EF Core с ASP.NET Core MVC (3 из 10)

На моей индексной странице я использую 3 строки поиска.

Сортировка работает очень хорошо, но без параметров поиска. Как только я пытаюсь отсортировать после ввода строки поиска, ничего не работает. Строка поиска должна быть принята. Этого не происходит.

Также пейджинг после вставки строки поиска не работает должным образом. Элементы ViewData с именем CurrentFilterxxx предоставляют представлению текущую строку фильтра. Это значение должно быть включено в ссылки на страницы, чтобы сохранить настройки фильтра во время страницы, и оно должно быть восстановлено в текстовом поле при повторном отображении страницы. В моем случае это не работает.

Вот мой метод Index класса контроллера:

public async Task<IActionResult> Index(
        string sortOrder, 
        string searchStringComune, 
        string searchStringProvincia, 
        string searchStringRegione,
        string searchString,
        string currentFilter,
        int? page)
    {
        ViewData["CurrentSort"] = sortOrder;
        ViewData["ComuneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "comune" : "";
        ViewData["ProvinciaSortParm"] = String.IsNullOrEmpty(sortOrder) ? "provincia" : "";
        ViewData["RegioneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "regione" : "";
        ViewData["PostalCodeSortParm"] = String.IsNullOrEmpty(sortOrder) ? "CAP" : "";
        ViewData["AbitantsSortParm"] = String.IsNullOrEmpty(sortOrder) ? "abitanti" : "";

        if (searchStringComune != null ||
            searchStringProvincia != null ||
            searchStringRegione != null ||
            searchString != null)
        {
            page = 1;
            if (searchStringComune != null)
            {
                searchString = searchStringComune;
            }
            if (searchStringProvincia != null)
            {
                searchString = searchStringProvincia;
            }
            if (searchStringRegione != null)
            {
                searchString = searchStringRegione;
            }
        }
        else
        {
            searchString = currentFilter;
        }

        ViewData["CurrentFilterComune"] = searchStringComune;
        ViewData["CurrentFilterProvincia"] = searchStringProvincia;
        ViewData["CurrentFilterRegione"] = searchStringRegione;
        ViewData["CurrentFilter"] = searchString;

        var comuni = from s in _context.Listacomuniitaliani
                       select s;

        if (!String.IsNullOrEmpty(searchStringComune) ||
            !String.IsNullOrEmpty(searchStringProvincia) ||
            !String.IsNullOrEmpty(searchStringRegione))
        {

            comuni = comuni.Where(s => s.Comune.Equals(searchStringComune) ||
                                       s.Provincia.Equals(searchStringProvincia) ||
                                       s.Regione.Equals(searchStringRegione));
        }

        switch (sortOrder)
        {
            case "comune":
                comuni = comuni.OrderByDescending(s => s.Comune);
                break;
            case "provincia":
                comuni = comuni.OrderBy(s => s.Provincia);
                break;
            case "regione":
                comuni = comuni.OrderBy(s => s.Regione);
                break;
            case "CAP":
                comuni = comuni.OrderBy(s => s.Cap);
                break;
            case "abitanti":
                comuni = comuni.OrderBy(s => s.Abitanti);
                break;
            default:
                comuni = comuni.OrderBy(s => s.Comune);
                break;
        }

        int pageSize = 7;
        return View(await PaginatedList<Listacomuniitaliani>.CreateAsync(comuni.AsNoTracking(), page ?? 1, pageSize));
    }

А вот мой индексный код:

@model PaginatedList<MyProjectName.Models.Listacomuniitaliani>

@{ViewData["Title"] = "Index";}

<h2>Index</h2>

<p>
<a asp-action="Create">Create New</a>
</p>

<form asp-action="Index" method="get">
    <div class="form-actions no-color">
        <p>
            Cerca un comune: <input type="text" name="SearchStringComune" value="@ViewData["currentFilterComune"]" />
            <input type="submit" value="trova" class="btn btn-default" />
        </p>
    </div>
</form>

<form asp-action="Index" method="get">
<div class="form-actions no-color">
    <p>
        Seleziona una provincia: <input type="text" name="SearchStringProvincia" value="@ViewData["currentFilterProvincia"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
</div>

<form asp-action="Index" method="get">
<div class="form-actions no-color">
    <p>
        Seleziona una regione: <input type="text" name="SearchStringRegione" value="@ViewData["currentFilterRegione"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
</div>

<form asp-action="Index" method="get">
<div class="form-actions no-color">
    <p>
        <a asp-action="Index">Torna indietro alla lista</a>
    </p>
</div>

<table class="table">
<thead>
    <tr>
            <th>
                Istat
            </th>
            <th>
                    <a asp-action="Index" asp-route-sortOrder="@ViewData["ComuneSortParm"]"
                       asp-route-currentFilterComune="@ViewData["CurrentFilterComune"]">Comune</a>                       
    </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["ProvinciaSortParm"]"
                   asp-route-currentFilterProvincia="@ViewData["CurrentFilterProvincia"]">Provincia</a>
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["RegioneSortParm"]"
                   asp-route-currentFilterRegione="@ViewData["CurrentFilterRegione"]">Regione</a>
            </th>
            <th>
                Prefisso
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["PostalCodeSortParm"]">CAP</a>
            </th>
            <th>
                CodFisco
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["AbitantsSortParm"]">Abitanti</a>
            </th>
            <th>
                Link
            </th>
        <th></th>
    </tr>
</thead>
<tbody>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Istat)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Comune)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Provincia)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Regione)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Prefisso)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Cap)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CodFisco)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Abitanti)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Link)
        </td>
        <td>
            <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
            <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
            <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
        </td>
    </tr>
     }
</tbody>
</table>

@{
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.HasNextPage ? "disabled" : "";
}


<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-page="@(Model.PageIndex - 1)"
@*asp-route-currentFilter="@ViewData["CurrentFilter"]"*@
asp-route-currentFilterComune="@ViewData["CurrentFilterComune"]"
asp-route-currentFilterRegione="@ViewData["CurrentFilterRegione"]"
asp-route-currentFilterProvincia="@ViewData["CurrentFilterProvincia"]"
class="btn btn-default @prevDisabled">
Previous
</a>

<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-page="@(Model.PageIndex + 1)"
@*asp-route-currentFilter="@ViewData["CurrentFilter"]"*@
asp-route-currentFilterComune="@ViewData["CurrentFilterComune"]"
asp-route-currentFilterRegione="@ViewData["CurrentFilterRegione"]"
asp-route-currentFilterProvincia="@ViewData["CurrentFilterProvincia"]"
class="btn btn-default ifextDisabled">
Next
</a>

The tag helper asp-route-currentFilter has not been used.Instead, I have used more specific tag helpers; for instance asp-route-currentFilterComune.

Любая помощь приветствуется.




Ответы (1)


У меня это работает. Для этого мне пришлось перепроектировать часть контроллера и внести некоторые изменения в код представления. Обработка более чем одной строки поиска была для меня довольно сложной задачей.

Вот мой новый метод индексации контроллера:

public async Task<IActionResult> Index(
        string sortOrder, 
        string searchStringComune, 
        string searchStringProvincia, 
        string searchStringRegione,
        string searchString,
        string currentFilter,
        int? page)
    {
        ViewData["CurrentSort"] = sortOrder;
        ViewData["ComuneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "comune" : "";
        ViewData["ProvinciaSortParm"] = String.IsNullOrEmpty(sortOrder) ? "provincia" : "";
        ViewData["RegioneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "regione" : "";
        ViewData["PostalCodeSortParm"] = String.IsNullOrEmpty(sortOrder) ? "CAP" : "";
        ViewData["AbitantsSortParm"] = String.IsNullOrEmpty(sortOrder) ? "abitanti" : "";


        if (searchStringComune != null ||
            searchStringProvincia != null ||
            searchStringRegione != null ||
            searchString != null)
        {
            page = 1;
        }
        else
        {
            searchStringProvincia = currentFilter;
            searchStringRegione = currentFilter;

            foreach (ItalianRegions itemRegion in Enum.GetValues(typeof(ItalianRegions)))
            {
                if (searchStringRegione == itemRegion.ToString())
                {
                    searchStringProvincia = null;
                }
            }

            foreach (ItalianComunes itemComune in Enum.GetValues(typeof(ItalianComunes)))
            {
                if (searchStringProvincia == itemComune.ToString())
                {
                    searchStringRegione = null;
                }
            }

        }


        ViewData["CurrentFilterComune"] = searchStringComune;
        ViewData["CurrentFilterProvincia"] = searchStringProvincia;
        ViewData["CurrentFilterRegione"] = searchStringRegione;
        ViewData["CurrentFilter"] = searchString;

        var comuni = from s in _context.Listacomuniitaliani
                       select s;

        if (!String.IsNullOrEmpty(searchStringComune) ||
            !String.IsNullOrEmpty(searchStringProvincia) ||
            !String.IsNullOrEmpty(searchStringRegione))
        {
            comuni = comuni.Where(s => s.Comune.Equals(searchStringComune) ||
                                       s.Provincia.Equals(searchStringProvincia) ||
                                       s.Regione.Equals(searchStringRegione));
        }

        switch (sortOrder)
        {
            case "comune":
                comuni = comuni.OrderByDescending(s => s.Comune);
                break;
            case "provincia":
                comuni = comuni.OrderBy(s => s.Provincia);
                break;
            case "regione":
                comuni = comuni.OrderBy(s => s.Regione);
                break;
            case "CAP":
                comuni = comuni.OrderBy(s => s.Cap);
                break;
            case "abitanti":
                comuni = comuni.OrderBy(s => s.Abitanti);
                break;
            default:
                comuni = comuni.OrderBy(s => s.Comune);
                break;
        }


        int pageSize = 7;
        return View(await PaginatedList<Listacomuniitaliani>.CreateAsync(comuni.AsNoTracking(), page ?? 1, pageSize));
    }

Я зациклился на строке поиска, используя 2 разных enum, чтобы иметь возможность правильно установить текст строки поиска в поле поиска при подкачке.

Вот код Index:

@model PaginatedList<MyProject.Models.Listacomuniitaliani>

@{
 ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>
 <a asp-action="Create">Create New</a>
</p>

<form asp-action="Index" method="get">
    <div class="form-actions no-color">
        <p>
            Cerca un comune: <input type="text" name="searchStringComune"    value="@ViewData["CurrentFilterComune"]" />
            <input type="submit" value="trova" class="btn btn-default" />
        </p>
    </div>
</form>


<form asp-action="Index" method="get">
 <div class="form-actions no-color">
    <p>
        Seleziona una provincia: <input type="text" name="searchStringProvincia" value="@ViewData["CurrentFilterProvincia"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
  </div>
</form>

<form asp-action="Index" method="get">
  <div class="form-actions no-color">
    <p>
        Seleziona una regione: <input type="text" name="searchStringRegione" value="@ViewData["CurrentFilterRegione"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
  </div>
</form>

<form asp-action="Index" method="get">
  <div class="form-actions no-color">
    <p>
        <a asp-action="Index">Torna indietro alla lista</a>
    </p>
  </div>
 </form>


 <table class="table">
  <thead>
    <tr>
            <th>
                Istat
            </th>
            <th>
                    <a asp-action="Index" asp-route-sortOrder="@ViewData["ComuneSortParm"]">Comune</a>
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["ProvinciaSortParm"]"
                   asp-route-currentFilter="@ViewData["CurrentFilterProvincia"]">Provincia</a>
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["RegioneSortParm"]"
                   asp-route-currentFilter="@ViewData["CurrentFilterRegione"]">Regione</a>
            </th>
            <th>
                Prefisso
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["PostalCodeSortParm"]">CAP</a>
            </th>
            <th>
                CodFisco
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["AbitantsSortParm"]">Abitanti</a>
            </th>
            <th>
                Link
            </th>
        <th></th>
     </tr>
    </thead>
  <tbody>

   @foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Istat)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Comune)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Provincia)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Regione)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Prefisso)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Cap)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CodFisco)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Abitanti)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Link)
        </td>
        <td>
            <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
            <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
            <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
        </td>
    </tr>
     }
   </tbody>
  </table>

   @{
     var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
     var nextDisabled = !Model.HasNextPage ? "disabled" : "";
    }


 <a asp-action="Index"
    asp-route-sortOrder="@ViewData["CurrentSort"]"
    asp-route-page="@(Model.PageIndex - 1)"
    asp-route-currentFilter=@if (@ViewData["CurrentFilterRegione"] != null)
    {
      @ViewData["CurrentFilterRegione"]
    } else
    {
      @ViewData["CurrentFilterProvincia"]
    }
    class="btn btn-default @prevDisabled">
    Previous
 </a>
 <a asp-action="Index"
    asp-route-sortOrder="@ViewData["CurrentSort"]"
    asp-route-page="@(Model.PageIndex + 1)"
    asp-route-currentFilter=@if (@ViewData["CurrentFilterRegione"] != null)
    {
      @ViewData["CurrentFilterRegione"]
    } else
    {
    @ViewData["CurrentFilterProvincia"]
    }
    class="btn btn-default @nextDisabled">
    Next
</a>

Теперь он работает отлично. Сортировка работает. Пейджинг также работает, сохраняя текст строки поиска.

person Code4Fun    schedule 18.07.2017
comment
Ваше название и решение вводят в заблуждение. Несколько строк поиска означают, что вы можете фильтровать по более чем 1 критерию. То, что вы сделали, это просто копирование и вставка кода, чтобы он соответствовал любому количеству строк поиска, которые у вас есть, и фильтрация только с использованием 1 строки поиска, поэтому ваше решение недействительно. - person TykiMikk; 22.07.2020
comment
Привет, TykiMikk, пожалуйста, учтите, что проблема в этом случае заключалась в сочетании разбиения на страницы вместе с более чем 1 строкой поиска. Возможно, я мог бы изменить название, чтобы лучше описать сложную ситуацию. Что ты предлагаешь? Для меня решение действительно, если оно решает проблему. Наверняка всегда есть более элегантный способ, но я не профессионал и меня это решение устраивает. В любом случае, я открыт для любого предложения. - person Code4Fun; 22.07.2020