Anda di halaman 1dari 91

Understanding ASP.

NET View State


Scott Mitchell 4GuysFromRolla.com May 2004 Applies to: Microsoft ASP.NET Microsoft Visual Studio .NET Summary: Scott Mitchell looks at the benefits of and confusion around View State in Microsoft ASP.NET. In addition, he shows you how you can interpret (and protect) the data stored in View State. (25 printed pages) Click here to download the code sample for this article. Contents Introduction The ASP.NET Page Life Cycle The Role of View State View State and Dynamically Added Controls The ViewState Property Timing the Tracking of View State Storing Information in the Page's ViewState Property The Cost of View State Disabling the View State Specifying Where to Persist the View State Parsing the View State View State and Security Implications Conclusion

Introduction
Microsoft ASP.NET view state, in a nutshell, is the technique used by an ASP.NET Web page to persist changes to the state of a Web Form across postbacks. In my experiences as a trainer and consultant, view state has caused the most confusion among ASP.NET developers. When creating custom server controls or doing more advanced page techniques, not having a solid grasp of what view state is and how it works can come back to bite you. Web designers who are focused on creating low-bandwidth, streamlined pages oftentimes find themselves frustrated with view state, as well. The view state of a page is, by default, placed in a hidden form field named __VIEWSTATE.

This hidden form field can easily get very large, on the order of tens of kilobytes. Not only does the __VIEWSTATE form field cause slower downloads, but, whenever the user posts back the Web page, the contents of this hidden form field must be posted back in the HTTP request, thereby lengthening the request time, as well. This article aims to be an in-depth examination of the ASP.NET view state. We'll look at exactly what view state is storing, and how the view state is serialized to the hidden form field and deserialized back on postback. We'll also discuss techniques for reducing the bandwidth required by the view state. Note This article is geared toward the ASP.NET page developer rather than the ASP.NET server control developer. This article therefore does not include a discussion on how a control developer would implement saving state. For an in-depth discussion on that issue, refer to the book Developing Microsoft ASP.NET Server Controls and Components. Before we can dive into our examination of view state, it is important that we first take a quick moment to discuss the ASP.NET page life cycle. That is, what exactly happens when a request comes in from a browser for an ASP.NET Web page? We'll step through this process in the next section.

The ASP.NET Page Life Cycle


Each time a request arrives at a Web server for an ASP.NET Web page, the first thing the Web server does is hand off the request to the ASP.NET engine. The ASP.NET engine then takes the request through a pipeline composed of numerous stages, which includes verifying file access rights for the ASP.NET Web page, resurrecting the user's session state, and so on. At the end of the pipeline, a class corresponding to the requested ASP.NET Web page is instantiated and the ProcessRequest() method is invoked (see Figure 1).

Figure 1. ASP.NET Page Handling

This life cycle of the ASP.NET page starts with a call to the ProcessRequest() method. This method begins by initializing the page's control hierarchy. Next, the page and its server controls proceed lock-step through various phases that are essential to executing an ASP.NET Web page. These steps include managing view state, handling postback events, and rendering the page's HTML markup. Figure 2 provides a graphical representation of the ASP.NET page life cycle. The life cycle ends by handing off the Web page's HTML markup to the Web server, which sends it back to the client that requested the page. Note A detailed discussion of the steps leading up to the ASP.NET page life cycle is beyond the scope of this article. For more information read Michele Leroux-Bustamante's Inside IIS & ASP.NET. For a more detailed look at HTTP handlers, which are the endpoints of the ASP.NET pipeline, check out my previous article on HTTP Handlers. What is important to realize is that each and every time an ASP.NET Web page is requested it goes through these same life cycle stages (shown in Figure 2).

Figure 2. Events in the Page Life Cycle

Stage 0 - Instantiation
The life cycle of the ASP.NET page begins with instantiation of the class that represents the requested ASP.NET Web page, but how is this class created? Where is it stored?

ASP.NET Web pages, as you know, are made up of both an HTML portion and a code portion, with the HTML portion containing HTML markup and Web control syntax. The ASP.NET engine converts the HTML portion from its free-form text representation into a series of programmatically-created Web controls. When an ASP.NET Web page is visited for the first time after a change has been made to the HTML markup or Web control syntax in the .aspx page, the ASP.NET engine autogenerates a class. If you created your ASP.NET Web page using the code-behind technique, this autogenerated class is derived from the page's associated code-behind class (note that the code-behind class must be derived itself, either directly or indirectly, from the System.Web.UI.Page class); if you created your page with an in-line, serverside <script> block, the class derives directly from System.Web.UI.Page. In either case, this autogenerated class, along with a compiled instance of the class, is stored in the WINDOWS\Microsoft.NET\Framework\version\Temporary ASP.NET Files folder, in part so that it doesn't need to be recreated for each page request. The purpose of this autogenerated class is to programmatically create the page's control hierarchy. That is, the class is responsible for programmatically creating the Web controls specified in the page's HTML portion. This is done by translating the Web control syntax<asp:WebControlName Prop1="Value1" ... />into the class's programming language (C# or Microsoft Visual Basic .NET, most typically). In addition to the Web control syntax being converted into the appropriate code, the HTML markup present in the ASP.NET Web page's HTML portion is translated to Literal controls. All ASP.NET server controls can have a parent control, along with a variable number of child controls. The System.Web.UI.Page class is derived from the base control class (System.Web.UI.Control), and therefore also can have a set of child controls. The toplevel controls declared in an ASP.NET Web page's HTML portion are the direct children of the autogenerated Page class. Web controls can also be nested inside one another. For example, most ASP.NET Web pages contain a single server-side Web Form, with multiple Web controls inside the Web Form. The Web Form is an HTML control (System.Web.UI.HtmlControls.HtmlForm). Those Web controls inside the Web Form are children of the Web Form. Since server controls can have children, and each of their children may have children, and so on, a control and its descendents form a tree of controls. This tree of controls is called the control hierarchy. The root of the control hierarchy for an ASP.NET Web page is the Page-derived class that is autogenerated by the ASP.NET engine. Whew! Those last few paragraphs may have been a bit confusing, as this is not the easiest subject to discuss or digest. To clear out any potential confusion, let's look at a quick example. Imagine you have an ASP.NET Web page with the following HTML portion: Copy
<html>

<body> <h1>Welcome to my Homepage!</h1> <form runat="server"> What is your name? <asp:TextBox runat="server" ID="txtName"></asp:TextBox> <br />What is your gender? <asp:DropDownList runat="server" ID="ddlGender"> <asp:ListItem Select="True" Value="M">Male</asp:ListItem> <asp:ListItem Value="F">Female</asp:ListItem> <asp:ListItem Value="U">Undecided</asp:ListItem> </asp:DropDownList> <br /> <asp:Button runat="server" Text="Submit!"></asp:Button> </form> </body> </html>

When this page is first visited, a class will be autogenerated that contains code to programmatically build up the control hierarchy. The control hierarchy for this example can be seen in Figure 3.

Figure 3. Control Hierarchy for sample page This control hierarchy is then converted to code that is similar to the following: Copy
Page.Controls.Add( new LiteralControl(@"<html>\r\n<body>\r\n <h1>Welcome to my Homepage!</h1>\r\n")); HtmlForm Form1 = new HtmlForm(); Form1.ID = "Form1"; Form1.Method = "post"; Form1.Controls.Add( new LiteralControl("\r\nWhat is your name?\r\n")); TextBox TextBox1 = new TextBox(); TextBox1.ID = "txtName";

Form1.Controls.Add(TextBox1); Form1.Controls.Add( new LiteralControl("\r\n<br />What is your gender?\r\n")); DropDownList DropDownList1 = new DropDownList(); DropDownList1.ID = "ddlGender"; ListItem ListItem1 = new ListItem(); ListItem1.Selected = true; ListItem1.Value = "M"; ListItem1.Text = "Male"; DropDownList1.Items.Add(ListItem1); ListItem ListItem2 = new ListItem(); ListItem2.Value = "F"; ListItem2.Text = "Female"; DropDownList1.Items.Add(ListItem2); ListItem ListItem3 = new ListItem(); ListItem3.Value = "U"; ListItem3.Text = "Undecided"; DropDownList1.Items.Add(ListItem3); Form1.Controls.Add( new LiteralControl("\r\n<br /> \r\n")); Button Button1 = new Button(); Button1.Text = "Submit!"; Form1.Controls.Add(Button1); Form1.Controls.Add( new LiteralControl("\r\n</body>\r\n</html>")); Controls.Add(Form1);

Note The C# source code above is not the precise code that is autogenerated by the ASP.NET engine. Rather, it's a cleaner and easier to read version of the autogenerated code. To see the full autogenerated codewhich won't win any points for readability navigate to the
WINDOWS\Microsoft.NET\Framework\Version\Temporary ASP.NET Files

