ASP.Net MVC 2 - 为字典和LT更好ModelBinding; INT,INT> [英] ASP.Net MVC 2 - better ModelBinding for Dictionary<int, int>

查看:206
本文介绍了ASP.Net MVC 2 - 为字典和LT更好ModelBinding; INT,INT>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些特殊情况下,你需要的文本框列表 - 其ID运行之前是不知道(处理N N关联)。
事情是这样的: http://screencast.com/t/YjIxNjUyNmU

In some special cases you will need a list of textboxes (to deal with n - n associations) whose id is not know before runtime. Something like this : http://screencast.com/t/YjIxNjUyNmU

在该特定示例中,我在找一个计数我的一些'模板'联系起来。

In that particular sample I'm looking to associate a count to some of my 'templates'.

ASP.Net MVC 1 I codeD字典ModelBinder的有一个干净的,直观的HTML。
它允许这样的事情:

in ASP.Net MVC 1 I coded a Dictionary ModelBinder to have a clean and intuitive HTML. It allowed things like this :

// loop on the templates
foreach(ITemplate template in templates)
{
        // get the value as text
        int val;
        content.TryGetValue(template.Id, out val);
        var value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name (for dictionary binding)
        string id = "cbts_{0}".FormatMe(template.Id);
%>
        <input type="text" id="<%= id %>" name="<%= id %>" value="<%= value %>" />
        <label for="<%= id %>"><%= template.Name %></label>
        <br />

下面是粘合剂的code:

Here is the code of the binder :

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;
}

当传递到 ASP.Net MVC 2 ,问题是在 ValueProvider 不是一本字典了。有没有办法通过值循环来分析他们,我做的方式。

When passing to ASP.Net MVC 2, the problem is the ValueProvider is not a dictionary anymore. There is no way to loop through the values to parse them the way I did.

和我没有找到任何其他方式这样做(如果您知道的,告诉我)。

And I did not find any other way to do so (If you know one, tell me).

我终于切换到绑定的字典中的标准的方式,但是HTML是丑陋的,违反直觉的(使用计数器遍历非索引集合??),并要求所有的属性值,而我需要的行为(这在ASP.Net MVC 1完美工作)。

I finally switched to the 'standard' way of binding the dictionary, but the HTML is ugly, counterintuitive (using counters to loop over a non-indexed collection ??) and all the values are required, unlike the behavior I need (and that worked perfectly in ASP.Net MVC 1).

它看起来是这样的:

int counter= 0;
// loop on the templates
foreach(ITemplate template in templates)
{
        // get the value as text
        int val;
        content.TryGetValue(template.Id, out val);
        var value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name (for dictionary binding)
        string id = "cbts_{0}".FormatMe(template.Id);
        string dictKey = "cbts[{0}].Key".FormatMe(counter);
        string dictValue = "cbts[{0}].Value".FormatMe(counter++);
%>
        <input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" />
        <input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" />
        <label for="<%= id %>"><%= template.Name %></label>
        <br />

在控制器我需要欺骗的ModelState 来避免'的值是必需的'错误:

In the controller I need to trick the ModelState to avoid 'a value is required' errors :

public ActionResult Save(int? id, Dictionary<int, int> cbts)
{
    // clear all errors from the modelstate
    foreach(var value in this.ModelState.Values)
        value.Errors.Clear();

这是太棘手。
我很快就需要使用这种结合了很多次,也许有一定的层次的开发工作,对应用程序。

This is too tricky. I will soon need to use this kind of binding many times, and maybe have some tiers developer work on the application.

问:


  • 你知道一种方法,使其更好?

我需要什么,国际海事组织,是字典中的ModelBinder的,允许一个更好的HTML并没有任何考虑所需的所有值。

What I need, IMO, is a ModelBinder for dictionary that allow a better html and that does no consider that all values are required.

推荐答案

您绝对可以继续使用你的MVC 1型粘结剂MVC 2,你必须做出的最大的变化就是你的模型粘结剂不该 ŧ违背IValueProvider而是应该直接去反对的Request.Form。您可以通过该集合枚举,并执行任何逻辑是必要的,您的场景。

You are absolutely free to continue using your MVC 1 model binder in MVC 2. The biggest change that you'll have to make is that your model binder shouldn't go against the IValueProvider but should instead go directly against Request.Form. You can enumerate over that collection and perform whatever logic is necessary for your particular scenario.

IValueProvider接口的目的是提供在其中数据来自和是为一个通用的粘合剂(如DefaultModelBinder)的抽象。作为数据不保证是枚举的IValueProvider本身不能IEnumerable的。但在特定情况下,如果你有一个特定的场景中的特定粘合剂和已经知道的数据是从表单来的,抽象是不必要的。

The purpose of the IValueProvider interface is to provide an abstraction over where the data comes from and is meant for a general-purpose binder (like the DefaultModelBinder). As the data isn't guaranteed to be enumerable, the IValueProvider itself cannot be IEnumerable. But in your particular case, where you have a specific binder for a specific scenario and already know the data is coming from the form, the abstraction is unnecessary.

这篇关于ASP.Net MVC 2 - 为字典和LT更好ModelBinding; INT,INT&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