0

I currently have a search form, it has three fields (a dropdown and two Nullable date fields for a date range,) and all of which are required to perform a query, from what I've seen in the asp.net/mvc docs, to perform validation I'm required to create a HttpGet action method to build the model display the page and then use HttpPost to take that model and validate it (and whatever else it needs to after that, RedirectToAction etc and such).

Because this is a search query, I'd rather avoid using the http POST verb and stick with http GET verb instead, but I can't for the life of me figure out how to achieve this without either the error messages appearing on the initial request (remember Nullable date fields) or, if I put default values in, the ModelState being valid.

Here are my two methods:

    [HttpGet]
    public ActionResult Index()
    {
        HomeIndexViewModel model = new HomeIndexViewModel()
        {
            SearchForm = new SearchFormViewModel()
            {
                GeoCounterDefinitions = geocounterservice.getAllDefinitions()
               .Select(x => new SelectListItem()
                {
                    Text = x.CounterKey + " " + x.FriendlyDesc,
                    Value = x.CounterKey.ToString()
                })
            }
        };

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(SearchFormViewModel search)
    {
        if (!ModelState.IsValid)
        {
            return View(new HomeIndexViewModel() {
                SearchForm = new SearchFormViewModel()
                {
                    CounterKey = search.CounterKey,
                    StartDate = search.StartDate,
                    EndDate = search.EndDate,
                    GeoCounterDefinitions = geocounterservice.getAllDefinitions()
                    .Select(x => new SelectListItem()
                    {
                        Text = x.CounterKey + " " + x.FriendlyDesc,
                        Value = x.CounterKey.ToString()
                    })
                }
            });
        }
        return RedirectToAction("Search");
    }
1
  • You could use your existing Index() method for the initial call and then have a (say) [HttpGet]public ActionResult Search(SearchFormViewModel search) { ... } method with both methods returning the save view with @using (Html.BeginForm("Search", yourController, FormMethod.Get)) Commented Nov 3, 2015 at 10:41

1 Answer 1

1

One way is to add a non-nullable property to SearchFormViewModel in order to detect if it's a form submit or not.

public class SearchFormViewModel 
{
     public bool IsSubmit {get; set;} 
} 

in your form with FormMethod.Get

Html.HiddenFor(m => m.IsSubmit, true) ; 

And then you can put both task (search display and actual search) in the same action :

[HttpGet]
public ActionResult Index(SearchFormViewModel search)
{
    if (search.IsSubmit) { 
       return ActualSearch(search) ; 
    }

    // Display search page

    HomeIndexViewModel model = new HomeIndexViewModel()
    {
        SearchForm = new SearchFormViewModel()
        {
            GeoCounterDefinitions = geocounterservice.getAllDefinitions()
           .Select(x => new SelectListItem()
            {
                Text = x.CounterKey + " " + x.FriendlyDesc,
                Value = x.CounterKey.ToString()
            })
        }
    };

    return View(model);
}

private ActionResult ActualSearch(SearchFormViewModel search)
{
    if (!ModelState.IsValid)
    {
        return View(new HomeIndexViewModel() {
            SearchForm = new SearchFormViewModel()
            {
                CounterKey = search.CounterKey,
                StartDate = search.StartDate,
                EndDate = search.EndDate,
                GeoCounterDefinitions = geocounterservice.getAllDefinitions()
                .Select(x => new SelectListItem()
                {
                    Text = x.CounterKey + " " + x.FriendlyDesc,
                    Value = x.CounterKey.ToString()
                })
            }
        });
    }
    return RedirectToAction("Search");
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.