views:

672

answers:

1

Hi,

I'm trying to migrate to ASP.Net MVC 2 and meet some issues. Here is one : I needed to bind directly a Dictionary as result of a view post.

In ASP.Net MVC 1 it worked perfectly using a custom IModelBinder :

/// <summary>
/// Bind Dictionary<int, int>
/// 
/// convention : <elm name="modelName_key" value="value"></elm>
/// </summary>
public class DictionaryModelBinder : IModelBinder
{
    #region IModelBinder Members

    /// <summary>
    /// Mandatory
    /// </summary>
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        IDictionary<int, int> retour = new Dictionary<int, int>();

        // get the values
        var values = bindingContext.ValueProvider;
        // get the model name
        string modelname = bindingContext.ModelName + '_';
        int skip = modelname.Length;

        // loop on the keys
        foreach(string keyStr in values.Keys)
        {
            // if an element has been identified
            if(keyStr.StartsWith(modelname))
            {
                // get that key
                int key;
                if(Int32.TryParse(keyStr.Substring(skip), out key))
                {
                    int value;
                    if(Int32.TryParse(values[keyStr].AttemptedValue, out value))
                        retour.Add(key, value);
                }
            }
        }
        return retour;
    }

    #endregion
}

It worked in pair with some smart HtmlBuilder that displayed dictionary of data.

The problem I meet now is that ValueProvider is not a Dictionary<> anymore, it's a IValueProvider that only allow to get values whose name is known

public interface IValueProvider
{
    bool ContainsPrefix(string prefix);
    ValueProviderResult GetValue(string key);
}

This is really not cool as I cannot perform my smart parsing...

Question :

  1. Is there another way to get all keys ?
  2. Do you know another way to bind a collection of HTML elements to a Dictionary

Thanks for your suggestions

O.

A: 

I don't think you'll be able to do it this way anymore in MVC 2.
Alternatively, you could extend DefaultModelBinder and override one of its virtual methods like GetModelProperties and then change the ModelName inside the ModelBindingContext. Another option would be to implement a custom MetadataProvider for your Dictionary type, you can change the model name there as well.

Felipe Lima