folder and open one of the .cs or .vb files. One thing to notice is that, when the control hierarchy is constructed, the properties that are explicitly set in the declarative syntax of the Web control are assigned in the code. (For example, the Button Web control has its Text property set to "Submit!" in the declarative syntax Text="Submit!" as well as in the autogenerated class Button1.Text = "Submit!";.

Stage 1 - Initialization
After the control hierarchy has been built, the Page, along with all of the controls in its control hierarchy, enter the initialization stage. This stage is marked by having the Page and controls fire their Init events. At this point in the page life cycle, the control hierarchy has been constructed, and the Web control properties that are specified in the declarative syntax have been assigned.

We'll look at the initialization stage in more detail later in this article. With regards to view state it is important for two reasons; first, server controls don't begin tracking view state changes until right at the end of the initialization stage. Second, when adding dynamic controls that need to utilize view state, these controls will need to be added during the Page's Init event as opposed to the Load event, as we'll see shortly.

Stage 2 - Load View State


The load view state stage only happens when the page has been posted back. During this stage, the view state data that had been saved from the previous page visit is loaded and recursively populated into the control hierarchy of the Page. It is during this stage that the view state is validated. As we'll discuss later in this article, the view state can become invalid due to a number of reasons, such as view state tampering, and injecting dynamic controls into the middle of the control hierarchy.

Stage 3 - Load Postback Data


The load postback data stage also only happens when the page has been posted back. A server control can indicate that it is interested in examining the posted back data by implementing the IPostBackDataHandler interface. In this stage in the page life cycle, the Page class enumerates the posted back form fields, and searches for the corresponding server control. If it finds the control, it checks to see if the control implements the IPostBackDataHandler interface. If it does, it hands off the appropriate postback data to the server control by calling the control's LoadPostData() method. The server control would then update its state based on this postback data. To help clarify things, let's look at a simple example. One nice thing about ASP.NET is that the Web controls in a Web Form remember their values across postback. That is, if you have a TextBox Web control on a page and the user enters some value into the TextBox and posts back the page, the TextBox's Text property is automatically updated to the user's entered value. This happens because the TextBox Web control implements the IPostBackDataHandler interface, and the Page class hands off the appropriate value to the TextBox class, which then updates its Text property. To concretize things, imagine that we have an ASP.NET Web page with a TextBox whose ID property is set to txtName. When the page is first visited, the following HTML will be rendered for the TextBox: <input type="text" id="txtName" name="txtName" />. When the user enters a value into this TextBox (such as, "Hello, World!") and submits the form, the browser will make a request to the same ASP.NET Web page, passing the form field values back in the HTTP POST headers. These include the hidden form field values (such as __VIEWSTATE), along with the value from the txtName TextBox. When the ASP.NET Web page is posted back in the load postback data stage, the Page class sees that one of the posted back form fields corresponds to the IPostBackDataHandler interface. There is such a control in the hierarchy, so the

TextBox's LoadPostData() method is invoked, passing in the value the user entered into the TextBox ("Hello, World!"). The TextBox's LoadPostData() method simply assigns this passed in value to its Text property. Notice that in our discussion on the load postback data stage, there was no mention of view state. You might naturally be wondering, therefore, why I bothered to mention the load postback data stage in an article about view state. The reason is to note the absence of view state in this stage. It is a common misconception among developers that view state is somehow responsible for having TextBoxes, CheckBoxes, DropDownLists, and other Web controls remember their values across postback. This is not the case, as the values are identified via posted back form field values, and assigned in the LoadPostData() method for those controls that implement IPostBackDataHandler.

Stage 4 - Load
This is the stage with which all ASP.NET developers are familiar, as we've all created an event handler for a page's Load event (Page_Load). When the Load event fires, the view state has been loaded (from stage 2, Load View State), along with the postback data (from stage 3, Load Postback Data). If the page has been posted back, when the Load event fires we know that the page has been restored to its state from the previous page visit.

Stage 5 - Raise Postback Event


Certain server controls raise events with respect to changes that occurred between postbacks. For example, the DropDownList Web control has a SelectedIndexChanged event, which fires if the DropDownList's SelectedIndex has changed from the SelectedIndex value in the previous page load. Another example: if the Web Form was posted back due to a Button Web control being clicked, the Button's Click event is fired during this stage. There are two flavors of postback events. The first is a changed event. This event fires when some piece of data is changed between postbacks. An example is the DropDownLists SelectedIndexChanged event, or the TextBox's TextChanged event. Server controls that provide changed events must implement the IPostBackDataHandler interface. The other flavor of postback events is the raised event. These are events that are raised by the server control for whatever reason the control sees fit. For example, the Button Web control raises the Click event when it is clicked, and the Calendar control raises the VisibleMonthChanged event when the user moves to another month. Controls that fire raised events must implement the IPostBackEventHandler interface. Since this stage inspects postback data to determine if any events need to be raised, the stage only occurs when the page has been posted back. As with the load postback data stage, the raise postback event stage does not use view state information at all. Whether or not an event is raised depends on the data posted back in the form fields.

Stage 6 - Save View State


In the save view state stage, the Page class constructs the page's view state, which represents the state that must persist across postbacks. The page accomplishes this by recursively calling the SaveViewState() method of the controls in its control hierarchy. This combined, saved state is then serialized into a base-64 encoded string. In stage 7, when the page's Web Form is rendered, the view state is persisted in the page as a hidden form field.

Stage 7 - Render
In the render stage the HTML that is emitted to the client requesting the page is generated. The Page class accomplishes this by recursively invoking the RenderControl() method of each of the controls in its hierarchy. These seven stages are the most important stages with respect to understanding view state. (Note that I did omit a couple of stages, such as the PreRender and Unload stages.) As you continue through the article, keep in mind that every single time an ASP.NET Web page is requested, it proceeds through these series of stages.

The Role of View State


View state's purpose in life is simple: it's there to persist state across postbacks. (For an ASP.NET Web page, its state is the property values of the controls that make up its control hierarchy.) This begs the question, "What sort of state needs to be persisted?" To answer that question, let's start by looking at what state doesn't need to be persisted across postbacks. Recall that in the instantiation stage of the page life cycle, the control hierarchy is created and those properties that are specified in the declarative syntax are assigned. Since these declarative properties are automatically reassigned on each postback when the control hierarchy is constructed, there's no need to store these property values in the view state. For example, imagine we have a Label Web control in the HTML portion with the following declarative syntax: Copy
<asp:Label runat="server" Font-Name="Verdana" Text="Hello, World!"></asp:Label>

When the control hierarchy is built in the instantiation stage, the Label's Text property will be set to "Hello, World!" and its Font property will have its Name property set to Verdana. Since these properties will be set each and every page visit during the instantiation stage, there's no need to persist this information in the view state.

What needs to be stored in the view state is any programmatic changes to the page's state. For example, suppose that in addition to this Label Web control, the page also contained two Button Web controls, a Change Message Button and an Empty Postback button. The Change Message Button has a Click event handler that assigns the Label's Text property to "Goodbye, Everyone!"; the Empty Postback Button just causes a postback, but doesn't execute any code. The change to the Label's Text property in the Change Message Button would need to be saved in the view state. To see how and when this change would be made, let's walk through a quick example. Assuming that the HTML portion of the page contains the following markup: Copy
<asp:Label runat="server" ID="lblMessage" Font-Name="Verdana" Text="Hello, World!"></asp:Label> <br /> <asp:Button runat="server" Text="Change Message" ID="btnSubmit"></asp:Button> <br /> <asp:Button runat="server" Text="Empty Postback"></asp:Button>

And the code-behind class contains the following event handler for the Button's Click event: Copy
private void btnSubmit_Click(object sender, EventArgs e) { lblMessage.Text = "Goodbye, Everyone!"; }

Figure 4 illustrates the sequence of events that transpire, highlighting why the change to the Label's Text property needs to be stored in the view state.

Figure 4. Events and View State To understand why saving the Label's changed Text property in the view state is vital, consider what would happen if this information were not persisted in view state. That is, imagine that in step 2's save view state stage, no view state information was persisted. If this were the case, then in step 3 the Label's Text property would be assigned to "Hello, World!" in the instantiation stage, but would not be reassigned to "Goodbye, Everyone!" in the load view state stage. Therefore, from the end user's perspective, the Label's Text

property would be "Goodbye, Everyone!" in step 2, but would seemingly be reset to its original value ("Hello, World!") in step 3, after clicking the Empty Postback button.

View State and Dynamically Added Controls


Since all ASP.NET server controls contain a collection of child controls exposed through the Controls property, controls can be dynamically added to the control hierarchy by appending new controls to a server control's Controls collection. A thorough discussion of dynamic controls is a bit beyond the scope of this article, so we won't cover that topic in detail here; instead, we'll focus on how to manage view state for controls that are added dynamically. (For a more detailed lesson on using dynamic controls, check out Dynamic Controls in ASP.NET and Working with Dynamically Created Controls.) Recall that in the page life cycle, the control hierarchy is created and the declarative properties are set in the instantiation stage. Later, in the load view state stage, the state that had been altered in the prior page visit is restored. Thinking a bit about this, three things become clear when working with dynamic controls: 1. Since the view state only persists changed control state across postbacks, and not the actual controls themselves, dynamically added controls must be added to the ASP.NET Web page, on both the initial visit as well as all subsequent postbacks. 2. Dynamic controls are added to the control hierarchy in the code-behind class, and therefore are added at some point after the instantiation stage. 3. The view state for these dynamically added controls is automatically saved in the save view state stage. (What happens on postback if the dynamic controls have not yet been added by the time the load view state stage rolls, however?) So, dynamically added controls must be programmatically added to the Web page on each and every page visit. The best time to add these controls is during the initialization stage of the page life cycle, which occurs before the load view state stage. That is, we want to have the control hierarchy complete before the load view state stage arrives. For this reason, it is best to create an event handler for the Page class's Init event in your code-behind class, and add your dynamic controls there. Note You may be able to get away with loading your controls in the Page_Load event handler and maintaining the view state properly. It all depends on whether or not you are setting any properties of the dynamically loaded controls programmatically and, if so, when you're doing it relative to the
Controls.Add(dynamicControl)

line. A thorough discussion of this is a bit beyond the scope of this article, but the reason it may work is because the Controls property's Add()

method recursively loads the parent's view state into its children, even though the load view state stage has passed. When adding a dynamic control c to some parent control p based on some condition (that is, when not loading them on each and every page visit), you need to make sure that you add c to the end of p's Controls collection. The reason is because the view state for p contains the view state for p's children as well, and, as we'll discuss in the "Parsing the View State" section, p's view state specifies the view state for its children by index. (Figure 5 illustrates how inserting a dynamic control somewhere other than the end of the Controls collection can cause a corrupted view state.)

Figure 5. Effect of inserting controls on View State

The ViewState Property


Each control is responsible for storing its own state, which is accomplished by adding its changed state to its ViewState property. The ViewState property is defined in the System.Web.UI.Control class, meaning that all ASP.NET server controls have this property available. (When talking about view state in general I'll use lower case letters with a space between view and state; when discussing the ViewState property, I'll use the correct casing and code-formatted text.) If you examine the simple properties of any ASP.NET server control you'll see that the properties read and write directly to the view state. (You can view the decompiled source code for a .NET assembly by using a tool like Reflector.) For example, consider the HyperLink Web control's NavigateUrl property. The code for this property looks like so: Copy
public string NavigateUrl

{ get { string text = (string) ViewState["NavigateUrl"]; if (text != null) return text; else return string.Empty; } set { ViewState["NavigateUrl"] = value; } }

As this code sample illustrates, whenever a control's property is read, the control's ViewState is consulted. If there is not an entry in the ViewState, then the default value for the property is returned. When the property is assigned, the assigned value is written directly to the ViewState. Note All Web controls use the above pattern for simple properties. Simple properties are those that are scalar values, like strings, integers, Booleans, and so on. Complex properties, such as the Label's Font property, which might be classes themselves, use a different approach. Consult the book Developing Microsoft ASP.NET Server Controls and Components for more information on state maintenance techniques for ASP.NET server controls. The ViewState property is of type System.Web.UI.StateBag. The StateBag class provides a means to store name and value pairs, using a System.Collections.Specialized.HybridDictionary behind the scenes. As the NavigateUrl property syntax illustrates, items can be added to and queried from the StateBag using the same syntax you could use to access items from a Hashtable.

Timing the Tracking of View State


Recall that earlier I said the view state only stores state that needs to be persisted across postbacks. One bit of state that does not need to be persisted across postbacks is the control's properties specified in the declarative syntax, since they are automatically reinstated in the page's instantiation stage. For example, if we have a HyperLink Web control on an ASP.NET Web page and declaratively set the NavigateUrl property to http://www.ScottOnWriting.NET then this information doesn't need to be stored in the view state. Seeing the HyperLink control's NavigateUrl property's code, however, it looks as if the control's ViewState is written to whenever the property value is set. In the instantiation stage, therefore, where we'd have something like HyperLink1.NavigateUrl =

http://www.ScottOnWriting.NET;, it would only make sense that this information

would be stored in the view state. Regardless of what might seem apparent, this is not the case. The reason is because the StateBag class only tracks changes to its members after its TrackViewState() method has been invoked. That is, if you have a StateBag, any and all additions or modifications that are made before TrackViewState() is made will not be saved when the SaveViewState() method is invoked. The TrackViewState() method is called at the end of the initialization stage, which happens after the instantiation stage. Therefore, the initial property assignments in the instantiation stagewhile written to the ViewState in the properties' set accessorsare not persisted during the SaveViewState() method call in the save view state stage, because the TrackViewState() method has yet to be invoked. Note The reason the StateBag has the TrackViewState() method is to keep the view state as trimmed down as possible. Again, we don't want to store the initial property values in the view state, as they don't need to be persisted across postbacks. Therefore, the TrackViewState() method allows the state management to begin after the instantiation and initialization stages.

Storing Information in the Page's ViewState Property


Since the Page class is derived from the System.Web.UI.Control class, it too has a ViewState property. In fact, you can use this property to persist page-specific and userspecific information across postbacks. From an ASP.NET Web page's code-behind class, the syntax to use is simply: Copy
ViewState[keyName] = value

There are a number of scenarios when being able to store information in the Page's ViewState is useful. The canonical example is in creating a pageable, sortable DataGrid (or a sortable, editable DataGrid), since the sort expression must be persisted across postbacks. That is, if the DataGrid's data is first sorted, and then paged, when binding the next page of data to the DataGrid it is important that you get the next page of the data when it is sorted by the user's specified sort expression. The sort expression therefore needs to be persisted in some manner. There are assorted techniques, but the simplest, in my opinion, is to store the sort expression in the Page's ViewState. For more information on creating sortable, pageable DataGrids (or a pageable, sortable, editable DataGrid), pick up a copy of my book ASP.NET Data Web Controls Kick Start.

The Cost of View State


Nothing comes for free, and view state is no exception. The ASP.NET view state imposes two performance hits whenever an ASP.NET Web page is requested: 1. On all page visits, during the save view state stage the Page class gathers the collective view state for all of the controls in its control hierarchy and serializes the state to a base-64 encoded string. (This is the string that is emitted in the hidden __VIEWSTATE form filed.) Similarly, on postbacks, the load view state stage needs to deserialize the persisted view state data, and update the pertinent controls in the control hierarchy. 2. The __VIEWSTATE hidden form field adds extra size to the Web page that the client must download. For some view state-heavy pages, this can be tens of kilobytes of data, which can require several extra seconds (or minutes!) for modem users to download. Also, when posting back, the __VIEWSTATE form field must be sent back to the Web server in the HTTP POST headers, thereby increasing the postback request time. If you are designing a Web site that is commonly accessed by users coming over a modem connection, you should be particularly concerned with the bloat the view state might add to a page. Fortunately, there are a number of techniques that can be employed to reduce view state size. We'll first see how to selectively indicate whether or not a server control should save its view state. If a control's state does not need to be persisted across postbacks, we can turn off view state tracking for that control, thereby saving the extra bytes that would otherwise have been added by that control. Following that, we'll examine how to remove the view state from the page's hidden form fields altogether, storing the view state instead on the Web server's file system.

Disabling the View State


In the save view state stage of the ASP.NET page life cycle, the Page class recursively iterates through the controls in its control hierarchy, invoking each control's SaveViewState() method. This collective state is what is persisted to the hidden __VIEWSTATE form field. By default, all controls in the control hierarchy will record their view state when their SaveViewState() method is invoked. As a page developer, however, you can specify that a control should not save its view state or the view state of its children controls by setting the control's EnableViewState property to False (the default is True). The EnableViewState property is defined in the System.Web.UI.Control class, so all server controls have this property, including the Page class. You can therefore indicate that an entire page's view state need not be saved by setting the Page class's EnableViewState to False. (This can be done either in the code-behind class with Page.EnableViewState = false; or as a @Page-level directive<%@Page EnableViewState="False" %>.)

Not all Web controls record the same amount of information in their view state. The Label Web control, for example, records only programmatic changes to its properties, which won't greatly impact the size of the view state. The DataGrid, however, stores all of its contents in the view state. For a DataGrid with many columns and rows, the view state size can quickly add up! For example, the DataGrid shown in Figure 6 (and included in this article's code download as HeavyDataGrid.aspx) has a view state size of roughly 2.8 kilobytes, and a total page size of 5,791 bytes. (Almost half of the page's size is due to the __VIEWSTATE hidden form field!) Figure 7 shows a screenshot of the view state, which can be seen by visiting the ASP.NET Web page, doing a View\Source, and then locating the __VIEWSTATE hidden form field.

Figure 6. DataGrid control

Figure 7. View State for DataGrid control The download for this article also includes an ASP.NET Web page called LightDataGrid.aspx, which has the same DataGrid as shown in Figure 6, but with the EnableViewState property set to False. The total view state size for this page? 96 bytes. The entire page size clocks in a 3,014 bytes. LightDataGrid.aspx boasts a view state size about 1/30th the size of HeavyDataGrid.aspx, and a total download size that's about half of HeavyDataGrid.aspx. With wider DataGrids with more rows, this difference would be even more pronounced. (For more information on performance comparisons between view state-enabled DataGrids and view state-disabled DataGrids, refer to Deciding When to Use the DataGrid, DataList, or Repeater.) Hopefully the last paragraph convinces you of the benefit of intelligently setting the EnableViewState property to False, especially for "heavy" view state controls like the DataGrid. The question now, is, "When can I safely set the EnableViewState property to False?" To answer that question, consider when you need to use the view stateonly when you need to remember state across postbacks. The DataGrid stores its contents in the view state so the page developer doesn't need to rebind the database data to the DataGrid on each and every page load, but only on the first one. The benefit is that the database doesn't need to be accessed as often. If, however, you set a DataGrid's EnableViewState property to False, you'll need to rebind the database data to the DataGrid on both the first page load and every subsequent postback. For a Web page that has a read-only DataGrid, like the one in Figure 6, you'd definitely want to set the DataGrid's EnableViewState property to False. You can even create sortable and pageable DataGrids with the view state disabled (as can be witnessed in the LightDataGrid-WithFeatures.aspx page, included in the download), but, again, you'll

need to be certain to bind the database data to the DataGrid on the first page visit, as well as on all subsequent postbacks. Note Creating an editable DataGrid with disabled view state requires some intricate programming, which involves parsing of the posted back form fields in the editable DataGrid. Such strenuous effort is required because, with an editable DataGrid blindly rebinding, the database data to the DataGrid will overwrite any changes the user made (see this FAQ for more information).

Specifying Where to Persist the View State


After the page has collected the view state information for all of the controls in its control hierarchy in the save view state stage, it persists it to the __VIEWSTATE hidden form field. This hidden form field can, of course, greatly add to the overall size of the Web page. The view state is serialized to the hidden form field in the Page class's SavePageStateToPersistenceMedium() method during the save view state stage, and is deserialized by the Page class's LoadPageStateFromPersistenceMedium() method in the load view state stage. With just a bit of work we can have the view state persisted to the Web server's file system, rather than as a hidden form field weighing down the page. To accomplish this we'll need to create a class that derives from the Page class and overrides the SavePageStateToPersistenceMedium() and LoadPageStateFromPersistenceMedium() methods. Note There is a third-party product called Flesk.ViewStateOptimizer that reduces the view state bloat using a similar technique. The view state is serialized and deserialized by the System.Web.UI.LosFormatter classthe LOS stands for limited object serializationand is designed to efficiently serialize certain types of objects into a base-64 encoded string. The LosFormatter can serialize any type of object that can be serialized by the BinaryFormatter class, but is built to efficiently serialize objects of the following types:
y y y y y y y y

Strings Integers Booleans Arrays


ArrayLists Hashtables Pairs Triplets

Note The Pair and Triplet

are two classes found in the System.Web.UI namespace, and provide a single class to store either two or three objects. The Pair class has properties First and Second to access its two elements, while Triplet has First , Second , and Third as properties. The SavePageStateToPersistenceMedium() method is called from the Page class and passed in the combined view state of the page's control hierarchy. When overriding this method, we need to use the LosFormatter() to serialize the view state to a base-64 encoded string, and then store this string in a file on the Web server's file system. There are two main challenges with this approach: 1. Coming up with an acceptable file naming scheme. Since the view state for a page will likely vary based on the user's interactions with the page, the stored view state must be unique for each user and for each page. 2. Removing the view state files from the file system when they are no longer needed. To tackle the first challenge, we'll name the persisted view state file based on the user's SessionID and the page's URL. This approach will work beautifully for all users whose browsers accept session-level cookies. Those who do not accept cookies, however, will have a unique session ID generated for them on each page visit, thereby making this naming technique unworkable for them. For this article I'm just going to demonstrate using the SessionID / URL file name scheme, although it won't work for those whose browsers are configured not to accept cookies. Also, it won't work for a Web farm unless all servers store the view state files to a centralized location. Note One workaround would be to use a globally unique identifier (GUID) as the file name for the persisted view state, saving this GUID in a hidden form field on the ASP.NET Web page. This approach, unfortunately, would take quite a bit more effort than using the SessionID / URL scheme, since it involves injecting a hidden form field into the Web Form. For that reason, I'll stick to illustrating the simpler approach for this article.

The second challenge arises because, each time a user visits a different page, a new file holding that page's view state will be created. Over time this will lead to thousands of files. Some sort of automated task would be needed to periodically clean out the view state files older than a certain date. I leave this as an exercise for the reader. To persist view state information to a file, we start by creating a class that derives from the Page class. This derived class, then, needs to override the SavePageStateToPersistenceMedium() and LoadPageStateFromPersistenceMedium() methods. The following code presents such a class: Copy
public class PersistViewStateToFileSystem : Page { protected override void SavePageStateToPersistenceMedium(object viewState) { // serialize the view state into a base-64 encoded string LosFormatter los = new LosFormatter(); StringWriter writer = new StringWriter(); los.Serialize(writer, viewState); // save the string to disk StreamWriter sw = File.CreateText(ViewStateFilePath); sw.Write(writer.ToString()); sw.Close(); } protected override object LoadPageStateFromPersistenceMedium() { // determine the file to access if (!File.Exists(ViewStateFilePath)) return null; else { // open the file StreamReader sr = File.OpenText(ViewStateFilePath); string viewStateString = sr.ReadToEnd(); sr.Close(); // deserialize the string LosFormatter los = new LosFormatter(); return los.Deserialize(viewStateString); } } public string ViewStateFilePath { get { string folderName = Path.Combine(Request.PhysicalApplicationPath, "PersistedViewState"); string fileName = Session.SessionID + "-" + Path.GetFileNameWithoutExtension(Request.Path).Replace("/", "-") + ".vs"; return Path.Combine(folderName, fileName); }

} }

The class contains a public property ViewStateFilePath, which returns the physical path to the file where the particular view state information will be stored. This file path is dependent upon the user's SessionID and the URL of the requested page. Notice that the SavePageStateToPersistenceMedium() method accepts an object input parameter. This object is the view state object that is built up from the save view state stage. The job of SavePageStateToPersistenceMedium() is to serialize this object and persist it in some manner. The method's code simply creates an instance of the LosFormatter object and invokes its Serialize() method, serializing the passed-in view state information to the StringWriter writer. Following that, the specified file is created (or overwritten, if it already exists) with the contents of the base-64 encoded, serialized view state string. The LoadPageStateFromPersistenceMedium() method is called at the beginning of the load view state stage. Its job is to retrieve the persisted view state and deserialize back into an object that can be propagated into the page's control hierarchy. This is accomplished by opening the same file where the persisted view state was stored on the last visit, and returning the deserialized version via the Deserialize() method in LosFormatter(). Again, this approach won't work with users that do not accept cookies, but for those that do, the view state is persisted entirely on the Web server's file system, thereby adding 0 bytes to the overall page size! Note Another approach to reducing the bloat imposed by view state is to compress the serialized view state stream in the SavePageStateToPersistenceMedium() method, and then decompress it back to its original form in the LoadPageStateFromPersistenceMedium() method. Scott Galloway has a blog entry where he discusses his experiences with using #ziplib library to compress the view state.

Parsing the View State


When a page is rendered, it serializes its view state into a base-64 encoded string using the LosFormatter class and (by default) stores it in a hidden form field. On postback, the hidden form field is retrieved and deserialized back into the view state's object representation, which is then used to restore the state of the controls in the control hierarchy. One detail we have overlooked up to this point in the article is what, exactly, is the structure of the Page class's view state object?

As we discussed earlier, entire view state of the Page is the sum of the view state of the controls in its control hierarchy. Put another way, at any point in the control hierarchy, the view state of that control represents the view state of that control along with the view state of all of its children controls. Since the Page class forms the root of the control hierarchy, its view state represents the view state for the entire control hierarchy. The Page class contains a SavePageViewState(), which is invoked during the page life cycle's save view state stage. The SavePageViewState() method starts by creating a Triplet that contains the following three items: 1. The page's hash code. This hash code is used to ensure that the view state hasn't been tampered with between postbacks. We'll talk more about view state hashing in the "View State and Security Implications" section. 2. The collective view state of the Page's control hierarchy. 3. An ArrayList of controls in the control hierarchy that need to be explicitly invoked by the page class during the raise postback event stage of the life cycle. The First and Third items in the Triplet are relatively straightforward; the Second item is where the view state for the Page's control hierarchy is maintained. The Second item is generated by the Page by calling the SaveViewStateRecursive() method, which is defined in the System.Web.UI.Control class. SaveViewStateRecursive() saves the view state of the control and its descendents by returning a Triplet with the following information: 1. The state present in the Control's ViewState StageBag. 2. An ArrayList of integers. This ArrayList maintains the indexes of the Control's child controls that have a non-null view state. 3. An ArrayList of the view states for the children controls. The ith view state in this ArrayList maps to the child control index in the ith item in the ArrayList in the Triplet's Second item. The Control class computes the view state, returning a Triplet. The Second item of the Triplet contains the view state of the Control's descendents. The end result is that the view state is comprised of many ArrayLists inside of Triplets inside of Triplets, inside of Triplets, inside of... (The precise contents in the view state depend on the controls in the hierarchy. More complex controls might serialize their own state to the view state using Pairs or object arrays. As we'll see shortly, though, the view state is composed of a number of Triplets and ArrayLists nested as deep as the control hierarchy.)

Programmatically Stepping Through the View State


With just a little bit of work we can create a class that can parse through the view state and display its contents. The download for this article includes a class called ViewStateParser that provides such functionality. This class contains a

ParseViewState() method that recursively steps through the view state. It takes in three

inputs: 1. The current view state object. 2. How many levels deep we are in the view state recursion. 3. A text label to display. The last two input parameters are just for display purposes. The code of this method, shown below, determines the type of the current view state object and displays the contents of the view state accordingly, by recursively calling itself on each of the current object's members. (The variable tw is a TextWriter instance to which the output is being written.) Copy
protected virtual void ParseViewStateGraph( object node, int depth, string label) { tw.Write(System.Environment.NewLine); if (node == null) { tw.Write(String.Concat(Indent(depth), label, "NODE IS NULL")); } else if (node is Triplet) { tw.Write(String.Concat(Indent(depth), label, "TRIPLET")); ParseViewStateGraph( ((Triplet) node).First, depth+1, "First: "); ParseViewStateGraph( ((Triplet) node).Second, depth+1, "Second: "); ParseViewStateGraph( ((Triplet) node).Third, depth+1, "Third: "); } else if (node is Pair) { tw.Write(String.Concat(Indent(depth), label, "PAIR")); ParseViewStateGraph(((Pair) node).First, depth+1, "First: "); ParseViewStateGraph(((Pair) node).Second, depth+1, "Second: "); } else if (node is ArrayList) { tw.Write(String.Concat(Indent(depth), label, "ARRAYLIST")); // display array values for (int i = 0; i < ((ArrayList) node).Count; i++) ParseViewStateGraph( ((ArrayList) node)[i], depth+1, String.Format("({0}) ", i)); } else if (node.GetType().IsArray) { tw.Write(String.Concat(Indent(depth), label, "ARRAY ")); tw.Write(String.Concat("(", node.GetType().ToString(), ")")); IEnumerator e = ((Array) node).GetEnumerator(); int count = 0; while (e.MoveNext()) ParseViewStateGraph(

e.Current, depth+1, String.Format("({0}) ", count++)); } else if (node.GetType().IsPrimitive || node is string) { tw.Write(String.Concat(Indent(depth), label)); tw.Write(node.ToString() + " (" + node.GetType().ToString() + ")"); } else { tw.Write(String.Concat(Indent(depth), label, "OTHER - ")); tw.Write(node.GetType().ToString()); } }

As the code shows, the ParseViewState() method iterates through the expected types Triplet, Pair, ArrayList, arrays, and primitive types. For scalar valuesintegers, strings, etc.the type and value are displayed; for aggregate typesarrays, Pairs, Triplets, etc.the members that compose the type are displayed by recursively invoking ParseViewState(). The ViewStateParser class can be utilized from an ASP.NET Web page (see the ParseViewState.aspx demo), or can be accessed directly from the SavePageStateToPersistenceMedium() method in a class that is derived from the Page class (see the ShowViewState class). Figures 8 and9 show the ParseViewState.aspx demo in action. As Figure 8 shows, the user is presented with a multi-line textbox into which they can paste the hidden __VIEWSTATE form field from some Web page. Figure 9 shows a snippet of the parsed view state for a page displaying file system information in a DataGrid.

Figure 8. Decoding ViewState

Figure 9. ViewState decoded In addition to the view state parser provided in this article's download, Paul Wilson provides a view state parser on his Web site. Fritz Onion also has a view state decoder WinForms application available for download from the Resources section on his Web site.

View State and Security Implications


The view state for an ASP.NET Web page is stored, by default, as a base-64 encoded string. As we saw in the previous section, this string can easily be decoded and parsed, displaying the contents of the view state for all to see. This raises two security-related concerns:

1. Since the view state can be parsed, what's to stop someone from changing the values, re-serializing it, and using the modified view state? 2. Since the view state can be parsed, does that mean I can't place any sensitive information in the view state (such as passwords, connection strings, etc.)? Fortunately, the LosFormatter class has capabilities to address both of these concerns, as we'll see over the next two sections. Before we delve into the solutions for these concerns, it is important to first note that view state should only be used to store nonsensitive data. View state does not house code, and should definitely not be used to place sensitive information like connection strings or passwords.

Protecting the View State from Modification


Even though view state should only store the state of the Web controls on the page and other non-sensitive data, nefarious users could cause you headaches if they could successfully modify the view state for a page. For example, imagine that you ran an eCommerce Web site that used a DataGrid to display a list of products for sale along with their cost. Unless you set the DataGrid's EnableViewState property to False, the DataGrid's contentsthe names and prices of your merchandisewill be persisted in the view state. Nefarious users could parse the view state, modify the prices so they all read $0.01, and then deserialize the view state back to a base-64 encoded string. They could then send out e-mail messages or post links that, when clicked, submitted a form that sent the user to your product listing page, passing along the altered view state in the HTTP POST headers. Your page would read the view state and display the DataGrid data based on this view state. The end result? You'd have a lot of customers thinking they were going to be able to buy your products for only a penny! A simple means to protect against this sort of tampering is to use a machine authentication check, or MAC. Machine authentication checks are designed to ensure that the data received by a computer is the same data that it transmitted outnamely, that it hasn't been tampered with. This is precisely what we want to do with the view state. With ASP.NET view state, the LosFormatter performs a MAC by hashing the view state data being serialized, and appending this hash to the end of the view state. (A hash is a quickly computed digest that is commonly used in symmetric security scenarios to ensure message integrity.) When the Web page is posted back, the LosFormatter checks to ensure that the appended hash matches up with the hashed value of the deserialized view state. If it does not match up, the view state has been changed en route. By default, the LosFormatter class applies the MAC. You can, however, customize whether or not the MAC occurs by setting the Page class's EnableViewStateMac property. The default, True, indicates that the MAC should take place; a value of False indicates that it should not. You can further customize the MAC by specifying what hashing algorithm should be employed. In the machine.config file, search for the <machineKey> element's validation attribute. The default hashing algorithm used is

SHA1, but you can change it to MD5 if you like. (For more information on the SHA1, see RFC 3174; for more information on MD5, read RFC 1321.) Note When using Server.Transfer() you may find you receive a problem with view state authentication. A number of articles online have mentioned that the only workaround is to set EnableViewStateMac to False. While this will certainly solve the problem, it opens up a security hole. For more information, including a secure workaround, consult this KB article.

Encrypting the View State


Ideally the view state should not need to be encrypted, as it should never contain sensitive information. If needed, however, the LosFormatter does provide limited encryption support. The LosFormatter only allows for a single type of encryption: Triple DES. To indicate that the view state should be encrypted, set the <machineKey> element's validation attribute in the machine.config file to 3DES. In addition to the validation attribute, the <machineKey> element contains validationKey and decryptionKey attributes, as well. The validationKey attribute specifies the key used for the MAC; decryptionKey indicates the key used in the Triple DES encryption. By default, these attributes are set to the value "AutoGenerate,IsolateApp," which uniquely autogenerates the keys for each Web application on the server. This setting works well for a single Web server environment, but if you have a Web farm, it's vital that all Web servers use the same keys for MAC and/or encryption and decryption. In this case you'll need to manually enter a shared key among the servers in the Web farm. For more information on this process, and the <machineKey> element in general, refer to the <machineKey> technical documentation and Susan Warren's article Taking a Bite Out of ASP.NET ViewState.

The ViewStateUserKey Property


Microsoft ASP.NET version 1.1 added an additional Page class property ViewStateUserKey. This property, if used, must be assigned a string value in the initialization stage of the page life cycle (in the Page_Init event handler). The point of the property is to assign some user-specific key to the view state, such as a username. The ViewStateUserKey, if provided, is used as a salt to the hash during the MAC. What the ViewStateUserKey property protects against is the case where a nefarious user visits a page, gathers the view state, and then entices a user to visit the same page, passing in their view state (see Figure 10). For more information on this property and its application, refer to Building Secure ASP.NET Pages and Controls.

Figure 10. Protecting against attacks using ViewStateUserKey

Conclusion
In this article we examined the ASP.NET view state, studying not only its purpose, but also its functionality. To best understand how view state works, it is important to have a firm grasp on the ASP.NET page life cycle, which includes stages for loading and saving the view state. In our discussions on the page life cycle, we saw that certain stagessuch as loading postback data and raising postback eventswere not in any way related to view state. While view state enables state to be effortlessly persisted across postbacks, it comes at a cost, and that cost is page bloat. Since the view state data is persisted to a hidden form field, view state can easily add tens of kilobytes of data to a Web page, thereby increasing both the download and upload times for Web pages. To cut back on the page weight imposed by view state, you can selectively instruct various Web controls not to record their view state by setting the EnableViewState property to False. In fact, view state can be turned off for an entire page by setting the EnableViewState property to false in the @Page directive. In addition to turning off view state at the page-level or control-level, you can also specify an alternate backing store for view state, such as the Web server's file system. This article wrapped up with a look at security concerns with view state. By default, the view state performs a MAC to ensure that the view state hasn't been tampered with between postbacks. ASP.NET 1.1 provides the ViewStateUserKey property to add an additional level of security. The view state's data can be encrypted using the Triple DES encryption algorithm, as well. Happy Programming!

Works Consulted
There are a number of good resources for learning more about ASP.NET view state. Paul Wilson has provided a number of resources, such as View State: All You Wanted to Know, and the Page View State Parser. Dino Esposito authored an article for MSDN Magazine in February, 2003, titled The ASP.NET View State, which discusses a technique for storing view state on the Web server's file system. Taking a Bite Out of ASP.NET View State, written by Susan Warren, provides a good high-level overview of the view state, including a discussion on encrypting the view state. Scott Galloway's blog has some good posts on working with ASP.NET view state, too.

Special Thanks To...


Before submitting my article to my MSDN editor I have a handful of volunteers help proofread the article and provide feedback on the article's content, grammar, and direction. Primary contributors to the review process for this article include James Avery, Bernard Vander Beken, Dave Donaldson, Scott Elkin, and Justin Lovell. If you are

interested in joining the ever-growing list of reviewers, drop me a line at mitchell@4guysfromrolla.com.

About the Author


Scott Mitchell, author of five books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies for the past five years. Scott works as an independent consultant, trainer, and writer. He can be reached at mitchell@4guysfromrolla.com or via his blog, which can be found at http://ScottOnWriting.NET.

Related Books
y y y y

ASP. NET: Tips, Tutorials, & Code Microsoft ASP.NET Coding Strategies with the Microsoft ASP.NET Team ASP.NET Unleashed Programming Microsoft ASP.NET

2011 Microsoft. All rights reserved.

Terms of Use | Trademarks | Privacy Statement | Feedback

ASP.NET Web Services


Introduction
We can now use ASP.NET to create Web Service that is based on industrial standards included XML, SOAP and WSDL. ASP.NET Web Services support clients using HTTP-POST, HTTP-GET and SOAP protocols to invoke methods exposed, depends on your specific requirement you choose one method over the others. The main difference between HTTP-GET or HTTP-POST and SOAP is the data types supported by SOAP is much richer because SOAP used XSD schema to represent complex data types. Here are samples codes I use to test the building of ASP.NET Web Service:

Step 1: Create the ASP.NET Web Service Source File


ASP.NET Web Service file name has extension asmx and my file is named MyWebService.asmx, source is listed as follows:

File: MyWebService.asmx
Collapse
<%@ WebService Language="C#" class="MyClass" %> using System.Web.Services ;

public class MyClass { [WebMethod()] public int Add ( int a, { return a + b ; } }

int

b)

The page directive WebService is required and class is the name of the .NET Class to expose the Web Service, each method exposes as Web Service Class Method need to have a declarative attribute statement [WebMethod()] in front of it. Here the .NET Class implementation is included in the same file with ASP.NET Web Service file but it is not mandatory and we can choose to include an external .NET Assembly to implement the service as the following example:

File: MyWebService2.asmx
Collapse
<%@ WebService Language="C#" MyWebServiceImpl" %> class="MyWebService.MyStringReverse,

The file MyWebService2.asmx is referencing another .NET Assembly MyWebServiceImpl which is located under the /bin ASP.NET Application sub-folder (note that the default location for Assemblies in ASP.NET is /bin sub-folder under each ASP.NET Applications). The source of .NET Assembly MyWebServiceImpl is written by C# and is listed as follows:

File: MyWebServiceImpl.cs
Collapse
namespace MyWebService { using System ; using System.Web.Services ; public class MyStringReverse: WebService { [WebMethod(Description="Reverse String")] public String ReverseString ( String InString ) { // Check null String if ( InString == null ) return null ;

Int32 intSize = InString.Length ; char[] arrayInString = InString.ToCharArray() ; char[] arrayOutString = new char[intSize] ; for (Int32 i = 0 ; i < intSize ; ++i) arrayOutString[i] = arrayInString[intSize-i-1] ; return new String(arrayOutString) ; } } }

To create the Assembly, you can use the following command: Collapse
C:\>CSC /t:library MyWebServiceImpl.cs /out:bin/MyWebServiceImpl.dll

The following sections I will continue use MyWebService.asmx as my experimental Web Service.

Step 2: Create the ASP.NET Web Service Clients


There are many ways to consume Web Services and have three examples. The first one uses HTTP-POST protocol and it has advantage to coexist with todays application quite well and use HTTP-GET is similar and I let reader to try it. The second one uses SOAP Proxy Client Object generated by WSDL utility and it provides programmers with their familiar object modal that they call methods provided by the generated Proxy Interface. The final one uses SOAP standard request message and it parses SOAP response message with the help of XMLHTTP COM object that is installed by Microsoft XML Parser 3.0.

Client use HTTP-POST Method


The example is an ASP.NET page TestWebService.aspx and source listing as follows:

File: TestWebService.aspx
Collapse
<html> <body> <form action="http://localhost/ASP.NET/MyWebService.asmx/Add" method="POST"> <input name="a"></input> <input name="b"></input> <input type="submit" value="Enter"> </input> </form>

</body> </html>

The ASP page accepts parameters from browser and calls the Add method of the Web Service MyWebService via the HTTP-POST protocol, the result will be XML message and need further parsing by the client application. To parse the response, client can use either Java XML parser in applet or use IE5s DOM Object. The following is an example of XML response when parameters a=1, b=2 are inputted: Collapse
<?xml version="1.0" encoding="utf-8" ?> <int xmlns="http://tempuri.org/">3</int>

Client use WSDL Generated Proxy Object


If your client will be Windows applications or ASP.NET applications, you can use WSDL.EXE utility to created standard .NET Assemble to provide Proxy Class for your clients. Here are steps you can follow and try: Use WSDL.EXE utility to create the Proxy Class source file in any language you have chosen and here I use C# and command as follows: Collapse
C:\>wsdl /language:C# /out:MyProxyClass.cs http://localhost/ASP.NET/MyWebService.asmx

MyProxyClass.cs is generated and source listing as follows:

File: MyProxyClass.cs
Collapse
//----------------------------------------------------------------------------// <autogenerated> // This code was generated by a tool. // Runtime Version: 1.0.2914.16 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </autogenerated> //----------------------------------------------------------------------------// // This source code was auto-generated by wsdl, Version=1.0.2914.16.

// using using using using using

System.Diagnostics; System.Xml.Serialization; System; System.Web.Services.Protocols; System.Web.Services;

[System.Web.Services.WebServiceBindingAttribute(Name="MyClassSoap", Namespace="http://tempuri.org/")] public class MyClass : System.Web.Services.Protocols.SoapHttpClientProtocol { [System.Diagnostics.DebuggerStepThroughAttribute()] public MyClass() { this.Url = "http://localhost/ASP.NET/MyWebService.asmx"; } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://temp uri.org/Add", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped )] public int Add(int a, int b) { object[] results = this.Invoke("Add", new object[] { a, b}); return ((int)(results[0])); } [System.Diagnostics.DebuggerStepThroughAttribute()] public System.IAsyncResult BeginAdd(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Add", new object[] { a, b}, callback, asyncState); } [System.Diagnostics.DebuggerStepThroughAttribute()] public int EndAdd(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } }

Then we need to create the .NET Assembly for used by clients: Collapse
C:\> csc /t:library MyProxyClass.cs

The above command will compile the source and create MyProxyClass.dll library file.

I use ASP to depict how to use the proxy object and the file is TestWebServiceWithProxy.aspx source listing as follows:

File: TestWebServiceWithProxy.aspx
Collapse
<%@ page language="C#" %> <html> <script runat="server"> void btn_click(Object source, EventArgs e) { MyClass mycls = new MyClass() ; int x = Int32.Parse(a.Text) ; int y = Int32.Parse(b.Text); Message.Text = mycls.Add( x, y).ToString() ; } </script> <body> <form Action = "TestWebServiceWithProxy.aspx" runat="server"> <asp:TextBox id="a" runat="server" /> <asp:TextBox id="b" runat="server" /> <asp:button id=btn OnClick="btn_click" Text="Enter" runat="server" /> <p><asp:label id="Message" runat="server" /></P> </form> </body> </html>

Client use XMLHTTP to call Web service via SOAP


To fully explore the SOAP capability, you may choose to call your ASP.NET Web Service via SOAP core protocol and here I provide another example for reference. To test the ASP.NET service with SOAP protocol, I create an ASP client file TestWebServiceByXML.asp and its source is listed as follows:

File: TestWebServiceByXML.asp
Collapse
<html> <body> <script language="jscript"> function btn_click (a, b) { var xmlObj = new ActiveXObject("Msxml2.DOMDocument") ; var sXml = "<?xml version=\"1.0\" ?>" ; sXml += "<soap:Envelope " sXml += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " ;

sXml += "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " ; sXml += "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" ; sXml += "<soap:Body>" ; sXml += "<Add xmlns=\"http://tempuri.org/\">" ; sXml = sXml + "<a>" + a.value + "</a>" ; sXml = sXml + "<b>" + b.value + "</b>" ; sXml += "</Add></soap:Body></soap:Envelope>" // Try to parse the XML string into DOM object xmlObj.loadXML(sXml) ; //To see the validated XML string is well-formed XmlRequest.innerText = xmlObj.xml ; var xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP") ; xmlHTTP.Open ( "Post", "http://localhost/ASP.NET/MyWebService.asmx", false) ; xmlHTTP.setRequestHeader("SOAPAction", "http://tempuri.org/Add") ; xmlHTTP.setRequestHeader("Content-Type", "text/xml; charset=utf-8" ) ; xmlHTTP.Send(xmlObj.xml) ; MyResult.innerText = xmlHTTP.responseText ; var xmlResponse = xmlHTTP.responseXML ; answer.innerText = xmlResponse.selectSingleNode("soap:Envelope/soap:Body/AddResponse/AddRe sult").text ; } </script> <form> <p>Please input a:<input id="a" name="a"></input></p> <p>Please input b:<input id="b" name="b"></input></p> <p> <input type="button" id="btn" value="Enter" onclick="jscript:btn_click(a, b)"></input> </p> <p>Answer is <span id="answer"></span></p> <hr></hr> <p>Request:</p> <span id="XmlRequest"></span> <p>Response:</p> <span id="MyResult"></span> </form> </body> </html>

Here I installed Microsoft XML Parser 3.0 in my client machine that give me the XMLHTTP and DOM COM objects to test my application.

Webservices http://msdn.microsoft.com/enus/library/t745kdsh.aspx
.NET Framework 4 Other Versions

y y

Visual Studio 2008 Visual Studio 2005

Web services are components on a Web server that a client application can call by making HTTP requests across the Web. ASP.NET enables you to create custom Web services or to use built-in application services, and to call these services from any client application. We suggest the following progression of documentation to help you navigate through the related topics.
y

Introduction to Programming Web Services in Managed Code Describes the XML Web services programming model in managed code.

XML Web Services Using ASP.NET Provides links to information about how to create XML Web services in ASP.NET, and about how they work.

Getting started
y

Creating WCF Services for ASP.NET AJAX Describes Windows Communication Foundation (WCF) services that are hosted as ASP.NET compatible services.

Web References in Visual Studio Provides information about how to reference Web services in

Visual Studio projects and about the proxy classes that represent a Web service. Walkthrough: Creating and Using an ASP.NET Web Service in Visual Web Developer Provides a step-by-step tutorial on how to create an ASP.NET Web service and how to call it.

Creating and using Web services

How to: Add and Remove Web References Describes how to use tools in Visual Studio to create a proxy class for a Web service.

How to: Call a Web Service Describes how to call Web service methods. Using Web Services in ASP.NET AJAX Describes ASP.NET Web services, which are ASP.NET and Windows Communication Foundation (WCF) custom services that are called from client script that runs in AJAX-enabled ASP.NET Web pages.

Walkthrough: Creating and AJAX-enabled Web Service Shows how to create an AJAX-enabled Web service in Visual Studio and how to create a Web page that calls the Web service by using client script.

Creating and using Web services in AJAX

Exposing Web Services to Client Script Shows how to make a Web service available to client script that runs in the browser.

Exposing WCF Services to Client Script Shows how to make a WCF service available to client script that runs in the browser.

Calling Web Services from Client Script Shows how to use AJAX functionality in ASP.NET to call a Web service from client script that runs in the browser. Using Forms Authentication with Microsoft Ajax

Using application services in AJAX

Shows how to call the application authentication service from client script that runs in the browser.
y

Using Roles Information with Microsoft Ajax Shows how to call the application role service from client script that runs in the browser.

Using Profile Information with Microsoft Ajax Shows how to call the application profile service from client script that runs in the browser. ASP.NET Application Services Overview Describes ASP.NET and Windows Communication Foundation (WCF) application services, which provide a consistent way to provide authentication, roles, and profile properties to any client in order to build service-oriented applications.

How to: Enable the WCF Authentication Service. Shows how to use the application authentication service as a Windows Communication Foundation (WCF) service.

Using application services as WCF services

How to: Enable the WCF Role Service. Shows how to use the application role service as a Windows Communication Foundation (WCF) service.

How to: Enable the WCF Profile Service. Shows how to use the application profile service as a Windows Communication Foundation (WCF) service.

Walkthrough: Using ASP.NET Application Services. Shows how to use the application services in a Windows application.

See Also

Other Resources Web Services in ASP.NET AJAX Community Content Add FAQ

2011 Microsoft. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Feedback

State Management Techniques in ASP.NET This article discusses various options for state management for web applications developed using ASP.NET. Generally, web applications are based on stateless HTTP protocol which does not retain any information about user requests. In typical client and server communication using HTTP protocol, page is created each time the page is requested. Developer is forced to implement various state management techniques when developing applications which provide customized content and which "remembers" the user. Here we are here with various options for ASP.NET developer to implement state management techniques in their applications. Broadly, we can classify state management techniques as client side state management or server side state management. Each technique has its own pros and cons. Let's start with exploring client side state management options. Client side State management Options: ASP.NET provides various client side state management options like Cookies, QueryStrings (URL), Hidden fields, View State and Control state (ASP.NET 2.0). Let's discuss each of client side state management options. Bandwidth should be considered while implementing client side state management options because they involve in each roundtrip to server. Example: Cookies are exchanged between client and server for each page request. Cookie: A cookie is a small piece of text stored on user's computer. Usually, information is stored as name-value pairs. Cookies are used by websites to keep track of visitors. Every time a user visits a website, cookies are retrieved from user machine and help identify the user. Let's see an example which makes use of cookies to customize web page. if (Request.Cookies["UserId"] != null) lbMessage.text = "Dear" + Request.Cookies["UserId"].Value + ", Welcome to our website!"; else lbMessage.text = "Guest,welcome to our website!";

If you want to store client's information use the below code Response.Cookies["UserId"].Value=username; Advantages: y Simplicity

Disadvantages: y y y Cookies can be disabled on user browsers Cookies are transmitted for each HTTP request/response causing overhead on bandwidth Inappropriate for sensitive data

Hidden fields: Hidden fields are used to store data at the page level. As its name says, these fields are not rendered by the browser. It's just like a standard control for which you can set its properties. Whenever a page is submitted to server, hidden fields values are also posted to server along with other controls on the page. Now that all the asp.net web controls have built in state management in the form of view state and new feature in asp.net 2.0 control state, hidden fields functionality seems to be redundant. We can still use it to store insignificant data. We can use hidden fields in ASP.NET pages using following syntax protected System.Web.UI.HtmlControls.HtmlInputHidden Hidden1; //to assign a value to Hidden field Hidden1.Value="Create hidden fields"; //to retrieve a value string str=Hidden1.Value; Advantages: y y Simple to implement for a page specific data Can store small amount of data so they take less size.

Disadvantages: y y Inappropriate for sensitive data Hidden field values can be intercepted(clearly visible) when passed over a network

View State: View State can be used to store state information for a single user. View State is a built in feature in web controls to persist data between page post backs. You can set View State on/off for each control using EnableViewState property. By default, EnableViewState property will be set to true. View state mechanism poses performance overhead. View state information of all the controls on the page will be

submitted to server on each post back. To reduce performance penalty, disable View State for all the controls for which you don't need state. (Data grid usually doesn't need to maintain state). You can also disable View State for the entire page by adding EnableViewState=false to @page directive. View state data is encoded as binary Base64 - encoded which add approximately 30% overhead. Care must be taken to ensure view state for a page is smaller in size. View State can be used using following syntax in an ASP.NET web page. // Add item to ViewState ViewState["myviewstate"] = myValue; //Reading items from ViewState Response.Write(ViewState["myviewstate"]); Advantages: y y y Simple for page level data Encrypted Can be set at the control level

Disadvantages: y y Overhead in encoding View State values Makes a page heavy

Query strings: Query strings are usually used to send information from one page to another page. They are passed along with URL in clear text. Now that cross page posting feature is back in asp.net 2.0, Query strings seem to be redundant. Most browsers impose a limit of 255 characters on URL length. We can only pass smaller amounts of data using query strings. Since Query strings are sent in clear text, we can also encrypt query values. Also, keep in mind that characters that are not valid in a URL must be encoded using Server.UrlEncode. Let's assume that we have a Data Grid with a list of products, and a hyperlink in the grid that goes to a product detail page, it would be an ideal use of the Query String to include the product ID in the Query String of the link to the product details page (for example, productdetails.aspx?productid=4). When product details page is being requested, the product information can be obtained by using the following codes: string productid; productid=Request.Params["productid"]; Advantages: y Simple to Implement

Disadvantages: y y y y Human Readable Client browser limit on URL length Cross paging functionality makes it redundant Easily modified by end user

Control State: Control State is new mechanism in ASP.NET 2.0 which addresses some of the shortcomings of View State. Control state can be used to store critical, private information across post backs. Control state is another type of state container reserved for controls to maintain their core behavioral functionality whereas View State only contains state to maintain control's contents (UI). Control State shares same memory data structures with View State. Control State can be propagated even though the View State for the control is disabled. For example, new control Grid View in ASP.NET 2.0 makes effective use of control state to maintain the state needed for its core behavior across post backs. Grid View is in no way affected when we disable View State for the Grid View or entire page Server Side State management: As name implies, state information will be maintained on the server. Application, Session, Cache and Database are different mechanisms for storing state on the server. Care must be taken to conserve server resources. For a high traffic web site with large number of concurrent users, usage of sessions object for state management can create load on server causing performance degradation Application object: Application object is used to store data which is visible across entire application and shared across multiple user sessions. Data which needs to be persisted for entire life of application should be stored in application object. In classic ASP, application object is used to store connection strings. It's a great place to store data which changes infrequently. We should write to application variable only in application_Onstart event (global.asax) or application.lock event to avoid data conflicts. Below code sample gives idea Application.Lock(); Application["mydata"]="mydata"; Application.UnLock(); Session object: Session object is used to store state specific information per client basis. It is specific to particular user. Session data persists for the duration of user session you can store session's data on web server in different ways. Session state can be configured

using the <session State> section in the application's web.config file. Configuration information: <sessionState mode = <"inproc" | "sqlserver" | "stateserver"> cookieless = <"true" | "false"> timeout = <positive integer indicating the session timeout in minutes> sqlconnectionstring = <SQL connection string that is only used in the SQLServer mode> server = <The server name that is only required when the mode is State Server> port = <The port number that is only required when the mode is State Server> Mode: This setting supports three options. They are InProc, SQLServer, and State Server Cookie less: This setting takes a Boolean value of either true or false to indicate whether the Session is a cookie less one. Timeout: This indicates the Session timeout vale in minutes. This is the duration for which a user's session is active. Note that the session timeout is a sliding value; Default session timeout value is 20 minutes SqlConnectionString: This identifies the database connection string that names the database used for mode SQLServer. Server: In the out-of-process mode State Server, it names the server that is running the required Windows NT service: aspnet_state. Port: This identifies the port number that corresponds to the server setting for mode State Server. Note that a port is an unsigned integer that uniquely identifies a process running over a network. You can disable session for a page using EnableSessionState attribute. You can set off session for entire application by setting mode=off in web.config file to reduce overhead for the entire application. Session state in ASP.NET can be configured in different ways based on various parameters including scalability, maintainability and availability y In process mode (in-memory)- State information is stored in memory of web

y y

server Out-of-process mode- session state is held in a process called aspnet_state.exe that runs as a windows service. Database mode session state is maintained on a SQL Server database.

In process mode: This mode is useful for small applications which can be hosted on a single server. This model is most common and default method to store session specific information. Session data is stored in memory of local web server Configuration information: <sessionState mode="Inproc" sqlConnectionString="data source=server;user id=freelance;password=freelance" cookieless="false" timeout="20" /> Advantages: y y Fastest mode Simple configuration

Disadvantages: y y Session data will be lost if the worker process or application domain recycles Not ideal for web gardens and web farms

Out-of-process Session mode (state server mode): This mode is ideal for scalable and highly available applications. Session state is held in a process called aspnet_state.exe that runs as a windows service which listens on TCP port 42424 by default. You can invoke state service using services MMC snap-in or by running following net command from command line. Net start aspnet_state Configuration information: <sessionState mode="StateServer" StateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;user id=freelance; password=freelance" cookieless="false" timeout="20"/> Advantages: y y Supports web farm and web garden configuration Session data is persisted across application domain recycles. This is achieved by using separate worker process for maintaining state

Disadvantages: y y Out-of-process mode provides slower access compared to In process Requires serializing data

SQL-Backed Session state: ASP.NET sessions can also be stored in a SQL Server database. Storing sessions in SQL Server offers resilience that can serve sessions to a large web farm that persists across IIS restarts. SQL based Session state is configured with aspnet_regsql.exe. This utility is located in .NET Framework's installed directory C:\<windows>\microsoft.net\framework\<version>. Running this utility will create a database which will manage the session state. Configuration Information: <sessionState mode="SQLServer" sqlConnectionString="data source=server;user id=freelance;password=freelance" cookieless="false" timeout="20" /> Advantages: y y Supports web farm and web garden configuration Session state is persisted across application domain recycles and even IIS restarts when session is maintained on different server.

Disadvantages: y Requires serialization of objects

Choosing between client side and Server side management techniques is driven by various factors including available server resources, scalability and performance. We have to leverage both client side and server side state management options to build scalable applications. When leveraging client side state options, ensure that little amount of insignificant information is exchanged between page requests. Various parameters should be evaluated when leveraging server side state options including size of application, reliability and robustness. Smaller the application, In process is the better choice. We should account in the overheads involved in serializing and deserializing objects when using State Server and Database based session state. Application state should be used religiously.

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.

Login to add your contents and source code to this article

About the author

Looking for C# Consulting? C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models. Click here to learn more about C# Consulting.

Santhosh Babu

Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP. Finally a virtual platform that delivers next-generation Windows Server 2008 HyperV virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology. Dynamic PDF ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. SQL and .NET performance profiling in one place Investigate SQL and .NET code side-by-side with ANTS Performance Profiler 6, so you can see which is causing the problem without switching tools. Go.NET Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes.

Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architectu

ASP.NET Authentication
Visual Studio .NET 2003 ASP.NET implements additional authentication schemes using authentication providers, which are separate from and apply only after the IIS authentication schemes. ASP.NET supports the following authentication providers:
y y y y

Windows (default) Forms Passport None

To enable an authentication provider for an ASP.NET application, use the authentication element in either machine.config or Web.config as follows: Copy
<system.web> <!-- mode=[Windows|Forms|Passport|None] --> <authentication mode="Windows" /> </system.web>

Each ASP.NET authentication provider supports an OnAuthenticate event that occurs during the authentication process, which you can use to implement a custom authorization scheme. The primary purpose of this event is to attach a custom object that implements the IPrincipal Interface to the context. Which ASP.NET authentication provider you use typically depends upon which IIS authentication scheme you choose. If you are using any of the IIS authentication schemes other than Anonymous, you will likely use the Windows authentication provider. Otherwise, you will use Forms, Passport, or None. For more information, see <authentication> Element and ASP.NET Authentication.

Windows
The Windows authentication provider relies upon IIS to perform the required authentication of a client. After IIS authenticates a client, it passes a security token to ASP.NET. ASP.NET constructs and attaches an object of the WindowsPrincipal Class to the application context based on the security token it receives from IIS. For more information, see Windows Authentication Provider and WindowsPrincipal Class.

Pro
y

Authenticates using Windows accounts, so you do not need to write any custom authentication code.

Con
y

May require the use and management of individual Windows user accounts.

In addition, each IIS authentication scheme has its own associated pros and cons, which you should consider when choosing a security model. For more information, see IIS Authentication. Implementation To implement Windows authentication, refer to the applicable IIS Authentication schemes. For more information, see IIS Authentication.

Forms (Cookie)
The Forms authentication provider is an authentication scheme that makes it possible for the application to collect credentials using an HTML form directly from the client. The client submits credentials directly to your application code for authentication. If your application authenticates the client, it issues a cookie to the client that the client presents on subsequent requests. If a request for a protected resource does not contain the cookie, the application redirects the client to the logon page. When authenticating credentials, the application can store credentials in a number of ways, such as a configuration file or a SQL Server database. For more information, see Forms Authentication Provider. Note An ISAPI server extension only handles those resources for which it has an application mapping. For example, the ASP.NET ISAPI server extension only has application mappings for particular resources, such as .asax, .ascx, .aspx, .asmx, and .config files to name a few. By default, the ASP.NET ISAPI server extension, and subsequently the Forms authentication provider, does not process any requests for nonASP.NET resources, such as .htm, .jpg or .gif files. Pros
y y y

Makes it possible for custom authentication schemes using arbitrary criteria. Can be used for authentication or personalization. Does not require corresponding Windows accounts.

Cons
y y

Is subject to replay attacks for the lifetime of the cookie, unless using SSL/TLS. Is only applicable for resources mapped to Aspnet_isapi.dll.

Implementation To implement forms authentication you must create your own logon page and redirect URL for unauthenticated clients. You must also create your own scheme for account authentication. The following is an example of a Web.config configuration using Forms authentication: Copy
<!-- Web.config file --> <system.web> <authentication mode="Forms"> <forms forms="401kApp" loginUrl="/login.aspx" /> </authentication> </system.web>

Because you are implementing your own authentication, you will typically configure IIS for Anonymous authentication.

Passport
The Passport authentication provider is a centralized authentication service provided by Microsoft that offers a single logon and core profile services for member sites. Passport is a forms-based authentication service. When member sites register with Passport, the Passport service grants a site-specific key. The Passport logon server uses this key to encrypt and decrypt the query strings passed between the member site and the Passport logon server. For more information, see Passport Authentication Provider. Pros
y y

Supports single sign-in across multiple domains. Compatible with all browsers.

Con
y

Places an external dependency for the authentication process.

Implementation To implement Passport, you must register your site with the Passport service, accept the license agreement, and install the Passport SDK prior to use. You must configure your application's Web.config file as follows: Copy
<!-- Web.config file --> <system.web> <authentication mode="Passport" /> </system.web>

For more information, see the Microsoft Passport Web site (http://www.passport.com/).

None (Custom Authentication)


Specify "None" as the authentication provider when users are not authenticated at all or if you plan to develop custom authentication code. For example, you may want to develop your own authentication scheme using an ISAPI filter that authenticates users and manually creates an object of the GenericPrincipal Class. For more information, see GenericPrincipal Class. Note An ISAPI server extension only handles those resources for which it has an application mapping. For example, the ASP.NET ISAPI server extension only has application mappings for particular resources, such as .asax, .ascx, .aspx, .asmx, and .config files to name a few. By default, the ASP.NET ISAPI server extension, and subsequently the None (custom) authentication provider, does not process any requests for non-ASP.NET resources, such as .htm, .jpg or .gif files. Pros
y y

Offers total control of the authentication process providing the greatest flexibility. Provides the highest performance if you do not implement an authentication method.

Cons
y y

Custom-built authentication schemes are seldom as secure as those provided by the operating system. Requires extra work to custom-build an authentication scheme.

Implementation To implement no authentication or to develop your own custom authentication, create a custom ISAPI filter to bypass IIS authentication. Use the following Web.config configuration: Copy
<!-- Web.config file --> <system.web> <authentication mode="None" /> </system.web>

See Also Security Model | <authentication> Element | ASP.NET Authentication 2011 Microsoft. All rights reserved.

Terms of Use | Trademarks | Privacy Statement | Feedback

Introduction: When you begin a program for a customer using ASP.Net, you should consider about security. Security is one of the most important components of any application. Security is even more important when you are making a web application which is exposed to million of users. Asp.net provides classes and methods that ensure that the application is secure from outside attacks. In this article we will investigate the different types of authentication provided by ASP.Net. In web.config file you can set authentication mode value 'windows' or 'forms'. What's about difference and how to you use them? (Authentication have some other values to, this article does not consider them.) Configure the Security Settings in the Web.config File: This section demonstrates how to add and modify the <authentication> and <authorization> configuration sections to configure the ASP.NET application to use window-based or forms-based authentication. How to use mode "Windows"? Change the authentication mode to Windows. Windows Authentication mode provides the developer to authenticate a user based on Windows user accounts. This is the default authentication mode provided by ASP.Net. You can easily get the Identity of the user by using User.Identity.Name. This will return the computer name along with the user name. Windows authentication also provides IsInRole method to find the role of the user and than you can give permissions to the user depending on the role. <authentication mode="Windows"> <forms name=" AuthenticationDemo" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /> </authentication> Deny access to the anonymous user in the <authorization> section as follows: <authorization> <deny users ="?" /> <allow users = "*" /> </authorization>

Other you can make a special client to access you project with windows authentication. Code like this (this case you can get value using 'User.Identity.Name', then you can use it to do other work you like.):
<authorization>

<deny users ="?" /> </authorization> How to use mode "Forms"? Change the authentication mode to Forms. Insert the <Forms> tag, and fill the appropriate attributes. (For more information about these attributes, refer to the MSDN documentation) First you should specify a page and make sure all clients can found it. Code like this <authentication mode="Forms"> <forms name=" AuthenticationDemo" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /> </authentication> Deny access to the anonymous user in the <authorization> section as follows: <authorization> <deny users ="?" /> </authorization> Second in that page you to validate the user's Id and Password. Code like this: You can use one of two methods to generate the forms authentication cookie and redirect the user to an appropriate page in the cmdLogin_ServerClick event. Sample code is provided for both scenarios. Use either of them according to your requirement. (1). Call the RedirectFromLoginPage method to automatically generate the forms authentication cookie and redirect the user to an appropriate page in the cmdLogin_ServerClick event: private void cmdLogin_ServerClick(object sender, System.EventArgs e) { If (ValidateUser(txtUserName.Value,txtUserPass.Value) ) { FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, false); } else { Response.Redirect("logon.aspx", true); } } (2). Generate the authentication ticket, encrypt it, create a cookie, add it to the response, and redirect the user. This gives you more control in how you create the cookie. You can also include custom data along with the FormsAuthenticationTicket in this case. Private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value) )

{ FormsAuthenticationTicket tkt; string cookiestr; HttpCookie ck; tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data"); cookiestr = FormsAuthentication.Encrypt(tkt); ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr); if (chkPersistCookie.Checked) ck.Expires=tkt.Expiration; ck.Path = FormsAuthentication.FormsCookiePath; Response.Cookies.Add(ck); string strRedirect; strRedirect = Request["ReturnUrl"]; if (strRedirect==null) strRedirect = "default.aspx"; Response.Redirect(strRedirect, true); } else Response.Redirect("logon.aspx", true); } Additional Notes: You may want to store passwords securely in a database. You can use the FormsAuthentication class utility function named HashPasswordForStoringInConfigFile to encrypt the passwords before you store them in the database or configuration file. You may want to store the SQL connection information in the configuration file (Web.config) so that you can easily modify it if necessary. You may consider adding code to prevent hackers who try to use different combinations of passwords from logging on. For example, you can include logic that accepts only two or three logon attempts. If the user cannot log on in a certain number of attempts, you may want to set a flag in the database to not allow that user to log on until that user re-enables his or her account by visiting a different page or by calling your support line. In addition, you should add appropriate error handling wherever necessary. Because the user is identified based on the authentication cookie, you may want to use Secure Sockets Layer (SSL) on this application so that no one can deceive the authentication cookie and any other valuable information that is being transmitted. Forms-based authentication requires that your client accept or enable cookies on their browser. The timeout parameter of the <authentication> configuration section controls the interval at which the authentication cookie is regenerated. You can choose a

value that provides better performance and security. Certain intermediary proxies and caches on the Internet may cache Web server responses that contain Set-Cookie headers, which are then returned to a different user. Because forms-based authentication uses a cookie to authenticate users, this can cause users to accidentally (or intentionally) impersonate another user by receiving a cookie from an intermediary proxy or cache that was not originally intended for them.

Asp .net Web.config Configuration File

What is Web.Config File? Web.config file, as it sounds like is a configuration file for the Asp .net web application. An Asp .net application has one web.config file which keeps the configurations required for the corresponding application. Web.config file is written in XML with specific tags having specific meanings. What is Machine.config File? As web.config file is used to configure one asp .net web application, same way Machine.config file is used to configure the application according to a particular machine. That is, configuration done in machine.config file is affected on any application that runs on a particular machine. Usually, this file is not altered and only web.config is used which configuring applications.

What can be stored in Web.config file? There are number of important settings that can be stored in the configuration file. Here are some of the most frequently used configurations, stored conveniently inside Web.config file..

1. 2. 3. 4.

Database connections Session States Error Handling Security

Database Connections: The most important configuration data that can be stored inside the web.config file is the database connection string. Storing the connection string in the web.config file makes sense,

since any modifications to the database configurations can be maintained at a single location. As otherwise we'll have to keep it either as a class level variable in all the associated source files or probably keep it in another class as a public static variable. But it this is stored in the Web.config file, it can be read and used anywhere in the program. This will certainly save us a lot of alteration in different files where we used the old connection. Lets see a small example of the connection string which is stored in the web.config file. <configuration> <appSettings> <add key="ConnectionString" value="server=localhost;uid=sa;pwd=;database=DBPerson" /> </appSettings> </configuration> As you can see it is really simple to store the connection string in the web.config file. The connection string is referenced by a key which in this case is "ConnectionString". The value attribute of the configuration file denotes the information about the database. Here we can see that if has database name, userid and password. You can define more options if you want. There is a very good website that deals with all sorts of connection strings. Its called www.connectionstrings.com , in the website you will find the connection strings for most of the databases. Lets see how we access the connection string from our Asp .net web application. using System.Configuration; string connectionString = (string )ConfigurationSettings.AppSettings["ConnectionString"]; The small code snippet above is all that is needed to access the value stored inside the Web.config file. Session States: Session in Asp .net web application is very important. As we know that HTTP is a stateless protocol and we needs session to keep the state alive. Asp .net stores the sessions in different ways. By default the session is stored in the asp .net process. You can always configure the application so that the session will be stored in one of the following ways. 1) Session State Service There are two main advantages of using the State Service. First the state service is not running in the same process as the asp .net application. So even if the asp .net application crashes the sessions will not be destroyed. Any advantage is sharing the state information across a Web

garden (Multiple processors for the same computer). Lets see a small example of the Session State Service. <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:55455" sqlConnectionString="data source=127.0.0.1;user id=sa;password='' cookieless="false" timeout="20"/> The attributes are self explanatory but I will go over them. mode: This can be StateServer or SqlServer. Since we are using StateServer we set the mode to StateServer. stateConnectionString: connectionString that is used to locate the State Service. sqlConnectionString: The connection String of the sql server database. cookieless: Cookieless equal to false means that we will be using cookies to store the session on the client side.

2) SQL Server The final choice to save the session information is using the Sql Server 2000 database. To use Sql Server for storing session state you need to do the following: 1) Run the InstallSqlState.sql script on the Microsoft SQL Server where you intend to store the session. You web.config settings will look something like this: <sessionState mode = "SqlServer" stateConnectionString="tcpip=127.0.0.1:45565" sqlConnectionString="data source="SERVERNAME;user id=sa;password='' cookiesless="false" timeout="20"/> SQL Server lets you share session state among the processors in a Web garden or the servers in a Web farm. Apart from that you also get additional space to store the session. And after that you can take various actions on the session stored. The downside is SQL Server is slow as compared to storing session in the state in process. And also SQL Server cost too much for a small company. 3) InProc: This is another Session State. This one is mostly used for development purposes. The biggest advantage of using this approach is the applications will run faster when compared to other Session state types. But the disadvantage is Sessions are not stored when there is any problem that occurs with the application, when there is a small change in the files etc., Also there could be

frequent loss of session data experienced.. Error Handling: Error handling is one of the most important part of any web application. Each error has to be caught and suitable action has to be taken to resolve that problem. Asp.net web.config file lets us configure, what to do when an error occurs in our application. Check the following xml tag in the web.config file that deals with errors: <customErrors mode = "On"> <error statusCode = "404" redirect = "errorPage.aspx" /> </customErrors> This tells the Asp.net to display custom errors from a remote client or a local client and to display a page named errorPage.aspx. Error "404" is "Page not found" error. If custom error mode is turned "off" than you will see Asp.net default error message. This error messages are good for debugging purposes but should never be exposed to the users. The users should always be presented with friendly errors if any. Security: The most critical aspect of any application is the security. Asp.net offers many different types of security method which can be used depending upon the condition and type of security you need. 1) No Authentication: No Authentication means "No Authentication" :) , meaning that Asp.net will not implement any type of security. 2) Windows Authentication: The Windows authentication allows us to use the windows user accounts. This provider uses IIS to perform the actual authentication, and then passes the authenticated identity to your code. If you like to see that what windows user is using the Asp.net application you can use: User.Identity.Name; This returns the DOMAIN\UserName of the current user of the local machine. 3) Passport Authentication:

