5

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.

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. 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. When unobtrusive validation is enabled, the result is a second jQuery reference on the page, and the javascript in the header breaks.

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? 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?

John
  • 772
  • 7
  • 17

3 Answers3

9

Unfortunately the ScriptResourceMapping is required. However, with a bit of work you can remove the reference from the ScriptManager so it won't render jQuery again.

Create your own class that derives from ScriptManager in your web project:

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:

<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).

Damian Edwards
  • 7,289
  • 1
  • 25
  • 19
  • Thanks for your suggestion, I completely missed it when you posted it. Just taking another look at some of the 4.5 features. I tried your suggestion, tested in Firefox, Chrome and IE and each result is the same - the header scripts break because of the 2nd jquery reference. Looks like I won't be able to use unobtrusive validation without major revisions to my webforms apps. I'd love to find a way to override this behavior. Is this possible in an update to webforms? Or would we need to wait for the next version of asp.net? – John Dec 30 '12 at 17:37
  • I just want to clarify because my comment above is misleading. Damian, your solution works perfectly (my previous comment was from an earlier approach that you posted). I've been using it in an application and it solved my problem. I'd still love to see a built in solution for this in a future version of WebForms, but in lieu of that, your workaround is much appreciated. – John Feb 22 '13 at 15:46
8

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. 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.

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"
        });
    }
}
Community
  • 1
  • 1
Michael Khalili
  • 933
  • 12
  • 13
0

Yes you can register a script reference(name=jquery) with scriptmanager which will inturn tell the unobtrusive validation system that jquery is registered and since you are rendering the scripts yourself it will all work

pranav rastogi
  • 4,124
  • 23
  • 23
  • And how would you add such a reference? When I add it in markup, I still get the error. If I add one in global.asax, I have to specify a path... – Lodewijk Sep 13 '12 at 18:39