Asp.net mvc 3 在加载mvc3之前解析页面上的所有html帮助程序扩展

Asp.net mvc 3 在加载mvc3之前解析页面上的所有html帮助程序扩展,asp.net-mvc-3,validation,extension-methods,Asp.net Mvc 3,Validation,Extension Methods,我已经编写了一些扩展方法来扩展用于客户端表单验证的html助手类。我希望能够在页面中加载我所有元素的数组(javascript),这些元素是我的验证“库”的一部分 例如: @Html.VTextBox("blah) @Html.VDropDownList("bling") @Html.VTextBox("bloo") 加载页面时,我希望在顶部放置一个javascript数组,其中填充如下内容: errorListArr = new Array("blah","bling","bloo");

我已经编写了一些扩展方法来扩展用于客户端表单验证的html助手类。我希望能够在页面中加载我所有元素的数组(javascript),这些元素是我的验证“库”的一部分

例如:

@Html.VTextBox("blah)
@Html.VDropDownList("bling")
@Html.VTextBox("bloo")
加载页面时,我希望在顶部放置一个javascript数组,其中填充如下内容:

errorListArr = new Array("blah","bling","bloo");
目前我正在做的是对每个元素使用errorListArr.push(),每次都写出脚本标记。。。显然这不是最优雅的方式。我还想弄清楚如何提前解析整个页面,以便将验证服务器端所需的元素列表放在一起


请告诉我是否可以这样做,任何代码片段/示例都将不胜感激。

我不完全清楚您想做什么,但我认为我理解得足够多,可以为您指出正确的方向

首先,MVC 3中的服务器端验证通常是作为对获取模型并对其进行验证的操作的回发来完成的。如果模型无效,则返回带有(现在已验证)模型的视图,该视图将针对错误的属性呈现相应的错误消息

默认情况下,可以通过将某些属性添加到要渲染输入的模型的属性来定义要执行的验证

更重要的是,MVC足够聪明,可以在用户试图提交表单时输出客户端javascript来执行许多验证,而实际上根本不需要发帖

有关如何使用模型验证的演练,请参见

在MVC 3中,您还可以选择启用,这与通常的客户端验证基本相同,但它不生成一堆内联javascript,而是用某些“数据”属性标记输入元素。然后,几个基于jquery的库扫描页面以查找具有这些标志的元素,并向它们添加适当的验证处理程序

如果您的验证需求超出了MVC提供的现成功能,那么可以很容易地添加您自己的验证属性,甚至可以让您的模型执行自定义逻辑来验证自己

一般来说,如果您发现在客户端呈现大量小javascript片段,您可能希望自己遵循“不引人注目的javascript”模式:

  • 将代码放在静态javascript文件中,该文件知道如何扫描DOM以查找它感兴趣的特定标志
  • 使用添加的这些标志呈现HTML元素,在必要时使用“data-”属性添加细节
  • 您的“验证库”可能不包含这么多扩展方法。因此,将处理后的元素的名称添加到数组中时,在每个元素中放置相同的代码行并不是很不雅观

    另一种方法实际上是通过“验证库”人为地使所有被验证的元素共享一些东西:一个公共标记接口。其思想是:不要将元素用作其真实类型的实例。改为创建这些类型的子类型,这些子类型也实现了接口
    IValidated
    ,只有一个
    string ID
    成员(我在这里假设,由于它们是原始类的实例,您感兴趣的所有元素都已经有了这样的属性)。 然后,在完成所有需要的操作之后,在将页面发送到客户端之前,只需构建一次数组作为结束操作。由于
    IValidated
    ,您的所有自定义验证元素都可以识别,使用这样的一行代码非常简单:

    errorListArr = new Array(this.Page.SubControls().OfType<IValidated>().Select(elt => elt.ID));
    
    当然,你可能需要做一些调整来满足你的确切需求,但这是最基本的想法


    第二个选项的主要优点是为所有元素提供“公共的东西”,尽管它们都是各种类的实例,否则它们的共同点可能很少。您创建了一个新的功能抽象,它是特定于您的项目的,以后如果需要,您可以使用特定的扩展方法来扩展
    IValidated
    ,例如…

    一些问题:1:您是否考虑过使用“不引人注目的javascript”技术来避免需要这些脚本片段?2:为什么数组需要放在页面的顶部(相对于底部)?3:为什么需要要验证(服务器端)的元素(客户端)列表。不知道你在这里是什么意思。数组可能在底部,那就好了。从本质上说,我试图使这段代码尽可能可重用,而不必为服务器端编写更多的代码。看一下上面的例子,我只需输入一个@Html.VTextBox,客户端和服务器端应该知道它需要验证。VTextBox元素接受一个“type”参数,如email的“e”或phone的“p”。我要做的是传递一个隐藏的表单var,其中包含需要验证服务器端的所有元素。我就是不能把我的听力也总结成创建列表4 arr。
    public static IEnumerable<Control> Subcontrols<T>(this T parentControl) where T : Control
    {
        //Recursively returns all the parentContol's descendant controls 
        foreach (Control ctrl in parentControl.Controls)
        {
            yield return ctrl;
            foreach (Control childCtrl in ctrl.Subcontrols())
            {
                yield return childCtrl;
            }
        }
    }