Variable scope in aspx page

2019-06-15 10:57发布

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?

enter image description here

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

enter image description here

3条回答
倾城 Initia
2楼-- · 2019-06-15 11:25

You could also declare your constants like this:

<script runat="server">
    private const string scriptPath = "assets/scripts/";
    private const string gkoConfig = "GkoConfig.js";
</script>
查看更多
甜甜的少女心
3楼-- · 2019-06-15 11:39

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.

查看更多
狗以群分
4楼-- · 2019-06-15 11:46

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.

查看更多
登录 后发表回答