What does <%: %> do in ASP.NET (MVC2)? - asp.net

A coworker recently checked in a changeset where lots of expressions on the form <%= (...) %> were changed to <%: (...) %>.
I have a vague recollection of having heard what <%: does, but cannot remember. It's too late in the night to call my coworker, and Google and Bing both seem unable to search for the string "<%:".
Can someone enlighten me, please?

It HtmlEncodes the string, if it hasn't already been encoded.
The "hasn't already been encoded part" is why MvcHtmlString was introduced. MVC2 returns MvcHtmlString from many HtmlHelper methods to represent strings that should not be re-encoded.
The <%: %> knows not to re-encode.
See What is an MvcHtmlString and when should I use it? for a good discussion.

It automatically wraps the rendered output in Html.Encode() to avoid scripting attacks.

One way to remember this is (courtesy: Scott Hanselman) think = as an closed gate. Now open the gate by turning it 90 degrees and see it from the same view. you will see :

Related

How to get the URL generated from Scripts.Render(“~/bundles/someScript”)?

When I do Scripts.Render(“~/bundles/someScript”), it may be translated into something like
<script src="/someURL/bundles/someScript?v=asdY9xOxSVHQfe4hgu-iqLwv6wr6rbpT3YvcuODIqQ1"></script>
My question is, how can I get the value that is generated this value /someURL/bundles/someScript?v=asdY9xOxSVHQfe4hgu-iqLwv6wr6rbpT3YvcuODIqQ1 and store it into some variable ?
I managed to find out the solution, is to use <%: Scripts.Url("~/bundles/someScript") %>. This will produce the URL generated by Scripts.Render method.

ASP.NET application doesn't reflect Regional settings

I've set, in my regional settings (for Czech, culture cs-CZ), the short time / long time pattern to following:
Short time: H.mm
Long time: H.mm.ss
I'm trying to use those settings in C# applications.
In following console app, everything works:
using System;
using System.Globalization;
class Program
{
static void Main()
{
Console.WriteLine(CultureInfo.CurrentCulture.Name);
Console.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern);
Console.ReadLine();
}
}
The output is, as I thought, following:
cs-CZ
H.mm.ss
I've created ASP.NET application, which, to my uttermost surprise, doesn't reflect this.
Minimal example:
<%# Page Language="C#" %>
<%= System.Globalization.CultureInfo.CurrentCulture.Name %><br />
<%= System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern %>
Output:
cs-CZ
H:mm:ss
I've tried restarting, .NET2.0, .NET4.0, still no effect.
Note - This issue raised as a part of bug, where we forgot to include InvariantCulture for DateTime.ToString(), which should then be parsed by JSON deserializer. (The guy with this problem has somewhat different Time format separator).
Fixing the issue with re-creating CultureInfo isn't something I'm looking for, I just want to see the reason, as I wasn't able to reproduce the issue with any means.
The problem is that the Regional Settings are user specific. You changed them for you, but the site runs as a different user (see the app-pool in IIS)

Does many include's (in "case") in ASP classic hurt the performance of the server?

I want to build this page with ASP classic:
<%
Dim depart
depart = 1556
Select Case depart
Case 1
%>
<!--#include virtual="/check/noam/newDesign/test1.asp"-->
<%
Case 2
%>
<!--#include virtual="/check/noam/newDesign/test2.asp"-->
<%
Case 3
%>
<!--#include virtual="/check/noam/newDesign/test3.asp"-->
<%
Case 4
%>
<!--#include virtual="/check/noam/newDesign/test4.asp"-->
<%
Case 5
%>
<!--#include virtual="/check/noam/newDesign/test5.asp"-->
<%
Case 6
%>
<!--#include virtual="/check/noam/newDesign/test6.asp"-->
<%
Case 7
%>
<!--#include virtual="/check/noam/newDesign/test7.asp"-->
<%
Case 8
%>
<!--#include virtual="/check/noam/newDesign/test8.asp"-->
<%
End If
%>
And I like to know if the server in the background need to enter to every include or he will enter only to the include in the right case?
I need to know that because I like to know if the server will get bad performance with this one.
It really depends on what is inside the includes but I wouldn't expect such a structure to have any observable impact on performance unless you either have 100s of case statements or have 100s of requests per second for the page.
It is true that all the includes will be composed into the script first before code is executed however it should also be remember that the composed and parsed "p-code" version of the final script is cached by ASP.
If the includes are primarly just static HTML content then this approach is actually quite efficient. On the other hand the more inline global identifiers (identifiers not enclosed in Sub, Function or Class) the more time needed to register these identifiers in the Script context (however there would still need to a lot of them to make a noticable difference).
A potential alternative is to use Server.Execute instead of an include. In this case the ASP executed has its own independant script context so it can't share the callers functions and variables (this may or may not be a good thing.) Also its quite possible that Server.Execute will actually turn out slower.
Includes are loaded before they're executed in classic ASP, so you're basically loading all of these includes, even if they're not executed.
You can use a different pattern: Execute Global, which is the equivalent of using eval() in VB. You read in the file as a string, then execute it. This gets around a cluster of includes but is rather ugly in itself.
You can use server.execute
server.execute("/check/noam/newDesign/test"&depart&".asp")
OR
page="/check/noam/newDesign/test"&depart&".asp"
server.execute(page)

