简体   繁体   English

asp.net 4.5 Web窗体不引人注意的验证jQuery问题

[英]asp.net 4.5 Web Forms Unobtrusive Validation jQuery Issue

I've been checking out some of the new features for Web Forms in 4.5, and I have run into a road block with unobtrusive validation. 我一直在查看4.5中Web Forms的一些新功能,而且我遇到了一个不显眼的验证路障。

Unobtrusive validation in Web Forms 4.5 is dependent on jQuery, and when it is enabled will result in a jQuery script reference inside of the server form in the page body. Web Forms 4.5中的不显眼验证依赖于jQuery,当它启用时,将在页面主体中的服务器表单内部生成jQuery脚本引用。 This sounds great, and I love the concept. 这听起来很棒,我喜欢这个概念。 It works great in the demos I have looked at, and the reduction/cleanup in code is a beautiful thing. 它在我看过的演示中效果很好,代码中的减少/清理是一件很美妙的事情。

I run into issues, however, when I enable this in pre-exisiting projects. 然而,当我在预先存在的项目中启用它时,我遇到了问题。 The problem is that I have countless pages and applications that utilize jQuery for client side interactions (jQuery UI being a typical example), and in these pages I have a jQuery reference and accompanying code in the header section of the page. 问题是我有无数的页面和应用程序利用jQuery进行客户端交互(jQuery UI是一个典型的例子),在这些页面中我有一个jQuery引用和附带的代码在页面的标题部分。 When unobtrusive validation is enabled, the result is a second jQuery reference on the page, and the javascript in the header breaks. 当启用不显眼的验证时,结果是页面上的第二个jQuery引用,并且标题中的javascript中断。

Is there a way for the me to tell the script manager that jQuery has already been loaded in the page so that a second reference does not get added? 有没有办法让我告诉脚本管理器jQuery已经加载到页面中,以便第二个引用不会被添加? Alternatively, is there a way for me to tell the script manager or the Web Forms framework to check the page for an existing jQuery reference? 或者,有没有办法告诉脚本管理器或Web窗体框架检查页面是否存在现有的jQuery引用?

Unfortunately the ScriptResourceMapping is required. 不幸的是ScriptResourceMapping是必需的。 However, with a bit of work you can remove the reference from the ScriptManager so it won't render jQuery again. 但是,通过一些工作,您可以从ScriptManager中删除引用,这样它就不会再次呈现jQuery。

Create your own class that derives from ScriptManager in your web project: 创建自己的类,该类派生自Web项目中的ScriptManager:

using System;
using System.Linq;
using System.Web.UI;

namespace WebApplication46
{
    public class CustomScriptManager : ScriptManager
    {
        protected override void OnInit(EventArgs e)
        {
            Page.PreRenderComplete += Page_PreRenderComplete;
            base.OnInit(e);
        }

        private void Page_PreRenderComplete(object sender, EventArgs e)
        {
            var jqueryReferences = Scripts.Where(s => s.Name.Equals("jquery", StringComparison.OrdinalIgnoreCase)).ToList();
            if (jqueryReferences.Count > 0)
            {
                // Remove the jquery references as we're rendering it manually in the master page <head>
                foreach (var reference in jqueryReferences)
                {
                    Scripts.Remove(reference);
                }
            }
        }
    }
}

Next, configure a tagMapping entry in your web.config so that ASP.NET will use your custom ScriptManager instead of the one in the box: 接下来,在web.config中配置tagMapping条目,以便ASP.NET将使用您自定义的ScriptManager而不是框中的那个:

<system.web>
  <pages>
    <tagMapping>
      <add tagType="System.Web.UI.ScriptManager" mappedTagType="WebApplication46.CustomScriptManager" />
    </tagMapping>
  </pages>
</system.web>

That's it. 而已。 Now your CustomScriptManager will ensure all jQuery references are removed from itself before the ScriptManager has a chance to start its rendering logic and you'll still satisfy all the requirements for UnobtrusiveValidation to work (assuming you have a reference to jQuery in your page's tag). 现在,您的CustomScriptManager将确保在ScriptManager有机会启动其渲染逻辑之前从其自身中删除所有jQuery引用,并且您仍将满足UnobtrusiveValidation的所有要求(假设您在页面的标记中引用了jQuery)。

As Damian Edwards said , you can't seem to remove the reference so the solution I went with was to create a fake jQuery reference that points to an empty JS file. 正如Damian Edwards所说 ,你似乎无法删除引用,因此我使用的解决方案是创建一个虚假的jQuery引用,指向一个空的JS文件。 That'll still create the unavoidable extra script tag in an attempt to load jQuery but it wont be an actual jQuery library so there won't be a conflict with the jQuery reference in your head tag. 这仍然会在尝试加载jQuery时创建不可避免的额外脚本标记,但它不会是一个真正的jQuery库,因此不会与head标记中的jQuery引用冲突。

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        ScriptManager.ScriptResourceMapping.AddDefinition("jquery", new ScriptResourceDefinition
        {
            Path = "~/Scripts/empty-file.js"
        });
    }
}

是的,您可以使用scriptmanager注册脚本引用(name = jquery),这将告诉不显眼的验证系统jquery已注册,并且由于您自己呈现脚本,它将全部工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM