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.
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).
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.
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 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.
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.
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.)
{ 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.
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.
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.
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 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).
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.
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.)
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 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.
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.
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.
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.
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
File: MyWebService.asmx
Collapse
<%@ WebService Language="C#" class="MyClass" %> using System.Web.Services ;
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.
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>
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.
[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>
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
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.
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.
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
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.
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
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.
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.
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
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
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/).
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.
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.
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: 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
// 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.
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.
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.
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
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
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.
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";
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.
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.
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.
Figure 6
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:
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.
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.
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.
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.
8) Follow the remaining steps to create the report layout as mentioned previously in the PULL Model to complete the .rpt Report file creation
'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.
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.
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.
'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
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...
ew
Mail Search
Ma il ea r c h
WelcomeInboxNewFoldersMail Options