ASP.NET MVC: Using LINQ to XML to render (X)HTML

There has been a lot of discussions on View-engines for ASP.NET MVC and some criticisms against the inline "tag-soup" with for-loops and thing like it.
The alternative or complement has been to use HTML-helpers, which are just inline method-calls.
When I look inside ASP.NET MVC's HTML-helpers today they are using a class called TagBuilder.
My proposal is to use LINQ to XML to get strongly typed and correctly formatted (X)HTML:
XDocument output = new XDocument();
XElement root = new XElement("div",
new XAttribute("class", "root_item"));
XElement iconImage = new XElement("img",
new XAttribute("src", ResolveUrl("~/image.gif")),
new XAttribute("alt", "This is an image"));
XElement link = new XElement("a",
new XAttribute("class", "link"),
new XAttribute("href", "http://google.com"),
new XText("Link to Google"));
root.Add(link);
root.Add(iconImage);
output.Add(root);
I like it because it's like the strongly typed controls in WebForms, where you can new-up a Button and add it to another control's Control-collection.
Are there any apparent problems or limitations in this?
This is a great idea! The only problem I see with it is the use of C#. ;) VB.NET has much better support for producing XML via it's XML literals feature.
The code you list in your question could be written like this in VB.NET. (With the addition of the text "This is a link" as your example didn't contain any text within the a element.)
Dim root = <div class="root_item">
<img src=<%= ResolveUrl("~/image.gif") %> alt="This is an image"/>
<a class="link" href="http://google.com">This is a link</a>
</div>
There are still <%= ... %> tags, but they are checked for validity at compile time. If this code was made the return value of a function that returned type XElement, then that Xhtml snippet could be reused elsewhere in the site.
I have a project on CodePlex that uses VB.NET XML Literals as a custom ASP.NET MVC View Engine at http://vbmvc.codeplex.com. It is based on code by Dmitry Robsman, who is Product Unit Manager for ASP.NET at Microsoft. Views are VB.NET classes and Master Pages are base classes. You new-up Partial view classes instead of referencing them by a name string, so that is also an additional compile time check. Instead of the HtmlHelper class, which returns strings, there is an XhtmlHelper class which returns XElement and works similarly to what you have proposed.
I can think of two problems to the above mentioned method.
First,
XElement iconImage = new XElement("img",
new XAttribute("src", ResolveUrl("~/image.gif")),
new XAttribute("alt", "This is an image"));
Referring to what you write above, we can have something like:
<img src=<%=whatever%> alt=<%=whatever%> />
This might be personal judgement or what, but I certainly vote the later one more "human" readable. Right, using LINQ 2 XML might get rid of the weird <% } %> that wandering around in my aspx pages, but at the same time, you make those "good boys" looks clumsy.
Second might come with performance issue. I think parsing and executing LINQ 2 XML could be quite slow, although I don't have any data regarding this.
Personally I am still experimenting the MVC framework, it feels like getting back to old days like ASP or PHP 3.X, since almost all the interactive parts are explicitly handled, instead of the window/GUI-OOP oriented ASP Dot Net Framework. I think the main reason I will use MVC is that it can guarantee the best quality client-side HTML codes..

What is going on in this ExecuteDataset method?

OK so I one page I find this line:
objDsCourse = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings("connstr").ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPAra)
And I copied it to another page to start modifying it to work there:
getData = SqlHelper.ExecuteDataset(ConfigurationManager.ConnectionStrings("connstr").ConnectionString, CommandType.StoredProcedure, "Course_NewReportGet_Get_Sav", objPAra)
However on the new page it underlines .ConnectionStrings saying that Non-invocable member 'System.Configuration.ConfigurationManager.ConnectionStrings' cannot be used like a method'... then why did it work in the other page??
EDIT: OK so I found in web.config what I think it is referencing because it says
<add name="ConnStr" connectionString="data source=..." />
Why would one page have access to this and the other not?
Is there any chance one page is using VB.NET, while the other is using C#?
I would agree with Daniel. In Visual Basic, both dictionary objects and methods are referenced by using parentheses. This can cause some confusion.
So in VB, ConfigurationManager.ConnectionStrings("connstr") would point to the ConnectionString object with the key "connstr" in the dictionary.
In C#, dictionary objects are referenced by square brackets [] so ConfigurationManager.ConnectionStrings("connstr") would literally mean "invoke the method ConnectionStrings of ConfigurationManager object using "connstr" as a parameter."
Long story short, check the <%# Page %> declaration at the top to make sure both pages are the same language. ... or, on the page with the error, change the line to use the ConfigurationManager.ConnectionStrings["connstr"] syntax.

Resources