3

I'm in a pickle here....

I'm trying to create a new, pretty much standard ASP.NET Webforms app targetting .NET 4.5.2. I've done it many times before - but never ran into these problems (and can't quite figure out WHY they happen now and never before....).

My customer supplied a set of CSS and Javascript as basis for the project, and this includes Bootstrap and jQuery amongst other things.

Now when I'm trying to get my first simple pages to work, I'm running into serious trouble with including some additional Javascript into my page.

Attempt #1

I was trying to have my Javascript files included like this:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="Web.MyMaster" %>
<!DOCTYPE html>
<html lang="en" class="no-js no-ie">
<head runat="server">
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=$start">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <webopt:BundleReference runat="server" Path="~/Content/css" />

    <!-- Favicons -->
    <link rel="shortcut icon" href="~/Images/Icons/favicon.ico" />

    <!-- Scripts -->
    <script type="text/javascript" src="/Scripts/vendors.min.js"></script>
    <script type="text/javascript" src="/Scripts/jquery.validate.min.js"></script>

    <asp:ContentPlaceHolder ID="HeaderContent" runat="server"></asp:ContentPlaceHolder>
</head>

That seemed to work - until I deployed to our test environment for the first time. There, the apps are not "rooted", e.g. they're installed in a IIS setup where the path to the app is http://test.server.com/apps/MyApp - and now my references to /Scripts/.... all break and nothing is found

Attempt #2

I tried changing the include of the scripts to use the ResolveUrl() method I had used before:

<!-- Scripts -->
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/vendors.min.js") %>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery.validate.min.js") %>"></script>

so in this case, ASP.NET should resolve those names based on the app's root directory (no matter where that is) and include those scripts.

Trouble: now I'm getting an error (upon startup) saying something like (freely translated from German):

The control collection cannot be modified since the control contains code blocks (e.g. <% ... %>)

I beg your pardon?!?!?!?!?!

Attempt #3

So my last resort was to use data binding expressions like this:

<!-- Scripts -->
<script type="text/javascript" src="<%# ResolveUrl("~/Scripts/vendors.min.js") %>"></script>
<script type="text/javascript" src="<%# ResolveUrl("~/Scripts/jquery.validate.min.js") %>"></script>

and this requires that I do a

Page.Header.DataBind();

in the OnInit event handler of the master page, and once I do that, when I try to use the DevExpress Grids, I get a nasty error:

Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.

OK, so I'm at the end of my wisdom - HOW on earth can I include a few Javascript files into an ASP.NET Webforms app today, in 2016, so that everything just works - no nasty .NET errors, no Javascript not found....... what's your approach to fix this dilemma of mine??

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

2

WebForms is special when it comes to script tags. One thing you can do is use a ScriptManager as described on this answer

Also, attempt #2 would work if you removed runat="server" from your <head> tag. If you're not accessing the head tag from codebehind, there's no need for it to be a server control.

Or, for a more "modern" approach, the ASP.NET Bundling and Minification stuff works in WebForms too. I've used it in a few projects without any issues.

Community
  • 1
  • 1
jrummell
  • 42,637
  • 17
  • 112
  • 171
  • If I remove the `runat="server"` from the ``, I can no longer set the `Page.Title` property..... – marc_s Jun 28 '16 at 13:27
  • As for the bundling & minification: *sounds* like a great idea, but I had tons of issues - tried to combine various `*.js` files into a bundle, but when trying to add that bundle (with its "logical" name) to the Script Manager, I kept getting errors about "this needs to have a .js extension" and stuff like that..... never worked for me (yet) – marc_s Jun 28 '16 at 13:32
  • You should be able to use `<%= Scripts.Render("~/bundle/path") %>`, but then you might have the same issue as Attempt 2 with a server head tag ... – jrummell Jun 28 '16 at 13:40