Is there a way to use “<%= someObject.Clien

2019-01-16 10:40发布

问题:

Is there a way to use "<%= someObject.ClientID %>" in an external javascript file?

If I use the code

<%= someObject.ClientID %>

in a script tag inside my as(c/p)x page, it works fine. On the rendered page, the ClientID is resolved. Howvever, if I put in an external JS file and just add:

It doesn't. Is there a way to do this or am I stuck with leaving that code in the as(c/p)x file?

Side question -- what is the act of doing <%=... %> in your markup file called?

回答1:

This is totally possible.

In your presentation layer (your .aspx page), create a script reference to an aspx page that contains your javascript code:

<script src="../MyJavaScriptFile.js.aspx" type='text/javascript'></script>

Then, in MyJavaScriptFile.js.aspx, you can write the following:

<%@ Page Language="C#" AutoEventWireup="false"  ContentType="text/javascript" %>

    <% 
        CustomPersonObject cpt = new CustomPersonObject();
        cpt.firstname = "John";
        cpt.lastname  = "Smith";
    %>

// Start Javascript
var personFirstName = '<% HttpContext.Current.Response.Write(cpt.name);%>';
var personLastName = '<% HttpContext.Current.Response.Write(cpt.lastname);%>'

One technique I frequently use is to pass the value I need evaluated in my javascript file as a url parameter in the initial script reference:

 <script src="../MyJavaScriptFile.js.aspx?username=<% somevalue %>" 
       type='text/javascript'></script>

Then, in MyJavaScriptFile.js.aspx, I can reference the value with

<% Request.QueryString["username"] %>

It's not the "best practice" way to do things, but it gets the job done in a way that my caveman brain can understand without having to resort to fancy workarounds and extra code.



回答2:

If you really want to do this you can do following

<%@ Page ContentType="text/javascript" Language="C#" AutoEventWireup="false" %>
<%@ OutputCache Duration="86400" Location="Any" VaryByParam="None" %>

var time = "<%= DateTime.Now.ToString() %>";
alert(time);

And then reference it in your page

<script src="Scripts/file.aspx" type="text/javascript"></script>

Note When using mentioned method, the only way to pass target page controls client-ids, is to store client id as string in a public property, and then reference it using new instance of that page

If the only thing that made you to do this is client-id then you can use following ASP.NET 4 feature

<any-tag ID="myCustomId" runat="server" ClientIDMode="Static" />

You can also put all your client-ids in C# class then serialize it using JSON and render it in script tag, could be smart way for ASP.NET prior to version 4.

Note using serialization method you have possibility to change any tag ids without worrying about javascript element usages, remember that this is not even possible with ASP.NET 4 ClientIDMode

See

Page-Code-File

public partial class About : System.Web.UI.Page
{
    ...

    protected string GetTagIds()
    {
        return new JavaScriptSerializer()
                    .Serialize(new
                     {
                            myButton = Button1.ClientID,
                            myCalendar = Calendar1.ClientID
                     });
    } 

    ...
}

Page-ASPX

<script type="text/javascript">
    var IDs = <%= GetTagIds() %>;
</script>

Anywhere

<script type="text/javascript">
    IDs.myCalendar.doSomthing...
</script>

There is another option that you can pass all javascript files to ASP.NET handler but i don't recommend it, because of just a single javascript file you make asp.net handler busy.

Code Blocks

<% inline code %>

This is an inline code definition which you can execute codes in it :

<% Response.Write("Hi"); %>

<% while(i < 0) { %>
      <% 
         Response.Write(i.ToString()); 
         i++;
      %>
<%}%>

Note You have to include ';' on end of each statement when using inline code with C# language, you can change inline language using page directive language attribute

<%= inline expression %>

This one equals to calling Response.Write your self, see:

<%= "Hi" %> equals to <% Response.Write("Hi"); %>

Note You shouldn't include ';' when using inline expression

<%: encoded inline expression %>

This one equals to :

Response.Write(HttpUtility.HtmlEncode("<script type="text/javascript">alert('XSS');</script>"))

And is used for security reasons --XSS, any input HTML to this one outputs HTML encoded text which is safe to display user entered contents in page.

Note You shouldn't include ';' when using encoded inline expression

<%$ expressionPrefix: expressionField %>

