Question

I am new to MVC and trying to implement what I would expect to be a common problem. I have a simple search form that I want to implement on each page of the site. I want this section to maintain its own code so that I don't have to duplicate it on each page.

So far I have been able to do this by calling a render action on the template page. The render action populates the quicksearch form. When I submit the form I am able to validate the form, however I have not found a way to redisplay the same page with the validation information. I would prefer a way that would just refresh the form area, but I would accept a full postback as long as the page is redisplayed.

Template Render Call

@{Html.RenderAction("Display", "QuickSearch");}

ActionController

    [HttpPost]
    public ActionResult Submit(QuickSearchModel qsModel)
    {
        if (!ModelState.IsValid)
        {
            return PartialView(qsModel);
        }

        //Perform redirect
    }

 [ChildActionOnly]
        public ActionResult Display()
        {
           //populate model
           return View(qsModel);
         }

Quick Search View

<div>
    @using (Html.BeginForm("Submit", "QuickSearch"))
    { 
        @Html.ValidationSummary(true)
        @Html.LabelFor(m => m.Destination)@Html.EditorFor(m => m.Destination)@Html.ValidationMessageFor(m => m.Destination)<br />
        @Html.LabelFor(m => m.ArrivalDate)@Html.EditorFor(m => m.ArrivalDate)@Html.ValidationMessageFor(m => m.ArrivalDate)
        @Html.LabelFor(m => m.DepartureDate)@Html.EditorFor(m => m.DepartureDate)@Html.ValidationMessageFor(m => m.DepartureDate)<br />
        @Html.LabelFor(m => m.Adults)@Html.DropDownListFor(model => model.Adults, new SelectList(Model.AdultsSelectOptions, "value", "text", Model.Adults))<br />
        @Html.LabelFor(m => m.Children)@Html.DropDownListFor(model => model.Children, new SelectList(Model.ChildrenSelectOptions, "value", "text", Model.Children))<br />
        <input id="qsSubmit" name="qsSubmit" type="submit" value="Submit" />
    }
</div>

Thanks in advance for any assistance!

Was it helpful?

Solution

I see that you have the following problems:

  1. How to redirect back to the page, from which the search was made?
  2. What if this original page was "POSTed to" - that is it was rendering something, based on POST request? In this case we will not be able to "re-produce" this POST in any easy way;
  3. After we have redirected to the original page, how to communicate the search model (or just it's errors), which we have failed to validate?

Given all these challenges, I would first seriously consider making this search form in AJAX style. That would be much easier solution, if it fits you.

If AJAX is not an option I see following solutions to the respective questions:

  1. I would make a hidden field in the search form with the URL of original page. When validation fails, we can redirect to this URL (just check that it is local URL and no one tries to brake something);
  2. This is a major problem - trying to replay original POST is not easy, but it may not be needed either - just check if this is a problem anyway;
  3. You could use TempData dictionary to communicate errors or model back to original page.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top