views:

146

answers:

2

I have a drop down list hardcoded in a MVC View User Control page and would like to populate this from a database table. The MVC View page Inherits data coming in from my controller. This drop down list would contain something like a list of states for the user to choose to set an item for my main object. This list would not fit into the data that is being passed into the View.

Where and how would you get the data for the drop down list into an MVC View user control? Webform user controls have a code-behind page which could help loading this information from the database and pass to the html rendering side. How would this be done with MVC using the correct separation of concerns approach?

Controller

public ActionResult Inboxes() 
{ 
    var vm = new ListInboxesViewModel(); 
    vm.Inboxes = MyDataService.GetInboxes().OrderBy(i => i.InboxName); 
    return View(vm); 
} 

Main View

<% Html.RenderPartial("InboxesGrid", Model.Inboxes); %>

Partial View

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<MoniteredInbox>>" %> 
<div> 
   <table>
       <tr><td>
           <select id="SelectedStateddl">
               <!-- Selected states from database Table -->
           </select>
       </td></tr>
   </table> 
</div> 
+1  A: 

If you are using ASP.NET MVC 2 you could take advantage of the RenderAction method on the HTML helper:

<% Html.RenderAction(actionNamne, controllerName); %>

This will call the action and controller you specify which can then call the UserControl view directly with it's model.

This would allow you to build up a suitable view model for the drop down.

Zhaph - Ben Duguid
I am this far. I guess I was somewhat vague on my question. See my changes above
+3  A: 

Zhaph - Ben Duguid's suggestion is a good one. You could also create a partial view that your main view renders and passes the necessary piece of the model to.

For example... I have a strongly typed view for "Inboxes" that is bound to my InboxesViewModel. I then render the partial view InboxesGrid and also pass in the list of inboxes. My partial view is also strongly typed to and allows me to use the data whichever way I'd like on the partial view.

CONTROLLER

    public ActionResult Inboxes()
    {
        var vm = new ListInboxesViewModel();
        vm.Inboxes = MyDataService.GetInboxes().OrderBy(i => i.InboxName);
        return View(vm);
    }

MAIN VIEW

    <% Html.RenderPartial("InboxesGrid", Model.Inboxes); %>

PARTIAL VIEW

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<MoniteredInbox>>" %>
    <div>
        <%= Html.DropDownListFor(model=>model.Inbox.InboxId, 
                 Model.Inboxes.ToSelectList(
                       x => x.InboxId.ToString(), 
                       x => x.InboxName, 
                       Model.Inbox.InboxId.ToString(),
                       "[ Select One ]")) %>
    </div>

EXTENSION METHOD

public static SelectList ToSelectList<T>(this IEnumerable<T> list,
                                         Func<T, string> value,
                                         Func<T, string> text,
                                         string firstValue,
                                         string firstText)
{
    var firstSelectListItem = new { Value = firstValue, Text = firstText };

    var collection = (new[] { firstSelectListItem })
        .Concat(list.Select(x => new { Value = value(x), Text = text(x) }));

    return new SelectList(collection, "Value", "Text");
}
RSolberg
I am this far. I guess I was somewhat vague on my question. See my changes above...