Before you can do ASP.NET, you must know Html and JavaScript (CSS doesn’t hurt either) – level 100

I’m not going to make this post a rant, but for anyone readers who are new to ASP.NET and have not come from Website development or ASP, there are some prerequisites to ASP.NET.  ASP.NET is a server-side technology that dynamically emits Html and JavaScript.  Now, you can stumble through an ASP.NET HelloWorld sample without knowing any web technologies, but you won’t be able to do anything with it afterwards.  The Microsoft ASP.NET newsgroup is full of people who ask questions about “ASP.NET”, but their question is really about Html, script or CSS.  For instance: “How can I set focus to a textbox on load of the page in ASP.NET?”  That has NOTHING to do with ASP.NET.  It’s simply running some script on the body’s onLoad event.  So the point I want to get accross is to isolate in your mind the Html, script and CSS from ASP.NET, and make sure you know the web front end before you dive into ASP.NET.

IE 5 & 6 Xml databinding – level 300

The following is not a .Net topic.  It’s an Internet Explorer 5 topic.  The following technique can be used with any web page that uses IE 5+ as the client, so I’ve used it with .html, .asp, and .aspx files.  It’s client-side xml databinding with Internet Explorer.  This feature isn’t in Mozilla, but if you have an IE Intranet app, this is a possible way in which you can make your front end more responsive and flexible. 

If you weren’t away, you can embed a section of xml in a web page, add some attributes to some html controls, and IE will automatically duplicate your bound controls for as many nodes as exist in the xml fragment.  There are events that are thrown throughout the binding process, so you can use JavaScript or VBScript to make the front end dynamic.  The following is a simple binding example:

<html>

<xml id=”xml”>

<MyData>

      <Node>

            <CheckBox>checked</CheckBox>

            <Kount>0</Kount>

      </Node>

      <Node>

            <CheckBox>1</CheckBox>

            <Kount>4</Kount>

      </Node>

      <Node>

            <CheckBox>0</CheckBox>

            <Kount>6</Kount>

      </Node>

</MyData>

</xml>

<body>

<table datasrc=”#xml”>

      <tbody>

            <tr>

                  <td>

                        <input type=”checkbox” id=”chk” datafld=”CheckBox”>

                  </td>

                  <td>

                        <input type=”button” id=”btn” datafld=”Kount”>

                  </td>

            </tr>

      </tbody>

</table>

</body>

</html>

Now, one small issue I ran into was that the property bound in the button is the value property.  The value property is the text on the face of the button, so that won’t due.  I modified it using JavaScript and a <input/> tag event to solve this if I need the button to be disabled if the value isn’t 0.

<html>

<script language=”javascript”>

function changeButton(button){

      if(button.value != “0”){

            button.disabled = true;

      }else{

            button.disabled = false;

      }

      button.onpropertychange = “”;

      button.value = “Delete”;

}

</script>

<xml id=”xml”>

<MyData>

      <Node>

            <CheckBox>checked</CheckBox>

            <Kount>0</Kount>

      </Node>

      <Node>

            <CheckBox>1</CheckBox>

            <Kount>4</Kount>

      </Node>

      <Node>

            <CheckBox>0</CheckBox>

            <Kount>6</Kount>

      </Node>

</MyData>

</xml>

<body>

<table datasrc=”#xml”>

      <tbody>

            <tr>

                  <td>

                        <input type=”checkbox” id=”chk” datafld=”CheckBox”>

                  </td>

                  <td>

                        <input type=”button” id=”btn” datafld=”Kount” onpropertychange=”changeButton(this);”>

                  </td>

            </tr>

      </tbody>

</table>

</body>

</html>

There is NO performance different between code-behind and in-line code. – level 200

I recently had an interesting discussion over lunch with a colleague about the performance of in-line code versus the code-behind model.  I relayed that I prefer to put the small, UI-related code in a <script runat=”server”/> block in the .aspx file, and my colleague swore by the code-behind model.  I currently use the code-behind model because intellisense makes development so much faster, but every time I want to make a small change to the UI that involves som C#, I have to fire up VS.NET and then build the whole project.  For my corporate projects I do this anyway because the of the source control, but not all projects need this.  My colleague insisted that script block incur and extra performance hit because the ASP.NET engine must check for changes in every page hit.  After lunch, I whipped up a test and created to ASP.NET pages:  one with code-behind, and the other with the code in a script block.  I ran each for 1 minute in WAST.  Then I ran each 8 more times.  My results:  It doesn’t make a hill of beans difference.  Each test was less than 1% difference.  Some tests the code-behind was less and 1% faster and some resulted in the in-line code being less than 1% faster.  Averaging all the tests gave the same performance for both methods.  So now I know first-hand that it doesn’t matter architecturally.  It’s only personal  and team preference.  Now, don’t take this as an excuse for putting a lot of code in your .aspx page.  If you choose to do that, it should only be UI event handlers.  All REAL code should be in your business objects.  Use this knowledge responsibly!