Passport Authentication provider uses Microsoft's Passport service to authenticate users. You need to purchase this service in order to use it.
4) Forms Authentication: Forms Authentication uses HTML forms to collect the user information and than it takes required

actions on those HTML collected values. In order to use Forms Authentication you must set the Anonymous Access checkbox checked. Now we need that whenever user tries to run the application he/she will be redirected to the login page. <authentication mode="Forms"> <forms loginUrl = "frmLogin.aspx" name="3345C" timeout="1"/> </authentication> <authorization> <deny users="?" /> </authorization> As you can see we set the Authentication mode to "Forms". The forms loginUrl is the first page being displayed when the application is run by any user. The authorization tags has the deny users element which contains "?", this means that full access will be given to the authenticated users and none access will be given to the unauthenticated users. You can replace "?" with "*" meaning that all access is given to all the users no matter what. Final Words: As you have seen that Web.config file plays a very important role in the over all Asp.net application. There are a lot more features that I have not discussed which includes caching. Try using web.config file when you need to configure the overall application. Mohammad Azam, also known as Azamsharp have been programming in .NET for 4 years. He is the author of several articles. Apart from the articles Azamsharp is also the Top 50 poster on Microsoft official forums (www.asp.net). At present Azamsharp is completing his undergraduate degree in Computer Science from University of Houston and also working as a .NET consultant for cSoft Technologies. You can reach Azamsharp at xMohammadAzamx (at) yahoo.com

Home | MFC | C++ | Microsoft .Net | Asp .Net | Win32 Introduction: Sponsored Links Caching is one of the coolest features in Asp.net. Caching enables you to store the expensive data into Cache object and later retrieve it without doing expensive operations. A very common example where you want to use caching is datagrid paging. I am sure you all are familiar with datagrid paging which enables you to view the records in multiple pages. Each time you visit a different page all the records are fetched from the database. This becomes very expensive operation. Caching can save a lot of expensive operations since you can store all the records in the cache object and use the cache object as the data source. In this article we will see some important features that caching provides. Output Caching: Output caching is used for pages and is also known as Page-level caching. All you need to do to enable output caching is to add a directive in your html view of the aspx page. The output directive can be written like this: @ OutputCache Duration="60" VaryByParam="none" The page will be cached for 60 seconds the VaryByParam attribute is set to "none" which means that there is no sort of caching implemented. Hence if the first user requested page which contains item1 than the second user will also see item1 even if he is requesting item2. That's why we always specify what the caching depends on. @ OutputCache Duration="60" VaryByParam="Category" In the above OutputCache directive you can notice that I changed the VaryByParam attribute to "Category" which means that now the result of caching depends upon Category. Here Category represents the name of the column in the database.

Programmatic Page Caching You can also use caching programmatically, meaning that you can change the value of cache depending upon the tasks performed by the user. The Response.Cache class let's you access the functionality to work with the cache object. You can change the expiration time on the Cache using the SetExpires method of the Response.Cache class. Response.Cache.SetExpires(System.DateTime.Now.AddMinutes(10)); In the same way you can also use Response.Cache.VaryByParams to set the Params programmatically.

Accessing Caching in the Class Libraries Sometimes you will need to access the caching object in the class library. You cannot use Response class anymore since its only limited to the asp.net code behind page. For accessing cache in class library you will have to use HttpContext.Current.Cache. Also don't forget to include System.web namespace.

Data Caching Caching is one of the coolest features in Asp.net. Caching enables you to store the expensive data into Cache object and later retrieve it without doing expensive operations. Data Caching can tremendously increase performance since each time the data is requested you can turn to the Cache object rather than going to the database and fetching the result.

Sponsored Links You all must be familiar with datagrid paging where you can display certain number of records in the datagrid control and use the numeric or next-previous buttons to view the other records. All the records are fetched for each and every page in the datagrid. Meaning that if you have 40000 records in the database and you are using paging. Each time you click to go to the next page you retrieve 40000 records. This is way too much performance kill. That's why for this task we can use Data Caching, let's see how we can use data caching to make our application more efficient.

private void Button3_Click(object sender, System.EventArgs e) { if(Cache["MyArticles"] == null) { // Go to the database and fetch the result in the DataSet

// Assign the dataset to the Cache object

// Cache["MyArticles"] = ds } else { // This means that Cache is not empty and there is data in the cache // Extract the value of Cache object to the DataSet // DataSet ds = (DataSet) Cache["MyArticles"] } }

The above example is pretty much simple and as you have also noticed that the syntax for using Data Caching is very similar to the ViewState object. By using this technique you will only get the data from the database if the Cache is empty. And if you see the page source you will not find any hidden fields since Cache is stored in memory rather than in page source.

Caching Page Fragments

Fragment Caching refers to caching the sections of the page. These sections are most commonly UserControls. Page fragment caching allows you to cache the small portion of the page instead of caching the whole page.

Let's see some examples of fragment caching and how it can be used.

@ OutputCache Duration="120" VaryByParam="CategoryID;SelectedID"

In the Page directive above we have cached CategoryID and SelectedID for 120 seconds. Both of these are the query string parameters.

This means that if the first user request CategoryID = 2 and the second user request the same CategoryID than the second user will recieve the contents from the cache object instead of going to the database and pulling records.

@ OutputCache Duration="120" VaryByParam="none" VaryByControl="Category"

The VaryByControl attribute can only be used in fragment caching. You can use this to cache the value of the controls. These controls can be any server controls like dropdownlist or datagrid. When using fragment caching you only need to put the cache directive in the user control and not on the page.

You can use different type of tools to monitor your performance before and after caching is used. Some of the good tools are NProf and ACT

4Share Read Next: Configuring and Deploying ASP.NET Applications

Related Topics Oracle Coherence: Distributed Caching ASP.NET 2.0 Free Training : Setting Application-Level Caching ASP.NET 2.0 Tutorials : Configuring Page-Level Caching ASP.NET 2.0 Free Tutorials : State Management And Caching in ASp.net 2.0
Sea r

Post Your Comment

Introduction
The majority [if not all] of the pages in a dynamic website are dynamic. That is, pages that are created on user request. As we all know, dynamic web pages help to provide dynamic content, customized for the user requesting the page [e.g.: the user's home page]. Dynamic pages also help provide dynamic content fetched from a changing data store without the need for the administrator to change the page content every time something changes in the data store [e.g.: Listing of books in a publisher's website]. The disadvantage is the overhead in creating the pages for every user request. To overcome this, some websites have page creation engines which create all pages in one go and save them as HTML pages which are then served to the users. But this will only help in scenarios where the page content is the same for all requests [userindependent] as in the second example above. The listing of books is the same irrespective of the user requesting the page. Even if there is provision for listing books category wise by providing different category ID values through the querystring, the page output for a particular category of books is the same for all users.

ASP.NET provides support for "caching" which will help us solve this problem to a great extend. It can cache [store in memory] the output generated by a page and will serve this cached content for future requests. And this is useful only in the second scenario described earlier, where the page content is the same for all requests [user-independent]. The caching feature is customizable in various ways and we will see how we can do that as we go through this article.

Caching a page
In order to cache a page's output, we need to specify an @OutputCache directive at the top of the page. The syntax is as shown below: Collapse
<%@ OutputCache Duration=5 VaryByParam="None" %>

As you can see, there are two attributes to this directive. They are:
y Duration - The time in seconds of how long the output should be cached. After

the specified duration has elapsed, the cached output will be removed and page content generated for the next request. That output will again be cached for 10 seconds and the process repeats. VaryByParam - This attribute is compulsory and specifies the querystring parameters to vary the cache. In the above snippet, we have specified the VaryByParam attribute as None which means the page content to be served is the same regardless of the parameters passed through the querystring [see Example 1 in the sample download]. If there are two requests to the same page with varying querystring parameters, e.g.: .../PageCachingByParam.aspx?id=12 and .../PageCachingByParam.aspx?id=15] and separate page content is generated for each of them, the directive should be: Collapse
<%@ OutputCache Duration=5 VaryByParam="id" %>

The page content for the two requests will each be cached for the time specified by the Duration attribute [see Example 2 in the sample download]. To specify multiple parameters, use semicolon to separate the parameter names. If we specify the VaryByParam attribute as *, the cached content is varied for all parameters passed through the querystring.

Some pages generate different content for different browsers. In such cases, there is provision to vary the cached output for different browsers. The @OutputCache directive has to be modified to: Collapse
<%@ OutputCache Duration=5 VaryByParam="id" VaryByCustom="browser" %>

This will vary the cached output not only for the browser but also its major version. I.e., IE5, IE 6, Netscape 4, Netscape 6 will all get different cached versions of the output.

Caching page fragments


Sometimes we might want to cache just portions of a page. For example, we might have a header for our page which will have the same content for all users. There might be some text/image in the header which might change everyday. In that case, we will want to cache this header for a duration of a day. The solution is to put the header contents into a user control and then specify that the user control content should be cached. This technique is called fragment caching. To specify that a user control should be cached, we use the @OutputCache directive just like we used it for the page. Collapse
<%@ OutputCache Duration=10 VaryByParam="None" %>

With the above directive, the user control content will be cached for the time specified by the Duration attribute [10 secs]. Regardless of the querystring parameters and browser type and/or version, the same cached output is served. [See Example 3 in the download for a demonstration].

Data Caching
ASP.NET also supports caching of data as objects. We can store objects in memory and use them across various pages in our application. This feature is implemented using the Cache class. This cache has a lifetime equivalent to that of the application. Objects can be stored as name value pairs in the cache. A string value can be inserted into the cache as follows: Collapse
Cache["name"]="Smitha";

The stored string value can be retrieved like this: Collapse


if (Cache["name"] != null)

Label1.Text= Cache["name"].ToString();

[See example 4 for an illustration.] To insert objects into the cache, the Add method or different versions of the Insert method of the Cache class can be used. These methods allow us to use the more powerful features provided by the Cache class. One of the overloads of the Insert method is used as follows: Collapse
Cache.Insert("Name", strName, new CacheDependency(Server.MapPath("name.txt"), DateTime.Now.AddMinutes(2), TimeSpan.Zero);

The first two parameters are the key and the object to be inserted. The third parameter is of type CacheDependency and helps us set a dependency of this value to the file named name.txt. So whenever this file changes, the value in the cache is removed. We can specify null to indicate no dependency. The fourth parameter specifies the time at which the value should be removed from cache. [See example 5 for an illustration.] The last parameter is the sliding expiration parameter which shows the time interval after which the item is to be removed from the cache after its last accessed time. The cache automatically removes the least used items from memory, when system memory becomes low. This process is called scavenging. We can specify priority values for items we add to the cache so that some items are given more priority than others: Collapse
Cache.Insert("Name", strName, new CacheDependency(Server.MapPath("name.txt"), DateTime.Now.AddMinutes(2), TimeSpan.Zero, CacheItemPriority.High, null);

The CacheItemPriority enumeration has members to set various priority values. The CacheItemPriority.High assigns a priority level to an item so that the item is least likely to be deleted from the cache.

Points of interest
y

y y

If there are old ASP pages in your website which use the Response.Expires property to cache page output, they can be retained as such. ASP.NET supports this property as well. The Insert method of the Cache class will overwrite any existing item with the same key name. The CacheItemPriority.NotRemovable priority value can be used with Cache.Insert method to set the priority level of an item so that the item will not be removed from the cache during scavenging.

How to Deploy ASP.NET Web Application


Introduction
Several times we encounter a great and sophisticated web or desktop application that does not poses it's appropriate market share just for the reason of poorly written SETUP package and poorly designed deployment strategy. The fact is simple: If your users are not able to easily deploy your application then whatever sophistication or features you provide, they will be unable to even experience your application from the very first place!

In this tutorial we are going to show you a set of techniques by which you can package and deploy your web applications .....

Alternatives
When it comes to web applications specifically, then you will encounter many techniques that can be utilized as a deployment strategy for your web application:

XCOPY Deployment
The most trivial technique is to simply copy your web application files to the production server hard drive and set a virtual directory there. The setting of a virtual directory is needed by several deployment schemes and can be achieved from Internet Information Manager Microsoft Management Consol (MMC snap-in). Because developers typically use the command line order 'XCOPY' to implement this technique, this technique is typically referred to as XCOPY Deployment.

Copy Web Site


Copy Web Site is a new technique provided in ASP.NET 2.0 and Microsoft Visual Studio 2005 (Available from the Website / Copy Web Site... Menu option). Although this technique is performed from inside Visual Studio (in contrast with the XCOPY deployment technique which is performed from outside Visual Studio), there is no compilation performed at all. All your pages are still in their source code form on the production server. Some developers see this fact as a high risk on their intellectual property. Two extra disadvantages of this technique (and in fact any other technique that does not involve any compilation before deployment) are reduced error checking and the slow initial page load. The reduced error checking is a direct result to that no compilation is performed and hence some errors may be discovered by your users later. The initial page load slowness

is also because nothing is compiled yet and the entire web application has to be compiled at the time the first page is being requested. An advantage of this technique over the XCOPY deployment is that you have the options to deploy to the File System, the Local IIS, the FTP Sites, and the Remote Sites. Please see figure 1.

Figure 1

Pre-compilation
All of the deployment methods we mentioned so far suffer from the fact of that no compilation is performed along with the disadvantages that comes as a direct result from this fact. To ensure fast page load and some protection of your source code, you should pre-compile your web site before deployment. Pre-compilation can be performed in-place by just adding '/Deployment/Precompile.axd' to the root URL of your web application and opening the resulting URL in Internet Explore. Pre-compilation can also be achieved using the command line compiler 'aspnet_compiler'.

Using Microsoft Visual Studio 2005 you can still perform pre-compilation from the 'Build / Publish Web Site' menu command. Please see figure 2.

Figure 2

SETUP Projects
It's always desirable to package your web applications such that they are easy to deploy on the production server. Microsoft Visual Studio 2005 gives you this rich packaging option for free ... Just follow the following instructions ... First of all you need to know that our target is to create a package (and MSI file) that contain our web application in a form that can be later easily deployed on the final production server. Let's start by selecting 'File / New / Project' in Microsoft Visual Studio 2005. This will present you the famous set of possible project types from which you will select 'Other Project Types / Setup and Deployment' then you will select the 'Web Setup Project' icon from the side to the right. See figure 3.

Figure 3 In figure 3, set the appropriate project name and folder options then click OK. You can always have the same behavior by adding the SETUP project above to your web application solution instead of creating a new separate solution. You can achieve this by selecting 'File / Add / New Project' instead of 'File / New / Project'. This way you will have a self contained web solution. The 'File / Add / New Project' method is much more recommended. Your setup project will then open as in figure 4 below:

Figure 4 You will then need to add your web application files to the SETUP project we are developing now. This can be achieved by right clicking your SETUP project name in solution explorer and selecting 'Add / Project Output'. Please see figure 5.

Figure 5

To tune the properties of our SETUP project, we will need to press F4 while it's name is selected in the solution explore. This will bring the SETUP project's properties window. Several useful properties can be set in this window: Property Purpose Author, Description, Manufacturer, Use all of these properties to identify / describe your ManufacturerUrl, application and yourself. ProductName, Subject, Title, and Version Here you can specify the icon to be displayed beside your AddRemoveProgramsIcon application in Windows Control Panel's Add Remove Programs. Specify here whether or not a check is to be performed to DetectNewerInstalledVersion determine the existence of a new version already installed of your web application. Specify here whether you need an older version of your web application to be removed if a newer version is being RemovePreviousVersions installed. Some web applications requires the Internet Information Service to be stopped and then restarted after the RestartWWWService deployment of the application. Use this property to control such behavior. The last and most important step is to actually build our SETUP project. This cane be achieved by right clicking the name of our SETUP project in the solution explorer. It's this specific step that creates the MSI package / file mentioned above. This is the file you will need to distribute to your users and this is the file they will use to deploy the web application on their production server. It's worth mentioning that the actual deployment process will be some what similar to the SETUP of any typical desktop application (with some exceptions of course). One of the many similarities is that the web application after deployment will automatically appear in the 'Add / Remove Programs' window of Windows Control Panel.

Production Server Deployment


For your users to deploy your web application they will just need to double click the MSI file. This will produce something similar to figure 6:

Figure 6

Protection and obfuscation of .NET executable files (.exe, .dll,...)


You must know that every of your .NET products, web application or ASP.NET custom control, can be easily decompiled. Practically every user can get your source code by using some free .Net decompiler. If your license doesn't include source code it is not enough to just exclude source code files from installation. You need additional protection. After long analyze, we decided to use Spices.Net for protection of all products of Bean Software. Even if you can't afford complete suite, consider at least their Obfuscator. Later, I discovered .NET Reactor which also looks good and it is about ten times cheaper :). You can check Product Comparison link on NetReactor site where it is compared to some other products, it looks really impressive, and not only in price issue.

For further information


Refer to the online copy of Microsoft Developers Network at http://msdn.microsoft.com or use your own local copy of MSDN.

Crystal Reports in ASP.NET


Crystal Reports is the standard reporting tool for Visual Studio .NET used to display data of presentation quality. You can display multiple-level totals, charts to analyze data, and much more in Crystal Reports. Creating a Crystal Report requires minimal coding since it is created in Designer interface. It is available as an integrated feature of Microsoft Visual Studio .NET, Borland Delphi, and C#Builder.

Advantages of Crystal Reports


Some of the major advantages of using Crystal Reports are: 1. Rapid report development since the designer interface would ease the coding work for the programmer. 2. Can extend it to complicated reports with interactive charts and enhance the understanding of the business model 3. Exposes a report object model, can interact with other controls on the ASP.NET Web form 4. Can programmatically export the reports into widely used formats like .pdf, .doc, .xls, .html and .rtf

Implementation Models
Crystal Reports need database drivers to connect to the data source for accessing data. Crystal Reports in .net support two methods to access data from a data source:

The Pull Method


When this model is used to access data from the data source, the database driver directly retrieves the data from the data source. This model does not require the developer to write code for creating a connection and retrieving data from the data source. It is the Crystal report that manages the SQL commands for connecting by using the specified driver.

The Push Method


When this model is used to access data from data source, the developer writes the code to connect to the data source and retrieve data. The data from the data source is cached in dataset and multiple crystal reports accesses data from the dataset. The performance can be optimized in this manner by using connection sharing and manually limiting the number of records that are passed on to the report.

Crystal Reports Types


Crystal Report Designer can load reports that are included into the project as well as those that are independent of the project.

Strongly-typed Report
When you add a report file into the project, it becomes a "strongly-typed" report. In this case, you will have the advantage of directly creating an instance of the report object, which could reduce a few lines of code, and cache it to improve performance. The related .vb file, which is hidden, can be viewed using the editor's "show all files" icon in the Solution Explorer.

Un-Typed Report
Those reports that are not included into the project are "un-typed" reports. In this case, you will have to create an instance of the Crystal Report Engine's "ReportDocument" object and manually load the report into it.

Creating Crystal Reports


You can create a Crystal Report by using three methods: 1. Manually i.e. from a blank document 2. Using Standard Report Expert 3. From an existing report

Using Pull Method


Creating Crystal Reports Manually. We would use the following steps to implement Crystal Reports using the Pull Model: 1. Create the .rpt file (from scratch) and set the necessary database connections using the Crystal Report Designer interface. 2. Place a CrystalReportViewer control from the toolbox on the .aspx page and set its properties to point to the .rpt file that we created in the previous step. 3. Call the databind method from your code behind page.

I. Steps to create the report i.e. the .rpt file


1) Add a new Crystal Report to the web form by right clicking on the "Solution Explorer", selecting "Add" --> "Add New Item" --> "Crystal Report".

2) On the "Crystal Report Gallery" pop up, select the "As a Blank Report" radio button and click "ok".

