6

Na mojej stronie mam:model jest zerowy po odświeżenie strony w pager

  • sekcja „filtr” - kilka pól i pól tekstowych,
  • przycisk „szukaj”,
  • siatki z stronicowania gdzie wyświetlane są wyniki. Siatka pochodzi z Telerik (http://demos.telerik.com/aspnet-mvc/grid/index1), ale nie sądzę, aby miało to znaczenie.

Wyszukiwanie działa OK - mogę wpisać tekst lub zaznaczyć pole wyboru w sekcji filtra, a zostaną wyświetlone odpowiednie wyniki.

Paging działa poprawnie tylko wtedy, gdy używam go, gdy strona jest ładowana (co oznacza, że ​​zanim kliknę przycisk Szukaj, w tym przypadku adres URL to "... Home").

Ale jeśli najpierw klikniesz w wyszukiwarkę (w tym przypadku URL będzie "... Strona główna/Szukaj"), a następnie spróbuj przejść do innej strony w sieci, to otrzymam wyjątek w metodzie wyszukiwania, ponieważ model Parametr .Filter ma wartość NULL (System.NullReferenceException: Odwołanie do obiektu nie jest ustawione na wystąpienie obiektu).

Próbowałem rozwiązać problem na wiele różnych sposobów (z metodą RedirectToAction, zapisując filtr w sesji i używając go w Metoda wyszukiwania, ...) ale żadne rozwiązanie nie działało we wszystkich scenariuszach. Jakieś pomysły?

Moja uproszczony kod:

HomeController:

public ActionResult Index() 
{ 
    // On page load display all data without filters. 
    var filter = new OverviewFilterModel 
    { 
     Type1 = true, 
     Type2 = true, 
     WorkingOrder = "" 
    }; 
    ViewBag.Results = GetResults(filter); 
    return View(new HomeModel { Filter = filter }); 
} 

public ActionResult Search(HomeModel model) 
{ 
    ViewBag.Results = GetResults(model.Filter); 
    return View("Index"); 
} 

public class OverviewFilterModel 
{ 
    public bool Type1 { get; set; } 
    public bool Type2 { get; set; } 
    public string WorkingOrder { get; set; } 
} 

public class HomeModel 
{ 
    public OverviewFilterModel Filter { get; set; } 
    public IEnumerable<OverviewResultsModel> Results { get; set; } 
} 

Widok:

<!-- ... --> 
@model HomeModel 
<!-- ... --> 

@using (Html.BeginForm("Search", "Home", FormMethod.Post, new { @class = "form-inline" })) 
{ 
    <div class="form-group" style="margin-left: 135px;"> 
     @Html.CheckBoxFor(p => p.Filter.Type1)@Html.LabelFor(p => p.Filter.Type1, new { style = "margin: 0 15px 0 5px;" }) 
    </div> 
    <!-- a bunch of other checkboxes --> 
    <br /> 
    <div class="form-group"> 
     <label style="width: 130px; text-align: right;">Delovni nalog</label> 
     @Html.TextBoxFor(p => p.Filter.WorkingOrder, new { @class = "form-control ecert-filter-small", @autocomplete = "off" }) 
    </div> 
    <!-- a bunch of other textboxes --> 
    <button class="k-button" id="button-refresh" style="margin: 10px 0 0 135px;">Refresh</button> 
    <hr /> 
    @(Html.Kendo().Grid<OverviewResultsModel>() 
     .BindTo((IEnumerable<OverviewResultsModel>)ViewBag.Results) 
     .Name("gridOverview") 
     .Events(p => p.Change("overviewOnRowSelect")) 
     .Columns(columns => 
     { 
      columns.Template(@<text>@Html.ActionLink("WorkingOrder", "Index", "WO", new { dn = @item.WorkingOrder }, new { @class = "selectable-dn" })</text>).Title(""); 
      columns.Bound(p => p.Type); 
      columns.Bound(p => p.WorkingOrder); 
      columns.Bound(p => p.Date); 
      columns.Bound(p => p.ProductId); 
      columns.Bound(p => p.ProductName); 
     }) 
     .Selectable() 
     .Pageable(p => p 
      .Refresh(true) 
      .PageSizes(true) 
      .ButtonCount(10) 
      .Messages(q => 
      { 
       q.Display("{0} - {1} od {2} records"); 
       q.Empty("No data for selected filter"); 
       q.ItemsPerPage("Number of records per page"); 
      }) 
     ) 
     .DataSource(p => p.Server().PageSize(20).Model(q => { q.Id(r => r.WorkingOrder); })) 
    ) 
} 
+1

Może powinieneś sprawdzić model, a jeśli jest zerowy, zrób to. Poza tym nie rozumiem, gdzie jest zmienna 'filter' zdefiniowana w twojej metodzie" Index "? Jeśli potrzebujesz użyć danych przez kilka stron, zalecam użycie 'TempData' zamiast' ViewBag'. –

+0

Edytowałem moje pytanie - w metodzie indeksu (gdy strona ładuje się) filtr jest pusty, więc wszystkie dane powinny być wyświetlane. Dodałem również klasę HomeModel, która jest używana w widoku (@model HomeModel). – sventevit

Odpowiedz

3

Rozwiązałem to za pomocą obiektów sesyjnych - jednego dla filtra i drugiego dla wyniku. Nie jest to najbardziej eleganckie rozwiązanie, ale działa.

public ActionResult Index() 
{ 
    // On page load display all data without filters. 
    OverviewFilterModel filter; 
    if (Session["filter"] == null) { 
     var filter = new OverviewFilterModel 
     { 
      Type1 = true, 
      Type2 = true, 
      WorkingOrder = "" 
     }; 
    } 
    else { 
     filter = (OverviewFilterModel)Session["filter"]; 
    } 

    if (Session["results"] == null){ 
     ViewBag.Results = GetResults(filter); 
    } 
    else{ 
     ViewBag.Results = Session["results"]; 
    } 

    return View(new HomeModel { Filter = filter }); 
} 

public ActionResult Search(HomeModel model) 
{ 
    if (model.Filter == null) 
    { 
     model.Filter = (OverviewFilterModel)Session["filter"]; 
    } 

    ViewBag.Results = GetResults(model.Filter); 
    return View("Index"); 
} 

private IEnumerable<OverviewResultModel> GetResults(OverviewFilterModel filter){ 
    var data = ... 

    Session["results"] = data; 
    Session["filter"] = filter; 

    return data; 
} 
2

Prawdopodobnie w ten sposób pomaga przez uchwyt wartości NULL HomeModel.Filter w metody poszukiwania przed wykonaniem GetResults(model.Filter):

public ActionResult Search(HomeModel model) 
{ 
    if (model.Filter == null) 
    { 
     model.Filter = new OverviewFilterModel 
     { 
      Type1 = true, 
      Type2 = true, 
      WorkingOrder = "" 
     }; 
    } 
    ViewBag.Results = GetResults(model.Filter); 
    return View("Index", new HomeModel { Filter = filter }); 
} 

Po prostu stwierdziłem, że wartość pusta powinna być obsługiwana przez warunek if, aby zapobiec NRE, CMIIW.

+0

To nie jest w porządku, ponieważ w tym przypadku tracę informacje o filtrze. Na przykład zaznaczam pole wyboru w sekcji filtru i klikam Szukaj. Wyświetlane są poprawne dane. Ale potem klikam na stronie 2 na pager siatki, a druga strona jest wyświetlana dla WSZYSTKICH danych, ponieważ oryginalne dane filtra zostaną utracone. – sventevit

+0

Musisz więc przechowywać swój filtr w ciasteczkach, a następnie go pobrać. –