This one is expression that you can use to bind values from ConnectionStrings, Resources and AppSettings

expressionPrefix possibilities is

  • AppSettings
  • ConnectionStrings
  • Resources

expressionField is the property of specified expressionPrefix that you need, see:

// AppSettings
<asp:Label ... Text="<%$ AppSettings: version %>" />

// ConnectionStrings
<asp:SqlDataSource ... ConnectionString="<%$ ConnectionStrings:dbConnectionString %>" />

// Resources
<asp:Label ... Text="<%$ Resources: Messages, Welcome %>" />

Note You shouldn't include ';' and you can use expressions only on ASP.Net controls attributes

<%# data-binding expression %>

You can use this anywhere inside controls with data-binding support, and usually is used by Eval and Bind methods.

<asp:DropDownList SelectedValue='<%# Bind("CategoryID") %>' 
                  DataSourceID="CategoriesDataSource"
                  DataTextField="CategoryName"
                  DataValueField="CategoryID"
                  runat="Server" />

Which one Eval or Bind?

Using Bind you have two-way binding set over specified attribute of ASP.NET control see the mentioned drop-down, it is using Bind that means if end-user selects a value and then submit the page, drop-down will not loose its selected value.

Use Eval just for displaying data.

<asp:FormView ...>
     <ItemTemplate>
          <a href='Eval("Link")'>Eval("LinkText")</a>
     </ItemTemplate>
</asp:FormView>

<%@ text template directive %>

<%@ Page ...%>
This one is Page Directive

<%@ OutputCache...%>
This one is OutputCache Directive and so on...


回答3:

I like to embed a single line of javascript on my page.

<script type="text/javascript">
   Application.init({variable1: "value1", variable2: "value2"...});
</script>

It's poor practice to have a ton of javascript rendered on your page, but it is common to need to pass initialization values to your javascript from the server. This allows you to do it without a whole bunch of unnecessary code and without polluting the global namespace with callback functions. I usually replace Application with some project specific global wrapper.



回答4:

This adds a bit more HTML but it works; wrap each server control in a div...

<div id="myContainer">
    <asp:HiddenField ID="hdMyControl" runat="server" /></div>

Set the HiddenField's value in the code behind

hdMyControl.Value = "something";

Then in your external JS file you can get the server control's value

$(document).ready(function () {
    var myValue= $('#myContainer input[type=hidden]').val();

I'm not sure that it matters, but I'm adding the script reference to the page via the codebehind using RegisterClientScriptBlock



回答5:

No, it won't work like that because the javascript file is being transmitted independently as a separate file and it isn't parsed by ASP.NET on the way out, while your aspx file IS being parsed and the .NET engine is replacing the tag w/ the actual value.

Now when your objects call those JS functions, what they could do is pass references to themselves into the function, or even pass in a dictionary list of some sort with your own key for what the control is and the assigned name.

One thing to think about as well - IF you are going to make a JS file independent of an ASPX page, then that JS file absolutely should not presume to know anything about the specific controls of the aspx file that calls it - because later on someone else might decide, "Oh that's a good JS file, I'll incorporate it too" and it won't work for them cause their objects wont match yours. Thus the pattern you should follow would have to be more generic - thus why you'd want to pass in references or lists of identifiers.



回答6:

The server tag <%= %> is used to enter code that is processed on the server.

You cannot use <%= someObject.ClientID %> in an external js file because the server tag is an asp.net thing and js doesn't know what this is.

If you use ASP.NET 4 you can set the client id in the properties of the control making it predictable.

If you don't use ASP.NET 4 you could put this client id in a hidden field or an inline js variable.



回答7:

You could create an empty callback function in the external file:

var MyCallback = function () { };

And then in the asp/cx do something like:

MyCallback = function () {return "<%= someObject.ClientID %>";}

And then, back in your external file:

var myClientID = MyCallback();


回答8:

Use the standard prefix identifier in script source files:

document.getElementById("ctl00_ContentDetail_textboxelename").value = "";
document.getElementById("ctl00_ContentDetail_radioORcheckboxelename").checked = false;
document.getElementById("ctl00_ContentDetail_elename").style.visibility = "hidden";
var javaele = document.getElementById("ctl00_ContentDetail_elename");
var boolIsChecked = document.getElementById("ctl00_ContentDetail_radioORcheckboxelename").checked;