Why is that the scriptPath
variable is out of scope in the bottom of the code?
Shouldn't it be in scope throughout this page? In MVC, if I mark this on top of the page like
@{
string scriptPath = "assets/scripts/",
gkoConfig = "GkoConfig.js";
}
it is available throughout the current View. What am I missing now that I'm back to WebForms for a while?
If I change the code position, It get's weirder as inside the <head>
I no longer have access to teh variable, but I do have, inside the <body>
now... :-/
When you declare a variable in a Web Forms .aspx file, you’re actually declaring a local variable inside an auto-generated rendering method. ASP.NET generates separate rendering methods for all tags marked runat="server"
, so you actually get a separate method for your head element. Now, the variable you declare can only exist in one of these methods - hence the 'weird' behavior.
You can see how this works if you pre-compile your application using aspnet_compiler.exe. You will get compiled DLL files for each of your web forms pages; just open one of those up in Reflector to see the generated code. I wrote a minimal equivalent of your code with the variable declared outside the head tag, and here’s the top-level render method that I got:
private void __Render__control1(HtmlTextWriter __w, Control parameterContainer)
{
string str = "scripts/";
__w.Write("\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n");
parameterContainer.Controls[0].RenderControl(__w);
__w.Write("\r\n<body>\r\n ");
parameterContainer.Controls[1].RenderControl(__w);
__w.Write("\r\n <script type=\"text/javascript\" src=\"");
__w.Write(str);
__w.Write("jquery-1.4.1.min.js\"></script>\r\n</body>\r\n</html>\r\n");
}
You see that the variable that I declared (here named str
) is scoped to this method, and it's calling other methods to render the head (and a form element marked runat="server"
.)
A quick and dirty solution might be to simply remove the runat="server"
from your head tag; however, I’d recommend that you declare a protected variable in your code-behind class for this. Adding a line like this to your code-behind file would work:
protected string scriptPath, gkoConfig;
You can then use these variables anywhere in your Web Forms code.
You could also declare your constants like this:
<script runat="server">
private const string scriptPath = "assets/scripts/";
private const string gkoConfig = "GkoConfig.js";
</script>
I suspect the head of the ASPX page gets processed separately from the body.
This problem is easily solved - all you need to do is use a class field in the code-behind with the access level set to protected.