3) This should open up the Report File in the Crystal Report Designer.

4) Right click on the "Details Section" of the report, and select "Database" -> "Add/Remove Database".

5) In the "Database Expert" pop up window, expand the "OLE DB (ADO)" option by clicking the "+" sign, which should bring up another "OLE DB (ADO)" pop up. 6) In the "OLE DB (ADO)" pop up, Select "Microsoft OLE DB Provider for SQL Server" and click Next.

7) Specify the connection information. 8) Click "Next" and then click "Finish" 9) Now you should be able to see the Database Expert showing the table that have been selected 10) Expand the "Pubs" database, expand the "Tables", select the "Stores" table and click on ">" to include it into the "Selected Tables" section. Note: If you add more than one table in the database Expert and the added tables have matching fields, when you click the OK button after adding the tables, the links between the added tables is displayed under the Links tab. You can remove the link by clicking the Clear Links button.

11) Now the Field Explorer should show you the selected table and its fields under the "Database Fields" section, in the left window. 12) Drag and drop the required fields into the "Details" section of the report. The field names would automatically appear in the "Page Header" section of the report. If you want to modify the header text then right click on the text of the "Page Header" section, select "Edit Text Object" option and edit it.

13) Save it and we are through.

II. Creating a Crystal Report Viewer Control


