Category: Asp.Net with C#


I was a little confused about the difference between <%= expression %> and <%# expression %> in ASP.NET. It seems like both work in a lot of cases, but in other cases, only the # (data binding) version works. So, I decided to dig into it a little bit. To try it out I built this simple page:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p>Equals: <%= this.TestValue %></p>
        <p>Pound: <%# this.TestValue %></p>
        <p>Equals label: <asp:Label runat="server" ID="_equals" Text="<%= this.TestValue %>" /></p>
        <p>Pound label: <asp:Label runat="server" ID="_pound" Text="<%# this.TestValue %>" /></p>
    </div>
    </form>
</body>
</html>

And the code behind is:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        _testValue = "2";
    }

    protected void Page_PreRenderComplete(object sender, EventArgs e)
    {
        // DataBind();
        _testValue = "3";
    }

    public string TestValue
    {
        get { return _testValue; }
    }

    private string _testValue = "1";
}

Here’s what the result is when the DataBind() line is commented out:

Equals: 3

Pound:

Equals label:

Pound label:

And, when it’s not commented out:

Equals: 3

Pound: 2

Equals label:

Pound label: 2

At first glance it looks like the Equals label case did nothing. But, if you view source, you see:

<p>Equals label: <span id=”_equals”><%= this.TestValue %></span></p>

The literal expression made it down to the browser and it’s just invalid HTML. What you can see as a result is:

  • The <%= expressions are evaluated at render time
  • The <%# expressions are evaluated at DataBind() time and are not evaluated at all if DataBind() is not called.
  • <%# expressions can be used as properties in server-side controls. <%= expressions cannot.

Now, let’s look at the generated code to see how it works. It builds the control tree using the following code:

        private void @__BuildControlTree(default_aspx @__ctrl) {
            this.InitializeCulture();

            System.Web.UI.IParserAccessor @__parser = ((System.Web.UI.IParserAccessor)(@__ctrl));
            @__parser.AddParsedSubObject(new
                        System.Web.UI.LiteralControl("\r\n\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/1" +
                        "999/xhtml\" >\r\n"));

            global::System.Web.UI.HtmlControls.HtmlHead @__ctrl1;
            @__ctrl1 = this.@__BuildControl__control2();
            @__parser.AddParsedSubObject(@__ctrl1);
            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n<body>\r\n    "));

            global::System.Web.UI.HtmlControls.HtmlForm @__ctrl2;
            @__ctrl2 = this.@__BuildControlform1();
            @__parser.AddParsedSubObject(@__ctrl2);

            @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n</body>\r\n</html>\r\n"));
        }

@__BuildControl__control2() isn’t that intersting, it’s just the <head> stuff. The guts are in @__BuildControlform1():

        private global::System.Web.UI.HtmlControls.HtmlForm @__BuildControlform1() {
            global::System.Web.UI.HtmlControls.HtmlForm @__ctrl;
            @__ctrl = new global::System.Web.UI.HtmlControls.HtmlForm();
            this.form1 = @__ctrl;
            @__ctrl.ID = "form1";

            global::System.Web.UI.DataBoundLiteralControl @__ctrl1;
            @__ctrl1 = this.@__BuildControl__control4();
            System.Web.UI.IParserAccessor @__parser = ((System.Web.UI.IParserAccessor)(@__ctrl));
            @__parser.AddParsedSubObject(@__ctrl1);

            global::System.Web.UI.WebControls.Label @__ctrl2;
            @__ctrl2 = this.@__BuildControl_equals();
            @__parser.AddParsedSubObject(@__ctrl2);

            global::System.Web.UI.WebControls.Label @__ctrl3;
            @__ctrl3 = this.@__BuildControl_pound();
            @__parser.AddParsedSubObject(@__ctrl3);

            @__ctrl.SetRenderMethodDelegate(new System.Web.UI.RenderMethod(this.@__Renderform1));
            return @__ctrl;
        }

