Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 1.0 - Model binder for Dictionaries

I have a ViewModel class containing a Dictionary (and other irrelevant things for this question):

public class MyViewModel {
    public Dictionary<int, string> Data { get; set; }
    /* ... */
}

Then I have a couple of GET/POST actions that deal with the dictionary. The GET action will first fill the Dictionary<int, string> with some data from the database, and then return a View:

  • the .Keys will be on hidden fields; and
  • the .Values will be on a textareas for the user to edit.

The user will then submit this form, calling the POST action. It will try to process the input (the process is irrelevant). Some of the Key/Value pairs will be valid, some will be invalid.

If there are invalid pairs, the POST action will then reconstruct a ViewModel, but this time the dictionary should contain only the invalid pairs, and will redisplay the same View for the user to fix and try submitting again.

Question: what is the easiest & cleanest way to achieve this?

What I have so far (working fine), in the controller:

public ActionResult MyAction(MyViewModel vm) {
    /* Process data */
    if (are there invalid pairs?) {
        var vmErrors = new MyViewModel();
        /* ... fill the ViewModel ... */
        vmErrors.Data = 
            vm.Data
                .Where(x => IsInvalid(x))
                .ToDictionary(x => x.Key, x => x.Value);
        return View(vmErrors);
    }
}

And the view:

<% var i = 0; foreach (var p in Model.Data) { %>
    <%= Html.Hidden("vm.Data[" + i + "].key", vm.Key %>
    <%= Html.TextArea("vm.Data[" + i + "].value", vm.Value %>
<% i++; } %>

The problem is that to please the model binder I must name my fields on the view with sequential ids. But I must also iterate over the Dictionary to extract the key/value pairs, so it cannot be a for (var i = 0; i < Model.Data.Count; i++) {...} loop.

like image 852
Bruno Reis Avatar asked Nov 15 '22 13:11

Bruno Reis


1 Answers

The solution is described in this article - Dictionary Model Binder in ASP.NET MVC2 and MVC3

The code is general-purpose and could be used with MVC 1 too.

like image 71
Alexander Prokofyev Avatar answered Jan 06 '23 13:01

Alexander Prokofyev