1) Drag and drop the "Crystal Report Viewer>" from the web forms tool box on to the .aspx page 2) Open the properties window for the Crystal Report Viewer control. 3) Click on the [...] next to the "Data Binding" Property and bring up the data binding pop-up window 4) Select "Report Source".

5) Select the "Custom Binding Expression" radio button, on the right side bottom of the window and specify the sample .rpt filename and path as shown in the fig.

6) You should be able to see the Crystal Report Viewer showing you a preview of actual report file using some dummy data and this completes the inserting of the Crystal Report Viewer controls and setting its properties. Note: In the previous example, the CrystalReportViewer control was able to directly load the actual data during design time itself as the report was saved with the data. In this case, it will not display the data during design time as it not saved with the data - instead it will show up with dummy data during design time and will fetch the proper data only at run time. 7) Call the Databind method on the Page Load Event of the Code Behind file (.aspx.vb). Build and run your .aspx page. The output would look like this.

Using a PUSH model


1. Create a Dataset during design time. 2. Create the .rpt file (from scratch) and make it point to the Dataset that we created in the previous step.

3. Place a CrystalReportViewer control on the .aspx page and set its properties to point to the .rpt file that we created in the previous step. 4. In your code behind page, write the subroutine to make the connections to the database and populate the dataset that we created previously in step one. 5. Call the Databind method from your code behind page.