This is building all of the controls in the form. First let’s look at the control built with @__BuildControl__control4():

        private global::System.Web.UI.DataBoundLiteralControl @__BuildControl__control4() {
            global::System.Web.UI.DataBoundLiteralControl @__ctrl;

            @__ctrl = new global::System.Web.UI.DataBoundLiteralControl(2, 1);
            @__ctrl.SetStaticString(0, "</p>\r\n        <p>Pound: ");
            @__ctrl.SetStaticString(1, "</p>\r\n        <p>Equals label: ");
            @__ctrl.DataBinding += new System.EventHandler(this.@__DataBind__control4);

            return @__ctrl;
        }

And related to this is:

        public void @__DataBind__control4(object sender, System.EventArgs e) {
            System.Web.UI.Page Container;
            System.Web.UI.DataBoundLiteralControl target;

            target = ((System.Web.UI.DataBoundLiteralControl)(sender));
            Container = ((System.Web.UI.Page)(target.BindingContainer));
            target.SetDataBoundString(0, System.Convert.ToString(this.TestValue, System.Globalization.CultureInfo.CurrentCulture));
        }

This is the part of the page up to the first <%#. You can see that it uses a DataBoundLiteralControl which is divided between static strings and data bound strings. When DataBind is called on the page, the event handler is called and SetDataBoundString is called on the control. This is why the value is captured at bind time. If you want to see how DataBoundLiteralControl works, you can use .NET Reflector. You can see that it’s Render function looks like:

    protected internal override void Render(HtmlTextWriter output)
    {
        int num1 = this._dataBoundLiteral.Length;
        for (int num2 = 0; num2 < this._staticLiterals.Length; num2++)
        {
            if (this._staticLiterals[num2] != null)
            {
                output.Write(this._staticLiterals[num2]);
            }
            if ((num2 < num1) && (this._dataBoundLiteral[num2] != null))
            {
                output.Write(this._dataBoundLiteral[num2]);
            }
        }
    }

So, it basically outputs the static and data bound fields alternately. That’s how it renders the first <%# value on the page if DataBind() is called. Next, let’s look at the “_equals” control:

        private global::System.Web.UI.WebControls.Label @__BuildControl_equals() {
            global::System.Web.UI.WebControls.Label @__ctrl;

            @__ctrl = new global::System.Web.UI.WebControls.Label();
            @__ctrl.ApplyStyleSheetSkin(this);
            @__ctrl.ID = "_equals";
            @__ctrl.Text = "<%= this.TestValue %>";

            return @__ctrl;
        }

You can see that the <%= is not in any way special. It’s just literal text. The “_pound” control, which uses <%# on the other hand, looks like:

        private global::System.Web.UI.WebControls.Label @__BuildControl_pound() {
            global::System.Web.UI.WebControls.Label @__ctrl;

            @__ctrl = new global::System.Web.UI.WebControls.Label();
            @__ctrl.ApplyStyleSheetSkin(this);
            @__ctrl.ID = "_pound";
            @__ctrl.DataBinding += new System.EventHandler(this.@__DataBinding_pound);

            return @__ctrl;
        }

        public void @__DataBinding_pound(object sender, System.EventArgs e) {
            System.Web.UI.WebControls.Label dataBindingExpressionBuilderTarget;
            System.Web.UI.Page Container;
            dataBindingExpressionBuilderTarget = ((System.Web.UI.WebControls.Label)(sender));
            Container = ((System.Web.UI.Page)(dataBindingExpressionBuilderTarget.BindingContainer));

            dataBindingExpressionBuilderTarget.Text = System.Convert.ToString( this.TestValue , System.Globalization.CultureInfo.CurrentCulture);
        }

As compared to the <%= version, <%# is treated specially in parameters. It adds a data binding handler and sets the property at data bind time. That’s why <%# does work in parameters and why it picks up the value at data bind time.

