Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a view in MVC to render a Dictionary within a Model and to map the dictionary back into the Model

Let's say you have this Model:

//model 
public class Stuff
{
  public string Name { get; set; }
  public Dictionary<String, String> Description { get; set; }
}

I want to be able to be able to create an action and it's corresponding view so users can add in the form the Name of the Stuff object, and can add multiple Description entries.

In this particular case, I want the key to be a language code like 'en', 'de', 'fr', 'es', etc. and the description the corresponding description for the given language.

For example, in the View you might see something like this:

@model Stuff

@using(Html.BeginForm())
{
   <div>
       @Html.LabelFor(x=>x.Name)
       @Html.TextBoxFor(x=>x.Name)
   </div>
   <div>
        <!-- What goes in here to map to the Dictionary in the Stuff Model? -->
        <input name="LanguageCode" value="en" />  <input name="DescriptionValue" />
        <input name="LanguageCode" value="de" />  <input name="DescriptionValue" />
        <input name="LanguageCode" value="fr" />  <input name="DescriptionValue" />
   </div>
   <div>
        <input type="submit" value="save" />
   </div>
}


// controller

[HttpGet]
public ActionResult Index ()
{
  return View(new Stuff());
}

[HttpPost]
public ActionResult Index (Stuff myStuff)
{
  foreach(KeyValuePair kvp in myStuff.Description)
  {
       Trace.WriteLine(String.Format("Language: {0} - Description: {1}", kvp.Key, kvp.Value)); 
  }
  DBHelper.Save(myStuff);
  return View();
}

Any alternative solutions are accepted.

Thanks.

like image 276
agarcian Avatar asked Oct 22 '11 21:10

agarcian


2 Answers

It will be something like this:

@int i = 0;
@foreach (var item in Model.Description) {
    <input name="Description[@i].Key" value="@item.Key" />  
    <input name="Description[@i].Value" value="@item.Value" />  
    @i++
}

See this post by Scott Hanselman

like image 183
Paul Creasey Avatar answered Oct 13 '22 18:10

Paul Creasey


You can create a Editor template (and the Display template) for your Dictionary type. Then, MVC will be able to render dictionary instances in your models.

For example, in your model you can specify the template to use as follow:

public class Stuff
{
  public string Name { get; set; }

  [UIHint("Stringdictionary")]
  public Dictionary<String, String> Description { get; set; }
}

in your View, you have to do just this:

@model Stuff

@using(Html.BeginForm())
{
   <div>
       @Html.LabelFor(x=>x.Name)
       @Html.TextBoxFor(x=>x.Name)
   </div>
   <div>
       @Html.Editor(x=>x.Description )
   </div>
   <div>
        <input type="submit" value="save" />
   </div>
}

And, the editor template (you have to create it in Views/Shared/EditorTemplates folder) could be something like this:

@model Dictionary<string,string>
@foreach (var item in Model) {
    @Html.EditorFor(x=>x.Key)
    @Html.EditorFor(x=>x.Value)
}
like image 20
lontivero Avatar answered Oct 13 '22 20:10

lontivero