I. Creating a Dataset during Design Time to Define the Fields of the Reports
1) Right click on "Solution Explorer", select "Add" --> select "Add New Item" --> Select "DataSet"

2) Drag and drop the "Stores" table (within the PUBS database) from the "SQL Server" Item under "Server Explorer".

3) This should create a definition of the "Stores" table within the Dataset

The .xsd file created this way contains only the field definitions without any data in it. It is up to the developer to create the connection to the database, populate the dataset and feed it to the Crystal Report.

II. Creating the .rpt File


4) Create the report file using the steps mentioned previously. The only difference here is that instead of connecting to the Database thru Crystal Report to get to the Table, we would be using our DataSet that we just created. 5) After creating the .rpt file, right click on the "Details" section of the Report file, select "Add/Remove Database" 6) In the "Database Expert" window, expand "Project Data" (instead of "OLE DB" that was selected in the case of the PULL Model), expand "ADO.NET DataSet", "DataSet1", and select the "Stores"table. 7) Include the "Stores" table into the "Selected Tables" section by clicking on ">" and then Click "ok"

8) Follow the remaining steps to create the report layout as mentioned previously in the PULL Model to complete the .rpt Report file creation

III. Creating a CrystalReportViewer Control


9) Follow the steps mentioned previously in the PULL Model to create a Crystal Report Viewer control and set its properties. Code Behind Page Modifications: 10) Call this subroutine in your page load event: Sub BindReport() Dim myConnection As New SqlClient.SqlConnection() myConnection.ConnectionString = "server= (local)\NetSDK;database=pubs;Trusted_Connection=yes" Dim MyCommand As New SqlClient.SqlCommand() MyCommand.Connection = myConnection MyCommand.CommandText = "Select * from Stores" MyCommand.CommandType = CommandType.Text Dim MyDA As New SqlClient.SqlDataAdapter() MyDA.SelectCommand = MyCommand Dim myDS As New Dataset1() 'This is our DataSet created at Design Time MyDA.Fill(myDS, "Stores")

'You have to use the same name as that of your Dataset that you created during design time Dim oRpt As New CrystalReport1() ' This is the Crystal Report file created at Design Time oRpt.SetDataSource(myDS) ' Set the SetDataSource property of the Report to the Dataset CrystalReportViewer1.ReportSource = oRpt ' Set the Crystal Report Viewer's property to the oRpt Report object that we created End Sub Note: In the above code, you would notice that the object oRpt is an instance of the "Strongly Typed" Report file. If we were to use an "UnTyped" Report then we would have to use a ReportDocument object and manually load the report file into it.

Enhancing Crystal Reports


Accessing filtered data through Crystal reports
Perform the following steps for the same. 1. Generate a dataset that contains data according to your selection criteria, say "where (cost>1000)". 2. Create the Crystal Report manually. It would look like this.

3. Right Click Group Name fields in the field Explorer window and select insert Group from the shortcut menu. Select the relevant field name from the first list box as shown.

The group name field is created, since the data needs to be grouped on the basis of the cat id say. 4. A plus sign is added in front of Group Name Filed in the field explorer window. The Group Name Field needs to be added to the Group Header section of the Crystal Report. Notice this is done automatically.

5. Right Click the running total field and select new. Fill the required values through > and the drop down list.

6. Since the count of number of categories is to be displayed for the total categories, drag RTotal0 to the footer of the report.

Create a formula
Suppose if the report required some Calculations too. Perform the following steps: 1. Right Click the formula Fields in the field explorer window and select new. Enter any relevant name, say percentage.

2. A formula can be created by using the three panes in the dialog box. The first pane contains all the crystal report fields, the second contains all the functions, such as Avg, Sin, Sum etc and the third contains operators such as arithmetic, conversion and comparison operators. 3. Double click any relevant field name from the forst pane, say there's some field like advance from some CustOrder table. Then expand Arithmetic from the third pane and double click Divide operator. 4. Double click another field name from the first which you want to use as divisor of the first field name already selected say it is CustOrder.Cost. 5. Double Click the Multiply from third pane and the type 100. 6. The formula would appear as {CustOrder.Advance}/{ CustOrder.Cost} * 100. 7. Save the formula and close Formula Editor:@Percentage dialog box. 8. Insert the percentage formula field in the details pane. 9. Host the Crystal report.

Exporting Crystal reports


When using Crystal Reports in a Web Form, the CrystalReportViewer control does not have the export or the print buttons unlike the one in Windows Form. Although, we can achieve export and print functionality through coding. If we export to PDF format, Acrobat can handle the printing for us, as well as saving a copy of the report. You can opt to export your report file into one of the following formats:
o

PDF (Portable Document Format)

o o o o

DOC (MS Word Document) XLS (MS Excel Spreadsheet) HTML (Hyper Text Markup Language - 3.2 or 4.0 compliant) RTF (Rich Text Format)

To accomplish this you could place a button on your page to trigger the export functionality. When using Crystal Reports in ASP.NET in a Web Form, the CrystalReportViewer control does not have the export or the print buttons like the one in Windows Form. We can still achieve some degree of export and print functionality by writing our own code to handle exporting. If we export to PDF format, Acrobat can be used to handle the printing for us and saving a copy of the report.

Exporting a Report File Created using the PULL Model


Here the Crystal Report takes care of connecting to the database and fetching the required records, so you would only have to use the below given code in the Event of the button. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim myReport As CrystalReport1 = New CrystalReport1() 'Note : we are creating an instance of the strongly-typed Crystal Report file here. Dim DiskOpts As CrystalDecisions.Shared.DiskFileDestinationOptions = New CrystalDecisions.Shared.DiskFileDestinationOptions myReport.ExportOptions.ExportDestinationType = CrystalDecisions.[Shared].ExportDestinationType.DiskFile ' You also have the option to export the report to other sources ' like Microsoft Exchange, MAPI, etc. myReport.ExportOptions.ExportFormatType = CrystalDecisions.[Shared].ExportFormatType.PortableDocFormat 'Here we are exporting the report to a .pdf format. You can ' also choose any of the other formats specified above. DiskOpts.DiskFileName = "c:\Output.pdf" 'If you do not specify the exact path here (i.e. including ' the drive and Directory), 'then you would find your output file landing up in the 'c:\WinNT\System32 directory - atleast in case of a ' Windows 2000 System myReport.ExportOptions.DestinationOptions = DiskOpts 'The Reports Export Options does not have a filename property 'that can be directly set. Instead, you will have to use 'the DiskFileDestinationOptions object and set its DiskFileName

'property to the file name (including the path) of your choice. 'Then you would set the Report Export Options 'DestinationOptions property to point to the 'DiskFileDestinationOption object. myReport.Export() 'This statement exports the report based on the previously set properties. End Sub

Exporting a Report File Created Using the PUSH Model


Using Push Model, the first step would be to manually create connections and populate the Dataset, and set the Report's "SetDataSource" property to the required Dataset (in the same manner as shown in the Push Model example before). The next step would be to call the above given Export.

Crystal Reports alternatives


Many people found Crystal Reports hard to learn and use and they are seeking for simpler alternatives. I suggest you to try Stimulsoft reports especially if you work with complex reports. Stimulsoft is much easier to use but also easier to deploy with your application since you deploy only one more .NET assembly, written in C#. In some areas (designer, working with different data sources, subreports) it is even better than Crystal.

Creating webservice: using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod]

public string HelloWorld() { return "Hello World"; } [WebMethod(Description="Sum of two No's")] public int sum(int a, int b) { return a + b; } [WebMethod] public int Mul(int a, int b) { return a * b; } } After excuting webservice it will generate XML format result. <?xml version="1.0" encoding="utf-8" ?> <int xmlns="http://tempuri.org/">2</int> copy the url before invoke http://localhost:1103/WebSite1/Service.asmx After that create website then goto Addwebreference click on it paste the url and click go button and then give the webservice name click add webreference. it will generate proxy class with the name of webservice name. then consume the webservice in website. Code of Consuming the webservice: protected void Mul_Click(object sender, EventArgs e) { triveniWS.Service ob = new triveniWS.Service(); Label1.Text =ob.Mul(int.Parse(TextBox1.Text), int.Parse(TextBox2.Text)).ToString(); } protected void Add_Click(object sender, EventArgs e) { triveniWS.Service ob = new triveniWS.Service(); Label1.Text = ob.sum(int.Parse(TextBox1.Text), int.Parse(TextBox2.Text)).ToString(); }

De le te

Rep l
pam

r ar

Mov e...

Mov e...

Go to Previous message | Go to Next message | Back to Messages


Go

| Full Headers Reply Reply All Forward Forward


Chec k Ma il

ew

Mail Search

Ma il ea r c h

WelcomeInboxNewFoldersMail Options

Anda mungkin juga menyukai