2

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!

tereško
  • 58,060
  • 25
  • 98
  • 150
user1041169
  • 639
  • 2
  • 9
  • 18

1 Answers1

0

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.
Konstantin
  • 3,817
  • 4
  • 29
  • 39
  • This seems a little odd to me it would be this complicated. I already have JS validation but want to include server side validation as well. I would assume this is a common problem as a lot of websites implement login forms and other user data that can be posted from any page and require validation. What is the common practice here? Send them to a new page just for validation? Copying the action code to every control? Adding the actions and code to a controller base? Something else that I am completely missing? – user1041169 Nov 15 '11 at 22:32
  • This seems like such common functionality that maybe I am missing something completely different and render-action is not the correct solution. – user1041169 Nov 15 '11 at 22:38
  • One other solution would be to use partial view and implement logic behind it in some global action filter. There is still a problem that you would be posting just a search form data, so, if you current page was "POSTed" to, this POST data will be lost. – Konstantin Nov 16 '11 at 07:45
  • Ok, so I added a
    – user1041169 Nov 19 '11 at 06:34