views:

50

answers:

2

Hi!

I'm new to MVC!

I am trying to use two DropDownLists (Cities, Categories) in a PartialView that will be used in MasterPage, meaning they will be visble all the time.

I tried to load them in HomeCOntroller, but that didn't work. I got an Exception.

I read something about making a baseController that the other controllers will inherit from, I have tried that, kind of, but I guess i'm doing something wrong.

This is the only code I got today:

Masterpage

<% Html.RenderPartial("SearchForm"); %>

PartialView (SearchForm.ascx)

<% using (Html.BeginForm("Search", "Search")) { %>
<% } %> // dont know why I need two BeginForms, if I dont have this the other form won't trigger at all! Weird!

<% using (Html.BeginForm("Search", "Search", FormMethod.Get)) { %>

    <%= Html.DropDownList("SearchForm.Category",  new SelectList(ViewData["Categories"] as IEnumerable, "ID", "Name", "--All categories--")) %>

    <%= Html.DropDownList("Search.City", Model.Cities, "--All cities--") %>
    <input name="search" type="text" size="16" id="search" />
    <input type="submit" id="test" title="Search" />
    <% } %>

Two question:

  1. Where and how to load the DropDownLists is the problem. I have tried to load it in the HomeController, but when go to another page then it says that the DDLs is empty and I get a Excecption.
  2. Why do I have to use two forms for the ActionMethod to trigger ?

Hope anyone can help me out!

+2  A: 

It sounds like you're only setting the property for a single action result. The Model.Cities data will have to be populated for every single view that needs to use it.

One solution would be to move the population of it to an ActionFilter

public class CityListAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        var result = filterContext.Result as ViewResult;
        result.ViewData.Model = //populate model
        base.OnActionExecuted(filterContext);
    }
}

and then add the filter to your controller

[CityList]
public class HomeController : Controller {  
    public ActionResult Index() {
        return View();
    }
}

As for the two forms issue, there should be no reason that i can think of that you need an empty form.

Take a look at the html that's being output and make sure it's ok. Also check the action is being generated correcly

big dave
Hey big dave! Thansks for your help!If im using ActionFilter i have to put this actionResult on every controller that is used, right ? I read about another solution something that you can make a baseController and load the ddls in the constructors and make all controllers inherit from the BaseController. I have tried it, but I dont understand exactly. What do you think big dave ?
That should work. Just create a new class (eg. BaseController) that inherits from Controller. Then change your controller (and any other controllers that need this action) to inherit from BaseController instead of Controller. Then you could either apply the CityList filter to BaseController, or set the value in the constructor of BaseController
big dave
+1  A: 

Better way to do this, is to create something like MasterController and have action method on it like this:

[ChildActionOnly]
public ActionResult SearchForm()
{
    //Get city data, category data etc., create SearchFormModel
    return PartialView(model);
}

I recommend you create strongly typed view (SearchForms.ascx of type ViewUserControl<SearchFormModel>). Also it may be a good idea to have a model like this:

public class SearchViewModel
{
    public IList<SelectListItem> Cities { get; set; }
    public IList<SelectListItem> Categories { get; set; }
}

and use a helper like this: http://github.com/Necroskillz/NecroNetToolkit/blob/master/Source/NecroNet.Toolkit/Mvc/SelectHelper.cs to convert raw data to DDL friendly format beforehand.

In any case, you now use Html.RenderAction() instead of Html.RenderPartial() and specify you want "SearchForm" action from "MasterController".

Necros