James Wilson
James Wilson

Reputation: 5150

A better way than using ViewBag

I obtain a list of data through docs which has a list of every single department and function the currently logged in user has access to. I need to populate a distinct list of Departments for a DropDownList and a distinct list of Functions for a DropDownList on the View page. I am currently not even using docs to do this but a different LINQ query to acheive this. Is there a way I can use the current model I am passing?

var docs = (Long LINQ query that joins in four different tables and returns a model)

ViewBag.DepartmentList = db.Department.Where(x => (x.name != null)).Select(s => new SelectListItem
            {
                Value = s.name,
                Text = s.name
            })
            .Distinct();  //  Fill the viewbag with a unique list of 'Department's from the table.

ViewBag.FunctionList = db.Function.Where(x => (x.name != null)).Select(s => new SelectListItem
            {
                Value = s.name,
                Text = s.name
            })
            .Distinct();  //  Fill the viewbag with a unique list of 'Function's from the table.

Code on View: (Strongly Typed Model)

@model IEnumerable<DB.Models.MasterList>

@Html.DropDownList("DepartmentList", "Select a Department")
@Html.DropDownList("FunctionList", "Select a Function")

Upvotes: 0

Views: 529

Answers (3)

emre nevayeshirazi
emre nevayeshirazi

Reputation: 19241

Define a model that will be used in your view.

public class MyViewModel
{
    public string SelectedDepartment { get; set; }
    public string SelectedFunction   { get; set; }


    public IEnumerable<SelectListItem> Departments  { get; set; }
    public IEnumerable<SelectListItem> Functions    { get; set; }

    // Your old model
    public IEnumerable<MasterList> Master           { get; set;}

}

In your controller, populate these collections and return your model to view.

[HttpGet]
public ActionResult ActionMethodName()
{
    var model = new MyViewModel();

    model.Departments = db.Departments.Where(x => (x.name != null))
                          .Select(s => new SelectListItem
                          {
                              Value = s.name,
                              Text = s.name
                          })
                          .Distinct(); 

    model.Functions = db.Functions.Where(x => (x.name != null))
                          .Select(s => new SelectListItem
                          {
                              Value = s.name,
                              Text = s.name
                          })
                          .Distinct(); 

    return View(model);
}

Inside your view, use strongly typed html helpers.

@model MyViewModel

@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments)
@Html.DropDownListFor(m => m.SelectedFunction, Model.Functions)

When you post back your form to server, SelectedDepartment and SelectedFunction should have the values selected in your view.

Upvotes: 3

Kenneth
Kenneth

Reputation: 28737

You could create a ViewModel and put all this data in this ViewModel:

ViewModel

public class MyViewModel{
    public object DepartmentList{get; set;}
    public object FunctionList{get; set;}
    public IEnumerable<MasterList> Master {get; set;}
}

Controller

var docs = (Long LINQ query that joins in four different tables and returns a model)
MyViewModel vm = new MyViewModel();
vm.Master = docs; // I guess docs is a list of Masterlist
vm.DepartmentList = db.Department.Where(x => (x.name != null)).Select(s => new SelectListItem
            {
                Value = s.name,
                Text = s.name
            })
            .Distinct();  //  Fill the viewbag with a unique list of 'Department's from the table.

vm.FunctionList = db.Function.Where(x => (x.name != null)).Select(s => new SelectListItem
            {
                Value = s.name,
                Text = s.name
            })
            .Distinct();  //  Fill the viewbag with a unique list of 'Function's from the table.
return View(vm);

View

@model MyViewModel

@Html.DropDownList("DepartmentList", "Select a Department")
@Html.DropDownList("FunctionList", "Select a Function")

Upvotes: 1

Adam Tal
Adam Tal

Reputation: 5961

You can always create a ViewModel class for your view and put all the necessary view information in it.

You can use a framework like AutoMapper (https://github.com/AutoMapper/AutoMapper) to help you with the mapping between your database model and your view model (I belive it's best that the view won't know the database model at all), and beside the model information you can also add those lists (That's what I do, I have a property for the entity, and properties for those kinds of lists).

If you need this information in many of your views you can always create a BaseViewModel and polpulate that information in a BaseController.

Upvotes: 0

Related Questions