简体   繁体   中英

Why the only hidden field that is being filled from GET action is not being passed in model?

Sorry for the long title, I didn't know how to make it any shorter.

  • My code:

My model:

public class CarFilter {
    public String carMake { get; set; }
    public String carModel { get; set; }
    public String carEdition { get; set; }
    .
    .
    .
    public String SortBy { get; set; }
}

public class CarSearch : CarFilter {
    public List<Car> Car { get; set; }
}

My controller:

public ActionResult SearchResult(CarSearch search)
    {
        var cars = from d in db.Cars
                   select d;

        if (Request.HttpMethod == "POST")
        {
            search.SortBy = "Price";
        }
        search.Car = new List<Car>();
        search.Car.AddRange(cars);

        var temp = new List<CarSearch>();
        temp.Add(search);

        return View(temp);
}

My Index view (where user filters results):

@model IEnumerable<Cars.Models.CarSearch>
@using (Html.BeginForm("SearchResult", "Home", FormMethod.Post)){..forms and other stuff..}

My SearchResult view (where user sees the results of filtration):

@model IEnumerable<Cars.Models.CarSearch>
@using (Html.BeginForm("SearchResult", "Home", FormMethod.Get))
{
@Html.Hidden("carMake")
@Html.Hidden("carModel")
@Html.Hidden("carEdition")
.
.
.
@Html.Hidden("SortBy")

<input name="SortBy" class="buttons" type="submit" value="Make"/>
  • My goal

What I'm trying to do is when user clicked on sort by Make it will have to GET back all the variables in hidden field back to the SearchResult action in order to sort the result (same filtered results).

  • Result

Is: <input id="SortBy" name="SortBy" type="hidden" value=""/> . The value is null and it's not being passed but all the other hidden fields such as carMake and etc have value. But when I use foreach it works perfect.

  • Question

Why is this like this? the SortBy is in the same model class as other fields in the view. The only difference is that SortBy is not being filled in the Index view with other fields, instead it's being filled in controller action. What is the explanation for this? Am I missing any C# definition or something such as dynamic objects or something?

You are not binding any of the html elements to anything in your model, you are just telling it to create hidden fields with specific names.

Instead of using @Html.Hidden("carMake") try @Html.HiddenFor(model => model.CarMake) .

Now, you are going to need to send your search settings to the view as well somehow. The inheritance you have on your ViewModels is throwing me off a bit. I don't think there's much of a reason for having CarSearch inherit from CarFilter . Is a search really a filter? It may be clearer to have the Action SearchResult receive a CarFilter , and return a CarSearch , where CarSearch could be:

public class CarSearch 
{
    public CarFilter Filter { get; set; }
    public List<Car> Cars { get; set; }
}

And the action would look like:

public ActionResult SearchResult(CarFilter filter)
{
    ...
    return View(new CarSearch {Filter = filter, Cars = <your result>});
}

That way your action is more clear regarding what is input and what is output. With that model your hidden fields would be something like:

@Html.HiddenFor(model => model.Filter.CarMake)

And for the actual Cars that represent the search result, you could either do a foreach , a partial view, or a Display template using @Html.DisplayFor() . I'd probably go with the last one.

Note : I changed the casing on your properties since you probably want to stick to the C# naming conventions.

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