Share ASP.NET Context with ASP 2 & 3 – level 400

We all have ASP applications that we need to extend with ASP.NET.  Unless our functionality is wrapped in COM, we may have to rewrite some in .Net.  Wouldn’t it be nice if we could rewrite common app functionality in .Net and then reuse it in the ASP?  I’ve worked up a sample that does just that.  I have a web service that exposes the Session object, so now ASP can query the ASP.NET’s Session object (this method could also be used for the Cache object, Application, etc.).  For this to work, ASP has to be in the same ASP.NET session.  That means that the cookie “ASP.NET_SessionId” must exist on the ASP and ASP.NET side, and it must contain the same session id.  Using the Soap Toolkit v.3, I make the web service calls.  One of the web service methods returns the ASP.NET SessionID.  I use this to manually make a Set-Cookie header in ASP because ASP natively HTML Encodes cookie names (would result in %20, or whatever for the . and the _).  Then in subsequent web service calls, I add a soap header to include the cookie with the ASP.NET session id, and this allows every web service call to participate in the same session, so all the data remains coherant. 

Here is my ASP code:

<%@ Language=VBScript%>

<html>

<body>

<%

set soapclient = CreateObject(“MSSOAP.SoapClient30”)

On Error Resume Next

Call soapclient.mssoapinit(Server.MapPath(“Math.wsdl”))

if err <> 0 then

  Response.Write “initialization failed” + err.description

end if

Dim strASPNETSession

if(Request.Cookies(“ASP.NET_SessionID”) <> “”) Then

      soapclient.ConnectorProperty(“RequestHTTPHeader”) = “COOKIE:” & Request.ServerVariables(“HTTP_COOKIE”)

Else

      strASPNETSession = soapclient.GetASPNET_SessionID()

      soapclient.ConnectorProperty(“RequestHTTPHeader”) = “COOKIE:ASP.NET_SessionID=” & strASPNETSession

End If

Dim a

a = soapclient.GetCookies()

Call Response.AddHeader(“Set-Cookie”, a)

Response.Write(“HTTP_COOKIE Server Variables: “)

Response.Write(Request.ServerVariables(“HTTP_COOKIE”) & “<br><br>”)

Response.Write(“Session Hit Counter = ” & soapclient.SessionHitCounter())

if err <> 0 then

  Response.Write err.description & “<BR/>”

  Response.Write “faultcode=” + soapclient.faultcode & “<BR/>”

  Response.Write “faultstring=” + soapclient.faultstring & “<BR/>”

  Response.Write “FaultActor=” + soapclient.FaultActor & “<BR/>”

  Response.Write “Detail=” + soapclient.Detail & “<BR/>”

end if

%>

</body>

</html>

And my web service code:

[WebMethod(true)]

            public string GetSession(string key)

            {

                  return (string)Session[key];

            }

            [WebMethod(true)]

            public void SetSession(string key, string myValue)

            {

                  HttpContext.Current.Session[key] = myValue;

            }

            [WebMethod(true)]

            public int SessionHitCounter()

            {

                  if (Session[“HitCounter”] == null)

                  {

                        Session[“HitCounter”] = 1;

                  }

                  else

                  {

                        Session[“HitCounter”] = ((int) Session[“HitCounter”]) + 1;

                  }

                  return ((int) Session[“HitCounter”]);

            }

            [WebMethod(true)]

            public string GetASPNET_SessionID()

            {

                  return Context.Request.Cookies[“ASP.NET_SessionId”].Value;

            }

            [WebMethod(true)]

            public string GetCookies()

            {

                  return Context.Request.ServerVariables[“HTTP_COOKIE”];

            }

I was so excited when I got this to work, I had to share.  If you search for this topic on Google, there are thousands of people who have this problem.

EZWeb Beta 0.51 Released on GotDotNet!!!

Go to the EZWeb workspace and download the latest release of my EZWeb application framework.  As I post, 63 people downloaded the first release.  I am pleased that there is interest in this project.  I fixed a bug involving the use of Request.ApplicationPath. 

If I ran EZWeb in a virtual directory, Request.ApplicationPath would return “/ezweb”, but if I ran it as the root web, it would return “/”.  This is inconsistent, so I created a property on my base page called “AppPath” where I correctly determine the path of the application wherever it happens to run.  I used Page.ResolveUrl(”~/”), and this always gives me the correct application path. 

If you don’t already have your own framework for web applications, EZWeb is a great place to start.  If you are just looking for a website that will run itself and will be easy to edit, EZWeb is also for you. 

If you have implemented EZWeb on a public website, send me the URL, so I can check it out!!!

EZWeb Root application bug

In response to comment http://dotnetjunkies.com/WebLog/jpalermo/archive/2004/05/13/13531.aspx#13805:

