0

I'm learning C#/MVC 4 by refactoring an old PHP program into ASP format. The program's purpose is to create calendar entries for client appointments, including some basic client info. My most recent challenge was to load static data into multiple @Html.DropDownLists on the page. I was able to accomplish this after hacking through this (How to add static list of items in MVC Html.DropDownList()) and that (How can I get this ASP.NET MVC SelectList to work?) , but I feel like I'm reinventing the wheel...

PORTION OF MODEL: (CommonDataModel.cs)

public class apptCounties{
  public IEnumerable<SelectItemList> Counties {get; set;}
  public apptCounties()
  {
    Counties = new[]
      {
        new SelectListItem{Text="Cook",Value="Cook"},
        new SelectListItem{Text="Dupage",Value="Dupage"},
        new SelectListItem{Text="Lake",Value="Lake"}
      };
  }
}

VIEWMODEL: (ScheduleDataViewModel.cs)

public class ScheduleDataViewModel {
  public apptClient ClientData {get; set;} 
    /* ^--This is from another model specific to this app - I'm attempting to use   
          "CommonDataModel.cs" to hold multiple lists of static data (Counties, Races, 
           Genders, etc) & then append app-specific data through specialized models. 
           I plan on expanding functionality later. */
  public apptCounties Counties {get; set;}
  public ScheduleDataViewModel()
  {
    ClientData = new apptClient(); 
    Counties = new apptCounties();
  }
}

CONTROLLER: (ScheduleController.cs)

public ActionResult Schedule()
{
  var model = new ScheduleDataViewModel();
  return View(model);
}

PORTION OF VIEW: (Index.cshtml - strongly typed to ScheduleDataViewModel)

@Html.DropDownList("Counties", Model.Counties)

Sorry for any mucky syntax there - my code isn't in front of me! I can verify that at least the general idea above is working when built & tested.

I worry that I'm overcomplicating what ought to be a much simpler procedure. Am I actually on the right track with all the constructor methods here, or can someone suggest a more elegant solution to serving static data lists without the benefit of a database?

Community
  • 1
  • 1
Alex
  • 1,434
  • 10
  • 17
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders May 10 '13 at 16:18

2 Answers2

3

If your lists are static and relatively independent of your actual model, you might find it simpler just to define these in a separate, static class:

public static class ListOptions
{
    public static readonly List<string> Counties = ...
}

Then create the SelectList in your view:

@Html.DropDownListFor(m => m.County, new SelectList(ListOptions.Counties))

There is nothing inherently wrong with doing this if it is appropriate. If your list is only relevant to that specific model, then yes, it belongs inside the view model; however, even then, if the values are not variable, I wouldn't worry about simply making it a static property.

I certainly disagree with the notion that creating the SelectList itself in the view is necessarily a bad thing; after all, the model and controller don't need to know that the value came from a SelectList - only what was selected. The way in which the option is presented is the concern of the view.

Ant P
  • 24,820
  • 5
  • 68
  • 105
  • A small nitpick: you can't declare a `List<>` as a compile-time `const`; you'll need to use `static readonly` instead. – LukeH May 10 '13 at 16:49
  • @LukeH that's what I get for writing code on a phone :-P - updated. – Ant P May 10 '13 at 16:52
  • That's certainly more appealing than having to call constructors all the time. Would it be out of line to transform my current "CommonDataModel" into a single static class full of `static readonly` lists? (thanks, @LukeH!) – Alex May 10 '13 at 16:54
  • This is PERFECT - converted CommonDataModel over to `static readonly` lists, assign any needed lists inside each ViewModel, use `@Html.DropDownListFor`. These unnecessary constructors are no more! Answer selected - thanks so much! – Alex May 10 '13 at 21:40
  • @JodahS No problem - just avoid overusing it! Effectively it comes down to who owns the list. If the list belongs to your application, hold it in a static class. If it belongs to your class, hold it in a static property. If it is variable, make it a normal model property. – Ant P May 11 '13 at 07:09
0

It looks okay. Maybe some syntactical improvements.

Action

public ActionResult Schedule()
{
    return View(new ScheduleDataViewModel());
}

ViewModel

// You want class names to be Upper-case
public class ScheduleDataViewModel 
{
    public ApptClient ClientData { get; set; } 
    public ApptCounties Counties { get; set; }

    public ScheduleDataViewModel()
    {
        ClientData = new ApptClient(); 
        Counties = new ApptCounties();
    }
}
Sam Leach
  • 12,746
  • 9
  • 45
  • 73
  • Polite follow-up: I updated the viewmodel per your recommendation, but found that I get a null reference error without the ScheduleDataViewModel() constructor. May be a result of slightly different code on my end. Again - thank you for your help! – Alex May 10 '13 at 19:00