Pergunta

Estou tentando migrar para o ASP.NET MVC 2 e encontrar alguns problemas. Aqui está um: eu precisava ligar diretamente um Dicionário como resultado de um post de visualização.

No ASP.NET MVC 1, funcionou perfeitamente usando um personalizado 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
}

Funcionou em par com algum htmlbuilder inteligente que exibia dicionário de dados.

O problema que encontro agora é que ValueProvider não é mais um dicionário <>

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

Isso realmente não é legal, pois não posso realizar minha análise inteligente ...

Pergunta :

  1. Existe outra maneira de obter todas as chaves?
  2. Você conhece outra maneira de vincular uma coleção de elementos html a um dicionário

Obrigado por suas sugestões

O.

Foi útil?

Solução

Acho que você não poderá mais fazê -lo dessa maneira no MVC 2.
Como alternativa, você pode estender o DefaultModelBinder e substituir um de seus métodos virtuais como getModelProperties e alterar o nome do modelo dentro do ModelBindingContext. Outra opção seria implementar um metadataprovider personalizado para o seu tipo de dicionário, você também pode alterar o nome do modelo.

Outras dicas

Embora essa pergunta tenha sido marcada 'respondida', acho que o seguinte pode ser útil. Eu tive o mesmo problema e dei uma olhada no código -fonte do sistema.web.mvc.defaultValueProvider. Ele obtém seus valores do roteiro, a sequência de consulta ou a partir de um envio de formulário de solicitação (nessa ordem exata). Para coletar todas as chaves (que é o que você faz em sua primeira pergunta), escrevi o seguinte método auxiliar.

private static IEnumerable<string> GetKeys(ControllerContext context)
{
    List<string> keys = new List<string>();
    HttpRequestBase request = context.HttpContext.Request;
    keys.AddRange(((IDictionary<string,
        object>)context.RouteData.Values).Keys.Cast<string>());
    keys.AddRange(request.QueryString.Keys.Cast<string>());
    keys.AddRange(request.Form.Keys.Cast<string>());
    return keys;
}

Você pode usar este método para enumerar sobre as chaves:

foreach (string key in GetKeys(controllerContext))
{
    // Do something with the key value.
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top