So, how does the first <%= work? We can see this by looking at the following function:

        private void @__Renderform1(System.Web.UI.HtmlTextWriter @__w, System.Web.UI.Control parameterContainer) {
            @__w.Write("        <p>Equals: ");
            @__w.Write( this.TestValue );

            parameterContainer.Controls[0].RenderControl(@__w);
            parameterContainer.Controls[1].RenderControl(@__w);
            @__w.Write("</p>\r\n        <p>Pound label: ");
            parameterContainer.Controls[2].RenderControl(@__w);
            @__w.Write("</p>\r\n    </div>\r\n    ");
        }

Here we can see the @__w.Write(this.TestValue) line which is the result of the <%= line in the source. It’s outputting the value of this.TestValue at render time, which explains the behavior we saw.

So, it all makes sense to me now. I hope it makes sense to you too 🙂

Original Post : http://blogs.msdn.com/b/dancre/archive/2007/02/13/the-difference-between-lt-and-lt-in-asp-net.aspx

using System.Security.Principal;

Code :

IPrincipal user = this.Page.User;

if (User.IsInRole(“administrator”))

{

// do anything

}

Tóm lượt từ các tutorial tại http://www.asp.net

Create User:

link gốc : http://www.asp.net/learn/security/tutorial-05-cs.aspx

MembershipCreateStatus createStatus;

MembershipUser newUser = Membership.CreateUser(Username.Text, Password.Text, Email.Text, passwordQuestion, SecurityAnswer.Text, true, out createStatus);

kiểm tra quá trình create user bằng creatStatus.

Kiểm tra quyền của user:

link : http://www.asp.net/learn/security/tutorial-08-cs.aspx

Get a reference to the currently logged on user

MembershipUser currentUser = Membership.GetUser();

Determine the currently logged on user's UserId value

Guid currentUserId = (Guid)currentUser.ProviderUserKey;

Kiểm tra Role của user hiện tại:

bool allow = (currentUser.IsInRole("Role cần kiểm tra"))

Tạm thời copy 2 em thường dùng nhưng cũng thường quên nhất 😦

RemoveHTML

using System.Text.RegularExpressions;

  ...

  public static string RemoveHTML(string in_HTML)
    {
      return Regex.Replace(in_HTML, "<(.|\n)*?>", "");
    }

Solution

Reference articles:

  • Tip/Trick: Url Rewriting with ASP.NET by Scott Guthrie – Examines four approaches: 1) Use Request.PathInfo Parameters Instead of QueryStrings; 2) Using an HttpModule to Perform URL Rewriting; 3) Using an HttpModule to Perform Extension-Less URL Rewriting with IIS7; 4) ISAPIRewrite to enable Extension-less URL Rewriting for IIS5 and IIS6; also discusses how to handle ASP.NET postbacks correctly with URL rewriting.
  • URL Rewriting by Salman (CSharpFriends) – simple implementation of URL rewriting logic within the Application_BeginRequest() method of the Global.asax file.
  • Rewrite.NET – A URL Rewriting Engine for .NET by Robert Chartier (15Seconds.com). Solution steps:
    • Create the HttpModule to process the web request and rewrite the URL
    • Add the handler in Web.config
    • Create a configuration section in Web.config to define URL mapping rules
    • Add extensibility by creating a rules engine interface
    • Write class or classes to implement rules engine interface
    • Add code to the HttpModule to dynamically load the desired rules from Web.config
  • URL Rewriting in ASP.NET by Scott Mitchell (MSDN) – examines how to implement URL rewriting in a HTTP module; also explains how to handle postbacks.
  • URL Rewriting with ASP.NET by Richard Birkby (CodeProject) – shows how legacy ASP sites can be upgraded to ASP.NET, while maintaining links from search engines. Solution steps:
    • Create the configuration section in Web.config for defining URL mapping rules
    • Write the configuration section handler class, incorporating the URL rewriting logic
    • Create a call to handler in Global.asax in Application_BeginRequest() method
    • Compile the code and install the rewriter assembly in the Global Assembly Cache (GAC)
    • Configure IIS to map non- .aspx files to the ASP.NET ISAPI extension

Related Resources