I have logged one bug regarding the EZWeb Beta 0.5 on the GotDotNet workspace, and it’s relating to the templates that I have included not rendering correcting when running as a root web.  When in a virtual directory, all is well, but when running as root web, the .css and images don’t render correctly.  This is a problem with the sample template that I included.  I will fix the template along with some other things and have another release.  I welcome input and contributions of plugins and templates.  One thing that would be really cool is to make DotNetNuke an EZWeb plugin so any EZWeb user could choose “portal” as part of their site.

Using inheritance with ASP.NET pages


I go back to work full time next Tuesday.  My terminal leave is almost up, I’m a civilian, and my new office furniture will be arriving today. 🙂 


Yesterday I was visiting with two colleagues of mine, and I was struck with a surprising reality:  They were programming with ASP.NET but had no idea that they were using inheritance.  One of the two was a former college professor of mine from whom I learned a great deal of database knowledge.  I pondered on it for a while, and I think that there are probably many out there that don’t yet know how to use the power of inheritance to improve their .Net web applications.  I will now attempt to simply explain an easy way one can easily improve a page using inheritance.


First, when you write code in an ASP.NET page, you are writing code in a class that is inheriting from another class.  Whether it’s specified in the machine.config, web.config or in the <@Page> directive at the top of the page, your page has to inherit from a class that ultimately will inherit from System.Web.UI.Page.  When you use the code-behind or code-beside technique, your page inherits from your code-behind class, which inherits from System.Web.UI.Page.  Look at the class.  Why else do you see “System.Web.UI.Page” in every code-behind page?  It makes your page contain the functionality of the Page class in the .Net framework.  It makes your page a System.Web.UI.Page object.  The Page object contains the properties for accessing Request, Response, Server, Cache, etc. 


Suppose you want to implement tracking for some of your pages?  You could put relevant code in every page, or make a static method in a shared class to track the current request.  But why not put this functionality in a class by itself, say “TrackedPage”.  When you declare TrackedPage, inherit from System.Web.UI.Page:


public class TrackedPage : System.Web.UI.Page{ }


and in your code-behind page, replace the reference to System.Web.UI.Page with “TrackedPage”.  This will make your page a “TrackedPage” object and will benefit from any logic you put in TrackedPage.  For instance,


public class TrackedPage :  System.Web.UI.Page{
protected override void OnInit(EventArgs e)
  {
   base.OnInit(e);
   //logic to track this request
   Trace.Write(“Tracking“, “This request has been tracked.“);
  }
}


will perform your tracking logic and write a line to the trace log for every page that inherits this custom class of yours.  You can imagine all the functionality you can include.  What if you have a custom user object that you need to be available for every request?  Make it a property of your class here, and make it the base page for all your pages? 


I find that a lot of people make user controls to encapsulate common functionality.  This is not a good technique.  Instead, put it in base pages and inherit from them.


My project on GotDotNet makes heavy use of this technique, and it’s easy to extend EZWeb because all you have to do is inherit from Palermo.EZWeb.UIPage, and you have all the functionality available.

GotDotNet Workspace Woes

Yesterday I was very excited to post my first release of my EZWeb project on GotDotNet.

http://workspaces.gotdotnet.com/ezweb

I had applied for a sourceforge.net workspace, but after waiting a week for “approval”, I just wanted it working, so I set it up on GotDotNet.  The workspace pages were slow, but they worked.  Source control was painfully slow, but it worked.  Yesterday evening I noticed that several people had already downloaded my release.  How exciting!!  This morning, I have yet to get to my workspace.  GotDotNet keeps erroring out!!  What gives?  Is anyone else experiencing this?  I can’t even get to the workspace for .Text!

My first public EZWeb release. Version 0.5 Beta

In previous posts, I’ve mentioned EZWeb, my current pet project.  It can be quite useful even if it’s just to make a template for your web apps.  I was surprised that so many people use a header and footer user controls to wrap page content with navigation and common content.  EZWeb will wrap your content with your custom template.  Join my workspace at:

http://workspaces.gotdotnet.com/ezweb
or
http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=949a0c93-38f2-4bd2-9f69-a49bb3c7938d

and contribute some features.  Plugin developers needed.  One of the first priorities should be a file upload plugin.  Please contact me with any questions.  I’m excited about this release, and I hope some of you will be interested in contributing to and using this project.

My project provides master pages features now!

In my previous post, I inquire about where to host an open-source project.  Well, I was just investigating the features promised by Master Pages in ASP.NET 2.0, and I realized that EZWeb provides some of those same features in .Net 1.1.  Master pages is discussed here on www.asp.net, and EZWeb provides the navigation abstraction as well as look and feel abstraction.  It does not allow for nested master pages (or nested templates in EZWeb – only one template per page), and it doesn’t automatically have a generated sitemap, but now I have the urge to develop a plugin that will automatically generate a sitemap for all ancestor pages.  Again, EZWeb will be availabe for download and contribution as soon as I get the workspace set up.