Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
422 views

Summary: Scott Mitchell Looks at The Benefits of and Confusion Around View State in

Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
422 views

Summary: Scott Mitchell Looks at The Benefits of and Confusion Around View State in

Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 91

Understanding ASP.

NET View State


 

Scott Mitchell
4GuysFromRolla.com

May 2004

Applies to:
   Microsoft® ASP.NET
   Microsoft® Visual Studio® .NET

Summary: Scott Mitchell looks at the benefits of and confusion around View State in
Microsoft® ASP.NET. In addition, he shows you how you can interpret (and protect) the
data stored in View State. (25 printed pages)

Click here to download the code sample for this article.

Contents

Introduction
The ASP.NET Page Life Cycle
The Role of View State
View State and Dynamically Added Controls
The ViewState Property
Timing the Tracking of View State
Storing Information in the Page's ViewState Property
The Cost of View State
Disabling the View State
Specifying Where to Persist the View State
Parsing the View State
View State and Security Implications
Conclusion

Introduction
Microsoft® ASP.NET view state, in a nutshell, is the technique used by an ASP.NET
Web page to persist changes to the state of a Web Form across postbacks. In my
experiences as a trainer and consultant, view state has caused the most confusion among
ASP.NET developers. When creating custom server controls or doing more advanced
page techniques, not having a solid grasp of what view state is and how it works can
come back to bite you. Web designers who are focused on creating low-bandwidth,
streamlined pages oftentimes find themselves frustrated with view state, as well. The
view state of a page is, by default, placed in a hidden form field named __VIEWSTATE.
This hidden form field can easily get very large, on the order of tens of kilobytes. Not
only does the __VIEWSTATE form field cause slower downloads, but, whenever the user
posts back the Web page, the contents of this hidden form field must be posted back in
the HTTP request, thereby lengthening the request time, as well.

This article aims to be an in-depth examination of the ASP.NET view state. We'll look at
exactly what view state is storing, and how the view state is serialized to the hidden form
field and deserialized back on postback. We'll also discuss techniques for reducing the
bandwidth required by the view state.

Note   This article is geared toward the ASP.NET page developer rather than the
ASP.NET server control developer. This article therefore does not include a discussion
on how a control developer would implement saving state. For an in-depth discussion on
that issue, refer to the book Developing Microsoft ASP.NET Server Controls and
Components.

Before we can dive into our examination of view state, it is important that we first take a
quick moment to discuss the ASP.NET page life cycle. That is, what exactly happens
when a request comes in from a browser for an ASP.NET Web page? We'll step through
this process in the next section.

The ASP.NET Page Life Cycle


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

Figure 1. ASP.NET Page Handling


This life cycle of the ASP.NET page starts with a call to the ProcessRequest() method.
This method begins by initializing the page's control hierarchy. Next, the page and its
server controls proceed lock-step through various phases that are essential to executing an
ASP.NET Web page. These steps include managing view state, handling postback events,
and rendering the page's HTML markup. Figure 2 provides a graphical representation of
the ASP.NET page life cycle. The life cycle ends by handing off the Web page's HTML
markup to the Web server, which sends it back to the client that requested the page.

Note   A detailed discussion of the steps leading up to the ASP.NET page life cycle is
beyond the scope of this article. For more information read Michele Leroux-Bustamante's
Inside IIS & ASP.NET. For a more detailed look at HTTP handlers, which are the
endpoints of the ASP.NET pipeline, check out my previous article on HTTP Handlers.

What is important to realize is that each and every time an ASP.NET Web page is
requested it goes through these same life cycle stages (shown in Figure 2).

Figure 2. Events in the Page Life Cycle

Stage 0 - Instantiation

The life cycle of the ASP.NET page begins with instantiation of the class that represents
the requested ASP.NET Web page, but how is this class created? Where is it stored?
ASP.NET Web pages, as you know, are made up of both an HTML portion and a code
portion, with the HTML portion containing HTML markup and Web control syntax. The
ASP.NET engine converts the HTML portion from its free-form text representation into a
series of programmatically-created Web controls.

When an ASP.NET Web page is visited for the first time after a change has been made to
the HTML markup or Web control syntax in the .aspx page, the ASP.NET engine auto-
generates 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, server-
side <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 top-
level 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 code—which won't win any points for readability—
navigate to the
WINDOWS\Microsoft.NET\Framework\Version\Temporary ASP.NET Files
folder and open one of the
.cs
or
.vb
files.

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

Stage 1 - Initialization

After the control hierarchy has been built, the Page, along with all of the controls in its
control hierarchy, enter the initialization stage. This stage is marked by having the Page
and controls fire their Init events. At this point in the page life cycle, the control
hierarchy has been constructed, and the Web control properties that are specified in the
declarative syntax have been assigned.
We'll look at the initialization stage in more detail later in this article. With regards to
view state it is important for two reasons; first, server controls don't begin tracking view
state changes until right at the end of the initialization stage. Second, when adding
dynamic controls that need to utilize view state, these controls will need to be added
during the Page's Init event as opposed to the Load event, as we'll see shortly.

Stage 2 - Load View State

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

Stage 3 - Load Postback Data

The load postback data stage also only happens when the page has been posted back. A
server control can indicate that it is interested in examining the posted back data by
implementing the IPostBackDataHandler interface. In this stage in the page life cycle,
the Page class enumerates the posted back form fields, and searches for the corresponding
server control. If it finds the control, it checks to see if the control implements the
IPostBackDataHandler interface. If it does, it hands off the appropriate postback data to
the server control by calling the control's LoadPostData() method. The server control
would then update its state based on this postback data.

To help clarify things, let's look at a simple example. One nice thing about ASP.NET is
that the Web controls in a Web Form remember their values across postback. That is, if
you have a TextBox Web control on a page and the user enters some value into the
TextBox and posts back the page, the TextBox's Text property is automatically updated
to the user's entered value. This happens because the TextBox Web control implements
the IPostBackDataHandler interface, and the Page class hands off the appropriate value
to the TextBox class, which then updates its Text property.

To concretize things, imagine that we have an ASP.NET Web page with a TextBox
whose ID property is set to txtName. When the page is first visited, the following HTML
will be rendered for the TextBox: <input type="text" id="txtName"
name="txtName" />. When the user enters a value into this TextBox (such as, "Hello,
World!") and submits the form, the browser will make a request to the same ASP.NET
Web page, passing the form field values back in the HTTP POST headers. These include
the hidden form field values (such as __VIEWSTATE), along with the value from the
txtName TextBox.

When the ASP.NET Web page is posted back in the load postback data stage, the Page
class sees that one of the posted back form fields corresponds to the
IPostBackDataHandler interface. There is such a control in the hierarchy, so the
TextBox's LoadPostData() method is invoked, passing in the value the user entered into
the TextBox ("Hello, World!"). The TextBox's LoadPostData() method simply assigns
this passed in value to its Text property.

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

Stage 4 - Load

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

Stage 5 - Raise Postback Event

Certain server controls raise events with respect to changes that occurred between
postbacks. For example, the DropDownList Web control has a SelectedIndexChanged
event, which fires if the DropDownList's SelectedIndex has changed from the
SelectedIndex value in the previous page load. Another example: if the Web Form was
posted back due to a Button Web control being clicked, the Button's Click event is fired
during this stage.

There are two flavors of postback events. The first is a changed event. This event fires
when some piece of data is changed between postbacks. An example is the
DropDownLists SelectedIndexChanged event, or the TextBox's TextChanged event.
Server controls that provide changed events must implement the IPostBackDataHandler
interface. The other flavor of postback events is the raised event. These are events that
are raised by the server control for whatever reason the control sees fit. For example, the
Button Web control raises the Click event when it is clicked, and the Calendar control
raises the VisibleMonthChanged event when the user moves to another month. Controls
that fire raised events must implement the IPostBackEventHandler interface.

Since this stage inspects postback data to determine if any events need to be raised, the
stage only occurs when the page has been posted back. As with the load postback data
stage, the raise postback event stage does not use view state information at all. Whether
or not an event is raised depends on the data posted back in the form fields.
Stage 6 - Save View State

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

Stage 7 - Render

In the render stage the HTML that is emitted to the client requesting the page is
generated. The Page class accomplishes this by recursively invoking the
RenderControl() method of each of the controls in its hierarchy.

These seven stages are the most important stages with respect to understanding view
state. (Note that I did omit a couple of stages, such as the PreRender and Unload stages.)
As you continue through the article, keep in mind that every single time an ASP.NET
Web page is requested, it proceeds through these series of stages.

The Role of View State


View state's purpose in life is simple: it's there to persist state across postbacks. (For an
ASP.NET Web page, its state is the property values of the controls that make up its
control hierarchy.) This begs the question, "What sort of state needs to be persisted?" To
answer that question, let's start by looking at what state doesn't need to be persisted
across postbacks. Recall that in the instantiation stage of the page life cycle, the control
hierarchy is created and those properties that are specified in the declarative syntax are
assigned. Since these declarative properties are automatically reassigned on each
postback when the control hierarchy is constructed, there's no need to store these property
values in the view state.

For example, imagine we have a Label Web control in the HTML portion with the
following declarative syntax:

Copy
<asp:Label runat="server" Font-Name="Verdana"
Text="Hello, World!"></asp:Label>

When the control hierarchy is built in the instantiation stage, the Label's Text property
will be set to "Hello, World!" and its Font property will have its Name property set to
Verdana. Since these properties will be set each and every page visit during the
instantiation stage, there's no need to persist this information in the view state.
What needs to be stored in the view state is any programmatic changes to the page's state.
For example, suppose that in addition to this Label Web control, the page also contained
two Button Web controls, a Change Message Button and an Empty Postback button. The
Change Message Button has a Click event handler that assigns the Label's Text property
to "Goodbye, Everyone!"; the Empty Postback Button just causes a postback, but doesn't
execute any code. The change to the Label's Text property in the Change Message
Button would need to be saved in the view state. To see how and when this change would
be made, let's walk through a quick example. Assuming that the HTML portion of the
page contains the following markup:

Copy
<asp:Label runat="server" ID="lblMessage"
Font-Name="Verdana" Text="Hello, World!"></asp:Label>
<br />
<asp:Button runat="server"
Text="Change Message" ID="btnSubmit"></asp:Button>
<br />
<asp:Button runat="server" Text="Empty Postback"></asp:Button>

And the code-behind class contains the following event handler for the Button's Click
event:

Copy
private void btnSubmit_Click(object sender, EventArgs e)
{
lblMessage.Text = "Goodbye, Everyone!";
}

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

To understand why saving the Label's changed Text property in the view state is vital,
consider what would happen if this information were not persisted in view state. That is,
imagine that in step 2's save view state stage, no view state information was persisted. If
this were the case, then in step 3 the Label's Text property would be assigned to "Hello,
World!" in the instantiation stage, but would not be reassigned to "Goodbye, Everyone!"
in the load view state stage. Therefore, from the end user's perspective, the Label's Text
property would be "Goodbye, Everyone!" in step 2, but would seemingly be reset to its
original value ("Hello, World!") in step 3, after clicking the Empty Postback button.

View State and Dynamically Added Controls


Since all ASP.NET server controls contain a collection of child controls exposed through
the Controls property, controls can be dynamically added to the control hierarchy by
appending new controls to a server control's Controls collection. A thorough discussion
of dynamic controls is a bit beyond the scope of this article, so we won't cover that topic
in detail here; instead, we'll focus on how to manage view state for controls that are
added dynamically. (For a more detailed lesson on using dynamic controls, check out
Dynamic Controls in ASP.NET and Working with Dynamically Created Controls.)

Recall that in the page life cycle, the control hierarchy is created and the declarative
properties are set in the instantiation stage. Later, in the load view state stage, the state
that had been altered in the prior page visit is restored. Thinking a bit about this, three
things become clear when working with dynamic controls:

1. Since the view state only persists changed control state across postbacks, and not
the actual controls themselves, dynamically added controls must be added to the
ASP.NET Web page, on both the initial visit as well as all subsequent postbacks.
2. Dynamic controls are added to the control hierarchy in the code-behind class, and
therefore are added at some point after the instantiation stage.
3. The view state for these dynamically added controls is automatically saved in the
save view state stage. (What happens on postback if the dynamic controls have
not yet been added by the time the load view state stage rolls, however?)

So, dynamically added controls must be programmatically added to the Web page on
each and every page visit. The best time to add these controls is during the initialization
stage of the page life cycle, which occurs before the load view state stage. That is, we
want to have the control hierarchy complete before the load view state stage arrives. For
this reason, it is best to create an event handler for the Page class's Init event in your
code-behind class, and add your dynamic controls there.

Note   You may be able to get away with loading your controls in the
Page_Load
event handler and maintaining the view state properly. It all depends on whether or not
you are setting any properties of the dynamically loaded controls programmatically and,
if so, when you're doing it relative to the
Controls.Add(dynamicControl)
line. A thorough discussion of this is a bit beyond the scope of this article, but the reason
it may work is because the
Controls
property's
Add()
method recursively loads the parent's view state into its children, even though the load
view state stage has passed.

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

Figure 5. Effect of inserting controls on View State

The ViewState Property


Each control is responsible for storing its own state, which is accomplished by adding its
changed state to its ViewState property. The ViewState property is defined in the
System.Web.UI.Control class, meaning that all ASP.NET server controls have this
property available. (When talking about view state in general I'll use lower case letters
with a space between view and state; when discussing the ViewState property, I'll use
the correct casing and code-formatted text.)

If you examine the simple properties of any ASP.NET server control you'll see that the
properties read and write directly to the view state. (You can view the decompiled source
code for a .NET assembly by using a tool like Reflector.) For example, consider the
HyperLink Web control's NavigateUrl property. The code for this property looks like
so:

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

As this code sample illustrates, whenever a control's property is read, the control's
ViewState is consulted. If there is not an entry in the ViewState, then the default value
for the property is returned. When the property is assigned, the assigned value is written
directly to the ViewState.

Note   All Web controls use the above pattern for simple properties. Simple properties are
those that are scalar values, like strings, integers, Booleans, and so on. Complex
properties, such as the Label's Font property, which might be classes themselves, use a
different approach. Consult the book Developing Microsoft ASP.NET Server Controls
and Components for more information on state maintenance techniques for ASP.NET
server controls.

The ViewState property is of type System.Web.UI.StateBag. The StateBag class


provides a means to store name and value pairs, using a
System.Collections.Specialized.HybridDictionary behind the scenes. As the
NavigateUrl property syntax illustrates, items can be added to and queried from the
StateBag using the same syntax you could use to access items from a Hashtable.

Timing the Tracking of View State


Recall that earlier I said the view state only stores state that needs to be persisted across
postbacks. One bit of state that does not need to be persisted across postbacks is the
control's properties specified in the declarative syntax, since they are automatically
reinstated in the page's instantiation stage. For example, if we have a HyperLink Web
control on an ASP.NET Web page and declaratively set the NavigateUrl property to
http://www.ScottOnWriting.NET then this information doesn't need to be stored in the
view state.

Seeing the HyperLink control's NavigateUrl property's code, however, it looks as if the
control's ViewState is written to whenever the property value is set. In the instantiation
stage, therefore, where we'd have something like HyperLink1.NavigateUrl =
http://www.ScottOnWriting.NET;, it would only make sense that this information
would be stored in the view state.

Regardless of what might seem apparent, this is not the case. The reason is because the
StateBag class only tracks changes to its members after its TrackViewState() method
has been invoked. That is, if you have a StateBag, any and all additions or modifications
that are made before TrackViewState() is made will not be saved when the
SaveViewState() method is invoked. The TrackViewState() method is called at the
end of the initialization stage, which happens after the instantiation stage. Therefore, the
initial property assignments in the instantiation stage—while written to the ViewState in
the properties' set accessors—are not persisted during the SaveViewState() method call
in the save view state stage, because the TrackViewState() method has yet to be
invoked.

Note   The reason the


StateBag
has the
TrackViewState()
method is to keep the view state as trimmed down as possible. Again, we don't want to
store the initial property values in the view state, as they don't need to be persisted across
postbacks. Therefore, the
TrackViewState()
method allows the state management to begin after the instantiation and initialization
stages.

Storing Information in the Page's ViewState Property


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

Copy
ViewState[keyName] = value

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

For more information on creating sortable, pageable DataGrids (or a pageable, sortable,
editable DataGrid), pick up a copy of my book ASP.NET Data Web Controls Kick Start.
The Cost of View State
Nothing comes for free, and view state is no exception. The ASP.NET view state imposes
two performance hits whenever an ASP.NET Web page is requested:

1. On all page visits, during the save view state stage the Page class gathers the
collective view state for all of the controls in its control hierarchy and serializes
the state to a base-64 encoded string. (This is the string that is emitted in the
hidden __VIEWSTATE form filed.) Similarly, on postbacks, the load view state
stage needs to deserialize the persisted view state data, and update the pertinent
controls in the control hierarchy.
2. The __VIEWSTATE hidden form field adds extra size to the Web page that the
client must download. For some view state-heavy pages, this can be tens of
kilobytes of data, which can require several extra seconds (or minutes!) for
modem users to download. Also, when posting back, the __VIEWSTATE form field
must be sent back to the Web server in the HTTP POST headers, thereby
increasing the postback request time.

If you are designing a Web site that is commonly accessed by users coming over a
modem connection, you should be particularly concerned with the bloat the view state
might add to a page. Fortunately, there are a number of techniques that can be employed
to reduce view state size. We'll first see how to selectively indicate whether or not a
server control should save its view state. If a control's state does not need to be persisted
across postbacks, we can turn off view state tracking for that control, thereby saving the
extra bytes that would otherwise have been added by that control. Following that, we'll
examine how to remove the view state from the page's hidden form fields altogether,
storing the view state instead on the Web server's file system.

Disabling the View State


In the save view state stage of the ASP.NET page life cycle, the Page class recursively
iterates through the controls in its control hierarchy, invoking each control's
SaveViewState() method. This collective state is what is persisted to the hidden
__VIEWSTATE form field. By default, all controls in the control hierarchy will record their
view state when their SaveViewState() method is invoked. As a page developer,
however, you can specify that a control should not save its view state or the view state of
its children controls by setting the control's EnableViewState property to False (the
default is True).

The EnableViewState property is defined in the System.Web.UI.Control class, so all


server controls have this property, including the Page class. You can therefore indicate
that an entire page's view state need not be saved by setting the Page class's
EnableViewState to False. (This can be done either in the code-behind class with
Page.EnableViewState = false; or as a @Page-level directive—<%@Page
EnableViewState="False" %>.)
Not all Web controls record the same amount of information in their view state. The
Label Web control, for example, records only programmatic changes to its properties,
which won't greatly impact the size of the view state. The DataGrid, however, stores all
of its contents in the view state. For a DataGrid with many columns and rows, the view
state size can quickly add up! For example, the DataGrid shown in Figure 6 (and included
in this article's code download as HeavyDataGrid.aspx) has a view state size of roughly
2.8 kilobytes, and a total page size of 5,791 bytes. (Almost half of the page's size is due
to the __VIEWSTATE hidden form field!) Figure 7 shows a screenshot of the view state,
which can be seen by visiting the ASP.NET Web page, doing a View\Source, and then
locating the __VIEWSTATE hidden form field.
Figure 6. DataGrid control
Figure 7. View State for DataGrid control

The download for this article also includes an ASP.NET Web page called
LightDataGrid.aspx, which has the same DataGrid as shown in Figure 6, but with the
EnableViewState property set to False. The total view state size for this page? 96 bytes.
The entire page size clocks in a 3,014 bytes. LightDataGrid.aspx boasts a view state
size about 1/30th the size of HeavyDataGrid.aspx, and a total download size that's about
half of HeavyDataGrid.aspx. With wider DataGrids with more rows, this difference
would be even more pronounced. (For more information on performance comparisons
between view state-enabled DataGrids and view state-disabled DataGrids, refer to
Deciding When to Use the DataGrid, DataList, or Repeater.)

Hopefully the last paragraph convinces you of the benefit of intelligently setting the
EnableViewState property to False, especially for "heavy" view state controls like the
DataGrid. The question now, is, "When can I safely set the EnableViewState property to
False?" To answer that question, consider when you need to use the view state—only
when you need to remember state across postbacks. The DataGrid stores its contents
in the view state so the page developer doesn't need to rebind the database data to the
DataGrid on each and every page load, but only on the first one. The benefit is that the
database doesn't need to be accessed as often. If, however, you set a DataGrid's
EnableViewState property to False, you'll need to rebind the database data to the
DataGrid on both the first page load and every subsequent postback.

For a Web page that has a read-only DataGrid, like the one in Figure 6, you'd definitely
want to set the DataGrid's EnableViewState property to False. You can even create
sortable and pageable DataGrids with the view state disabled (as can be witnessed in the
LightDataGrid-WithFeatures.aspx page, included in the download), but, again, you'll
need to be certain to bind the database data to the DataGrid on the first page visit, as well
as on all subsequent postbacks.

Note   Creating an editable DataGrid with disabled view state requires some intricate
programming, which involves parsing of the posted back form fields in the editable
DataGrid. Such strenuous effort is required because, with an editable DataGrid blindly
rebinding, the database data to the DataGrid will overwrite any changes the user made
(see this FAQ for more information).

Specifying Where to Persist the View State


After the page has collected the view state information for all of the controls in its control
hierarchy in the save view state stage, it persists it to the __VIEWSTATE hidden form field.
This hidden form field can, of course, greatly add to the overall size of the Web page.
The view state is serialized to the hidden form field in the Page class's
SavePageStateToPersistenceMedium() method during the save view state stage, and
is deserialized by the Page class's LoadPageStateFromPersistenceMedium() method in
the load view state stage. With just a bit of work we can have the view state persisted to
the Web server's file system, rather than as a hidden form field weighing down the page.
To accomplish this we'll need to create a class that derives from the Page class and
overrides the SavePageStateToPersistenceMedium() and
LoadPageStateFromPersistenceMedium() methods.

Note   There is a third-party product called Flesk.ViewStateOptimizer that reduces the


view state bloat using a similar technique.

The view state is serialized and deserialized by the System.Web.UI.LosFormatter class


—the LOS stands for limited object serialization—and is designed to efficiently serialize
certain types of objects into a base-64 encoded string. The LosFormatter can serialize
any type of object that can be serialized by the BinaryFormatter class, but is built to
efficiently serialize objects of the following types:

 Strings
 Integers
 Booleans
 Arrays
 ArrayLists
 Hashtables
 Pairs
 Triplets

Note   The
Pair
and
Triplet
are two classes found in the
System.Web.UI
namespace, and provide a single class to store either two or three objects. The
Pair
class has properties
First
and
Second
to access its two elements, while
Triplet
has
First
,
Second
, and
Third
as properties.

The SavePageStateToPersistenceMedium() method is called from the Page class and


passed in the combined view state of the page's control hierarchy. When overriding this
method, we need to use the LosFormatter() to serialize the view state to a base-64
encoded string, and then store this string in a file on the Web server's file system. There
are two main challenges with this approach:

1. Coming up with an acceptable file naming scheme. Since the view state for a page
will likely vary based on the user's interactions with the page, the stored view
state must be unique for each user and for each page.
2. Removing the view state files from the file system when they are no longer
needed.

To tackle the first challenge, we'll name the persisted view state file based on the user's
SessionID and the page's URL. This approach will work beautifully for all users whose
browsers accept session-level cookies. Those who do not accept cookies, however, will
have a unique session ID generated for them on each page visit, thereby making this
naming technique unworkable for them. For this article I'm just going to demonstrate
using the SessionID / URL file name scheme, although it won't work for those whose
browsers are configured not to accept cookies. Also, it won't work for a Web farm unless
all servers store the view state files to a centralized location.

Note   One workaround would be to use a globally unique identifier (GUID) as the file
name for the persisted view state, saving this GUID in a hidden form field on the
ASP.NET Web page. This approach, unfortunately, would take quite a bit more effort
than using the
SessionID
/ URL scheme, since it involves injecting a hidden form field into the Web Form. For that
reason, I'll stick to illustrating the simpler approach for this article.
The second challenge arises because, each time a user visits a different page, a new file
holding that page's view state will be created. Over time this will lead to thousands of
files. Some sort of automated task would be needed to periodically clean out the view
state files older than a certain date. I leave this as an exercise for the reader.

To persist view state information to a file, we start by creating a class that derives from
the Page class. This derived class, then, needs to override the
SavePageStateToPersistenceMedium() and
LoadPageStateFromPersistenceMedium() methods. The following code presents such
a class:

Copy
public class PersistViewStateToFileSystem : Page
{
protected override void
SavePageStateToPersistenceMedium(object viewState)
{
// serialize the view state into a base-64 encoded string
LosFormatter los = new LosFormatter();
StringWriter writer = new StringWriter();
los.Serialize(writer, viewState);
// save the string to disk
StreamWriter sw = File.CreateText(ViewStateFilePath);
sw.Write(writer.ToString());
sw.Close();
}
protected override object LoadPageStateFromPersistenceMedium()
{
// determine the file to access
if (!File.Exists(ViewStateFilePath))
return null;
else
{
// open the file
StreamReader sr = File.OpenText(ViewStateFilePath);
string viewStateString = sr.ReadToEnd();
sr.Close();
// deserialize the string
LosFormatter los = new LosFormatter();
return los.Deserialize(viewStateString);
}
}
public string ViewStateFilePath
{
get
{
string folderName =
Path.Combine(Request.PhysicalApplicationPath,
"PersistedViewState");
string fileName = Session.SessionID + "-" +
Path.GetFileNameWithoutExtension(Request.Path).Replace("/",
"-") + ".vs";
return Path.Combine(folderName, fileName);
}
}
}

The class contains a public property ViewStateFilePath, which returns the physical
path to the file where the particular view state information will be stored. This file path is
dependent upon the user's SessionID and the URL of the requested page.

Notice that the SavePageStateToPersistenceMedium() method accepts an object


input parameter. This object is the view state object that is built up from the save view
state stage. The job of SavePageStateToPersistenceMedium() is to serialize this object
and persist it in some manner. The method's code simply creates an instance of the
LosFormatter object and invokes its Serialize() method, serializing the passed-in
view state information to the StringWriter writer. Following that, the specified file is
created (or overwritten, if it already exists) with the contents of the base-64 encoded,
serialized view state string.

The LoadPageStateFromPersistenceMedium() method is called at the beginning of the


load view state stage. Its job is to retrieve the persisted view state and deserialize back
into an object that can be propagated into the page's control hierarchy. This is
accomplished by opening the same file where the persisted view state was stored on the
last visit, and returning the deserialized version via the Deserialize() method in
LosFormatter().

Again, this approach won't work with users that do not accept cookies, but for those that
do, the view state is persisted entirely on the Web server's file system, thereby adding 0
bytes to the overall page size!

Note   Another approach to reducing the bloat imposed by view state is to compress the
serialized view state stream in the
SavePageStateToPersistenceMedium()
method, and then decompress it back to its original form in the
LoadPageStateFromPersistenceMedium()
method. Scott Galloway has a blog entry where he discusses his experiences with using
#ziplib library to compress the view state.

Parsing the View State


When a page is rendered, it serializes its view state into a base-64 encoded string using
the LosFormatter class and (by default) stores it in a hidden form field. On postback, the
hidden form field is retrieved and deserialized back into the view state's object
representation, which is then used to restore the state of the controls in the control
hierarchy. One detail we have overlooked up to this point in the article is what, exactly, is
the structure of the Page class's view state object?
As we discussed earlier, entire view state of the Page is the sum of the view state of the
controls in its control hierarchy. Put another way, at any point in the control hierarchy,
the view state of that control represents the view state of that control along with the view
state of all of its children controls. Since the Page class forms the root of the control
hierarchy, its view state represents the view state for the entire control hierarchy.

The Page class contains a SavePageViewState(), which is invoked during the page life
cycle's save view state stage. The SavePageViewState() method starts by creating a
Triplet that contains the following three items:

1. The page's hash code. This hash code is used to ensure that the view state hasn't
been tampered with between postbacks. We'll talk more about view state hashing
in the "View State and Security Implications" section.
2. The collective view state of the Page's control hierarchy.
3. An ArrayList of controls in the control hierarchy that need to be explicitly
invoked by the page class during the raise postback event stage of the life cycle.

The First and Third items in the Triplet are relatively straightforward; the Second
item is where the view state for the Page's control hierarchy is maintained. The Second
item is generated by the Page by calling the SaveViewStateRecursive() method, which
is defined in the System.Web.UI.Control class. SaveViewStateRecursive() saves the
view state of the control and its descendents by returning a Triplet with the following
information:

1. The state present in the Control's ViewState StageBag.


2. An ArrayList of integers. This ArrayList maintains the indexes of the
Control's child controls that have a non-null view state.
3. An ArrayList of the view states for the children controls. The ith view state in
this ArrayList maps to the child control index in the ith item in the ArrayList in
the Triplet's Second item.

The Control class computes the view state, returning a Triplet. The Second item of the
Triplet contains the view state of the Control's descendents. The end result is that the
view state is comprised of many ArrayLists inside of Triplets inside of Triplets,
inside of Triplets, inside of... (The precise contents in the view state depend on the
controls in the hierarchy. More complex controls might serialize their own state to the
view state using Pairs or object arrays. As we'll see shortly, though, the view state is
composed of a number of Triplets and ArrayLists nested as deep as the control
hierarchy.)

Programmatically Stepping Through the View State

With just a little bit of work we can create a class that can parse through the view state
and display its contents. The download for this article includes a class called
ViewStateParser that provides such functionality. This class contains a
ParseViewState() method that recursively steps through the view state. It takes in three
inputs:

1. The current view state object.


2. How many levels deep we are in the view state recursion.
3. A text label to display.

The last two input parameters are just for display purposes. The code of this method,
shown below, determines the type of the current view state object and displays the
contents of the view state accordingly, by recursively calling itself on each of the current
object's members. (The variable tw is a TextWriter instance to which the output is being
written.)

Copy
protected virtual void ParseViewStateGraph(
object node, int depth, string label)
{
tw.Write(System.Environment.NewLine);
if (node == null)
{
tw.Write(String.Concat(Indent(depth), label, "NODE IS NULL"));
}
else if (node is Triplet)
{
tw.Write(String.Concat(Indent(depth), label, "TRIPLET"));
ParseViewStateGraph(
((Triplet) node).First, depth+1, "First: ");
ParseViewStateGraph(
((Triplet) node).Second, depth+1, "Second: ");
ParseViewStateGraph(
((Triplet) node).Third, depth+1, "Third: ");
}
else if (node is Pair)
{
tw.Write(String.Concat(Indent(depth), label, "PAIR"));
ParseViewStateGraph(((Pair) node).First, depth+1, "First: ");
ParseViewStateGraph(((Pair) node).Second, depth+1, "Second: ");
}
else if (node is ArrayList)
{
tw.Write(String.Concat(Indent(depth), label, "ARRAYLIST"));
// display array values
for (int i = 0; i < ((ArrayList) node).Count; i++)
ParseViewStateGraph(
((ArrayList) node)[i], depth+1, String.Format("({0}) ", i));
}
else if (node.GetType().IsArray)
{
tw.Write(String.Concat(Indent(depth), label, "ARRAY "));
tw.Write(String.Concat("(", node.GetType().ToString(), ")"));
IEnumerator e = ((Array) node).GetEnumerator();
int count = 0;
while (e.MoveNext())
ParseViewStateGraph(
e.Current, depth+1, String.Format("({0}) ", count++));
}
else if (node.GetType().IsPrimitive || node is string)
{
tw.Write(String.Concat(Indent(depth), label));
tw.Write(node.ToString() + " (" +
node.GetType().ToString() + ")");
}
else
{
tw.Write(String.Concat(Indent(depth), label, "OTHER - "));
tw.Write(node.GetType().ToString());
}
}

As the code shows, the ParseViewState() method iterates through the expected types—
Triplet, Pair, ArrayList, arrays, and primitive types. For scalar values—integers,
strings, etc.—the type and value are displayed; for aggregate types—arrays, Pairs,
Triplets, etc.—the members that compose the type are displayed by recursively
invoking ParseViewState().

The ViewStateParser class can be utilized from an ASP.NET Web page (see the
ParseViewState.aspx demo), or can be accessed directly from the
SavePageStateToPersistenceMedium() method in a class that is derived from the Page
class (see the ShowViewState class). Figures 8 and9 show the ParseViewState.aspx
demo in action. As Figure 8 shows, the user is presented with a multi-line textbox into
which they can paste the hidden __VIEWSTATE form field from some Web page. Figure 9
shows a snippet of the parsed view state for a page displaying file system information in a
DataGrid.
Figure 8. Decoding ViewState

Figure 9. ViewState decoded

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

View State and Security Implications


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

1. Since the view state can be parsed, what's to stop someone from changing the
values, re-serializing it, and using the modified view state?
2. Since the view state can be parsed, does that mean I can't place any sensitive
information in the view state (such as passwords, connection strings, etc.)?

Fortunately, the LosFormatter class has capabilities to address both of these concerns, as
we'll see over the next two sections. Before we delve into the solutions for these
concerns, it is important to first note that view state should only be used to store non-
sensitive data. View state does not house code, and should definitely not be used to place
sensitive information like connection strings or passwords.

Protecting the View State from Modification

Even though view state should only store the state of the Web controls on the page and
other non-sensitive data, nefarious users could cause you headaches if they could
successfully modify the view state for a page. For example, imagine that you ran an
eCommerce Web site that used a DataGrid to display a list of products for sale along with
their cost. Unless you set the DataGrid's EnableViewState property to False, the
DataGrid's contents—the names and prices of your merchandise—will be persisted in the
view state.

Nefarious users could parse the view state, modify the prices so they all read $0.01, and
then deserialize the view state back to a base-64 encoded string. They could then send out
e-mail messages or post links that, when clicked, submitted a form that sent the user to
your product listing page, passing along the altered view state in the HTTP POST
headers. Your page would read the view state and display the DataGrid data based on this
view state. The end result? You'd have a lot of customers thinking they were going to be
able to buy your products for only a penny!

A simple means to protect against this sort of tampering is to use a machine


authentication check, or MAC. Machine authentication checks are designed to ensure that
the data received by a computer is the same data that it transmitted out—namely, that it
hasn't been tampered with. This is precisely what we want to do with the view state. With
ASP.NET view state, the LosFormatter performs a MAC by hashing the view state data
being serialized, and appending this hash to the end of the view state. (A hash is a quickly
computed digest that is commonly used in symmetric security scenarios to ensure
message integrity.) When the Web page is posted back, the LosFormatter checks to
ensure that the appended hash matches up with the hashed value of the deserialized view
state. If it does not match up, the view state has been changed en route.

By default, the LosFormatter class applies the MAC. You can, however, customize
whether or not the MAC occurs by setting the Page class's EnableViewStateMac
property. The default, True, indicates that the MAC should take place; a value of False
indicates that it should not. You can further customize the MAC by specifying what
hashing algorithm should be employed. In the machine.config file, search for the
<machineKey> element's validation attribute. The default hashing algorithm used is
SHA1, but you can change it to MD5 if you like. (For more information on the SHA1,
see RFC 3174; for more information on MD5, read RFC 1321.)

Note   When using
Server.Transfer()
you may find you receive a problem with view state authentication. A number of articles
online have mentioned that the only workaround is to set
EnableViewStateMac
to False. While this will certainly solve the problem, it opens up a security hole. For more
information, including a secure workaround, consult this KB article.

Encrypting the View State

Ideally the view state should not need to be encrypted, as it should never contain sensitive
information. If needed, however, the LosFormatter does provide limited encryption
support. The LosFormatter only allows for a single type of encryption: Triple DES. To
indicate that the view state should be encrypted, set the <machineKey> element's
validation attribute in the machine.config file to 3DES.

In addition to the validation attribute, the <machineKey> element contains


validationKey and decryptionKey attributes, as well. The validationKey attribute
specifies the key used for the MAC; decryptionKey indicates the key used in the Triple
DES encryption. By default, these attributes are set to the value
"AutoGenerate,IsolateApp," which uniquely autogenerates the keys for each Web
application on the server. This setting works well for a single Web server environment,
but if you have a Web farm, it's vital that all Web servers use the same keys for MAC
and/or encryption and decryption. In this case you'll need to manually enter a shared key
among the servers in the Web farm. For more information on this process, and the
<machineKey> element in general, refer to the <machineKey> technical documentation
and Susan Warren's article Taking a Bite Out of ASP.NET ViewState.

The ViewStateUserKey Property

Microsoft® ASP.NET version 1.1 added an additional Page class property—


ViewStateUserKey. This property, if used, must be assigned a string value in the
initialization stage of the page life cycle (in the Page_Init event handler). The point of
the property is to assign some user-specific key to the view state, such as a username. The
ViewStateUserKey, if provided, is used as a salt to the hash during the MAC.

What the ViewStateUserKey property protects against is the case where a nefarious user
visits a page, gathers the view state, and then entices a user to visit the same page,
passing in their view state (see Figure 10). For more information on this property and its
application, refer to Building Secure ASP.NET Pages and Controls.
Figure 10. Protecting against attacks using ViewStateUserKey
Conclusion
In this article we examined the ASP.NET view state, studying not only its purpose, but
also its functionality. To best understand how view state works, it is important to have a
firm grasp on the ASP.NET page life cycle, which includes stages for loading and saving
the view state. In our discussions on the page life cycle, we saw that certain stages—such
as loading postback data and raising postback events—were not in any way related to
view state.

While view state enables state to be effortlessly persisted across postbacks, it comes at a
cost, and that cost is page bloat. Since the view state data is persisted to a hidden form
field, view state can easily add tens of kilobytes of data to a Web page, thereby increasing
both the download and upload times for Web pages. To cut back on the page weight
imposed by view state, you can selectively instruct various Web controls not to record
their view state by setting the EnableViewState property to False. In fact, view state can
be turned off for an entire page by setting the EnableViewState property to false in the
@Page directive. In addition to turning off view state at the page-level or control-level,
you can also specify an alternate backing store for view state, such as the Web server's
file system.

This article wrapped up with a look at security concerns with view state. By default, the
view state performs a MAC to ensure that the view state hasn't been tampered with
between postbacks. ASP.NET 1.1 provides the ViewStateUserKey property to add an
additional level of security. The view state's data can be encrypted using the Triple DES
encryption algorithm, as well.

Happy Programming!

Works Consulted

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

Special Thanks To...

Before submitting my article to my MSDN editor I have a handful of volunteers help


proofread the article and provide feedback on the article's content, grammar, and
direction. Primary contributors to the review process for this article include James Avery,
Bernard Vander Beken, Dave Donaldson, Scott Elkin, and Justin Lovell. If you are
interested in joining the ever-growing list of reviewers, drop me a line at
mitchell@4guysfromrolla.com.

About the Author

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

Related Books

 ASP. NET: Tips, Tutorials, & Code


 Microsoft ASP.NET Coding Strategies with the Microsoft ASP.NET Team
 ASP.NET Unleashed
 Programming Microsoft ASP.NET

© 2011 Microsoft. All rights reserved.

Terms of Use | Trademarks | Privacy Statement | Feedback

ASP.NET Web Services


Introduction
We can now use ASP.NET to create Web Service that is based on industrial standards
included XML, SOAP and WSDL.

ASP.NET Web Services support clients using HTTP-POST, HTTP-GET and SOAP
protocols to invoke methods exposed, depends on your specific requirement you choose
one method over the others. The main difference between HTTP-GET or HTTP-POST
and SOAP is the data types supported by SOAP is much richer because SOAP used XSD
schema to represent complex data types.

Here are samples codes I use to test the building of ASP.NET Web Service:

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


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

Collapse
<%@ WebService Language="C#" class="MyClass" %>

using System.Web.Services ;

public class MyClass


{
[WebMethod()]
public int Add ( int a, int b)
{
return a + 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#" class="MyWebService.MyStringReverse,
MyWebServiceImpl" %>

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 /out:bin/MyWebServiceImpl.dll
MyWebServiceImpl.cs

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


Service.

Step 2: Create the ASP.NET Web Service Clients


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

Client use HTTP-POST Method


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

File: TestWebService.aspx

Collapse
<html>

<body>
<form action="http://localhost/ASP.NET/MyWebService.asmx/Add"
method="POST">

<input name="a"></input>
<input name="b"></input>

<input type="submit" value="Enter"> </input>


</form>
</body>
</html>

The ASP page accepts parameters from browser and calls the Add method of the Web
Service MyWebService via the HTTP-POST protocol, the result will be XML message
and need further parsing by the client application. To parse the response, client can use
either Java XML parser in applet or use IE5’s DOM Object.

The following is an example of XML response when parameters a=1, b=2 are inputted:

Collapse
<?xml version="1.0" encoding="utf-8" ?>
<int xmlns="http://tempuri.org/">3</int>

Client use WSDL Generated Proxy Object


If your client will be Windows applications or ASP.NET applications, you can use
WSDL.EXE utility to created standard .NET Assemble to provide Proxy Class for your
clients.

Here are steps you can follow and try:

Use WSDL.EXE utility to create the Proxy Class source file in any language you have
chosen and here I use C# and command as follows:

Collapse
C:\>wsdl /language:C# /out:MyProxyClass.cs
http://localhost/ASP.NET/MyWebService.asmx

MyProxyClass.cs is generated and source listing as follows:

File: MyProxyClass.cs

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

//
// This source code was auto-generated by wsdl, Version=1.0.2914.16.
//
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.Web.Services;

[System.Web.Services.WebServiceBindingAttribute(Name="MyClassSoap",
Namespace="http://tempuri.org/")]
public class MyClass :
System.Web.Services.Protocols.SoapHttpClientProtocol {

[System.Diagnostics.DebuggerStepThroughAttribute()]
public MyClass() {
this.Url = "http://localhost/ASP.NET/MyWebService.asmx";
}

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempu
ri.org/Add",

Use=System.Web.Services.Description.SoapBindingUse.Literal,

ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)
]
public int Add(int a, int b) {
object[] results = this.Invoke("Add", new object[] {
a,
b});
return ((int)(results[0]));
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
public System.IAsyncResult BeginAdd(int a, int b,
System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("Add", new object[] {
a,
b}, callback, asyncState);
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
public int EndAdd(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((int)(results[0]));
}
}

Then we need to create the .NET Assembly for used by clients:

Collapse
C:\> csc /t:library MyProxyClass.cs

The above command will compile the source and create MyProxyClass.dll library file.
I use ASP to depict how to use the proxy object and the file is
TestWebServiceWithProxy.aspx source listing as follows:

File: TestWebServiceWithProxy.aspx

Collapse
<%@ page language="C#" %>
<html>
<script runat="server">
void btn_click(Object source, EventArgs e)
{
MyClass mycls = new MyClass() ;
int x = Int32.Parse(a.Text) ;
int y = Int32.Parse(b.Text);

Message.Text = mycls.Add( x, y).ToString() ;


}
</script>

<body>
<form Action = "TestWebServiceWithProxy.aspx" runat="server">
<asp:TextBox id="a" runat="server" />
<asp:TextBox id="b" runat="server" />
<asp:button id=btn OnClick="btn_click" Text="Enter"
runat="server" />
<p><asp:label id="Message" runat="server" /></P>
</form>
</body>
</html>

Client use XMLHTTP to call Web service via SOAP


To fully explore the SOAP capability, you may choose to call your ASP.NET Web
Service via SOAP core protocol and here I provide another example for reference.

To test the ASP.NET service with SOAP protocol, I create an ASP client file
TestWebServiceByXML.asp and its source is listed as follows:

File: TestWebServiceByXML.asp

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

// Try to parse the XML string into DOM object


xmlObj.loadXML(sXml) ;

//To see the validated XML string is well-formed


XmlRequest.innerText = xmlObj.xml ;

var xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP") ;


xmlHTTP.Open ( "Post",
"http://localhost/ASP.NET/MyWebService.asmx", false) ;
xmlHTTP.setRequestHeader("SOAPAction",
"http://tempuri.org/Add") ;
xmlHTTP.setRequestHeader("Content-Type", "text/xml;
charset=utf-8" ) ;
xmlHTTP.Send(xmlObj.xml) ;
MyResult.innerText = xmlHTTP.responseText ;

var xmlResponse = xmlHTTP.responseXML ;


answer.innerText =
xmlResponse.selectSingleNode("soap:Envelope/soap:Body/AddResponse/AddRes
ult").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/en-
us/library/t745kdsh.aspx

.NET Framework 4
Other Versions

 Visual Studio 2008


 Visual Studio 2005

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

Getting started  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.

 Creating WCF Services for ASP.NET AJAX

Describes Windows Communication Foundation (WCF)


services that are hosted as ASP.NET compatible services.

 Web References in Visual Studio

Provides information about how to reference Web services in


Visual Studio projects and about the proxy classes that
represent a Web service. 
 Walkthrough: Creating and Using an ASP.NET Web Service in
Visual Web Developer

Provides a step-by-step tutorial on how to create an ASP.NET


Web service and how to call it.
Creating and
 How to: Add and Remove Web References
using Web
services
Describes how to use tools in Visual Studio to create a proxy
class for a Web service.

 How to: Call a Web Service

Describes how to call Web service methods.


 Using Web Services in ASP.NET AJAX

Describes ASP.NET Web services, which are ASP.NET and


Windows Communication Foundation (WCF) custom services
that are called from client script that runs in AJAX-enabled
ASP.NET Web pages. 

 Walkthrough: Creating and AJAX-enabled Web Service

Shows how to create an AJAX-enabled Web service in Visual


Studio and how to create a Web page that calls the Web service
by using client script. 
Creating and
using Web  Exposing Web Services to Client Script
services in AJAX
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 application  Using Forms Authentication with Microsoft Ajax
services in AJAX
Shows how to call the application authentication service from
client script that runs in the browser.

 Using Roles Information with Microsoft Ajax

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

 Using Profile Information with Microsoft Ajax

Shows how to call the application profile service from client


script that runs in the browser.
 ASP.NET Application Services Overview

Describes ASP.NET and Windows Communication Foundation


(WCF) application services, which provide a consistent way to
provide authentication, roles, and profile properties to any
client in order to build service-oriented applications.

 How to: Enable the WCF Authentication Service.

Shows how to use the application authentication service as a


Windows Communication Foundation (WCF) service.
Using application
 How to: Enable the WCF Role Service.
services as WCF
services
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:

 Simplicity

Disadvantages:

 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:

 Simple to implement for a page specific data


 Can store small amount of data so they take less size.

Disadvantages:

 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:
 Simple for page level data
 Encrypted 
 Can be set at the control level

Disadvantages:

 Overhead in encoding View State values


 Makes a page heavy

Query strings:

Query strings are usually used to send information from one page to another page.
They are passed along with URL in clear text. Now that cross page posting feature is
back in asp.net 2.0, Query strings seem to be redundant. Most browsers impose a
limit of 255 characters on URL length. We can only pass smaller amounts of data
using query strings. Since Query strings are sent in clear text, we can also encrypt
query values. Also, keep in mind that characters that are not valid in a URL must be
encoded using Server.UrlEncode.

Let's assume that we have a Data Grid with a list of products, and a hyperlink in the
grid that goes to a product detail page, it would be an ideal use of the Query String
to include the product ID in the Query String of the link to the product details page
(for example, productdetails.aspx?productid=4).

When product details page is being requested, the product information can be
obtained by using the following codes:

string productid;
productid=Request.Params["productid"];            

Advantages:

 Simple to Implement
Disadvantages:

 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

 In process mode (in-memory)- State information is stored in memory of web


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:

 Fastest mode 
 Simple configuration

Disadvantages:

 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:
 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:

 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:

 Supports web farm and web garden configuration


 Session state is persisted across application domain recycles and even IIS
restarts    when session is maintained on different server.

Disadvantages:

 Requires serialization of objects

Choosing between client side and Server side management techniques is driven by
various factors including available server resources, scalability and performance. We
have to leverage both client side and server side state management options to build
scalable applications. 

When leveraging client side state options, ensure that little amount of insignificant
information is exchanged between page requests. 

Various parameters should be evaluated when leveraging server side state options
including size of application, reliability and robustness. Smaller the application, In
process is the better choice. We should account in the overheads involved in
serializing and deserializing objects when using State Server and Database based
session state. Application state should be used religiously.
Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this
post Here.

Login to add your contents and source code to this article

 About the author


 

Santhosh Babu

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.

  Introducing MaxV - one click. infinite control. Hyper-V Hosting from


MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-
V 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:

 Windows (default)
 Forms
 Passport
 None

To enable an authentication provider for an ASP.NET application, use the authentication


element in either machine.config or Web.config as follows:

Copy
<system.web>
<!-- mode=[Windows|Forms|Passport|None] -->
<authentication mode="Windows" />
</system.web>

Each ASP.NET authentication provider supports an OnAuthenticate event that occurs


during the authentication process, which you can use to implement a custom
authorization scheme. The primary purpose of this event is to attach a custom object that
implements the IPrincipal Interface to the context.

Which ASP.NET authentication provider you use typically depends upon which IIS
authentication scheme you choose. If you are using any of the IIS authentication schemes
other than Anonymous, you will likely use the Windows authentication provider.
Otherwise, you will use Forms, Passport, or None.

For more information, see <authentication> Element and ASP.NET Authentication.

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

Pro

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

Con

 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 non-
ASP.NET resources, such as .htm, .jpg or .gif files.

Pros

 Makes it possible for custom authentication schemes using arbitrary criteria.


 Can be used for authentication or personalization.
 Does not require corresponding Windows accounts.

Cons

 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

 Supports single sign-in across multiple domains.


 Compatible with all browsers.

Con

 Places an external dependency for the authentication process.

Implementation
To implement Passport, you must register your site with the Passport service, accept the
license agreement, and install the Passport SDK prior to use. You must configure your
application's Web.config file as follows:

Copy
<!-- Web.config file -->
<system.web>
<authentication mode="Passport" />
</system.web>

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

None (Custom Authentication)

Specify "None" as the authentication provider when users are not authenticated at all or if
you plan to develop custom authentication code. For example, you may want to develop
your own authentication scheme using an ISAPI filter that authenticates users and
manually creates an object of the GenericPrincipal Class. For more information, see
GenericPrincipal Class.

Note   An ISAPI server extension only handles those resources for which it has an
application mapping. For example, the ASP.NET ISAPI server extension only has
application mappings for particular resources, such as .asax, .ascx, .aspx, .asmx, and
.config files to name a few. By default, the ASP.NET ISAPI server extension, and
subsequently the None (custom) authentication provider, does not process any requests
for non-ASP.NET resources, such as .htm, .jpg or .gif files.

Pros

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

Cons

 Custom-built authentication schemes are seldom as secure as those provided by


the operating system.
 Requires extra work to custom-build an authentication scheme.

Implementation

To implement no authentication or to develop your own custom authentication, create a


custom ISAPI filter to bypass IIS authentication. Use the following Web.config
configuration:

Copy
<!-- Web.config file -->
<system.web>
<authentication mode="None" />
</system.web>

See Also

Security Model | <authentication> Element | ASP.NET Authentication

© 2011 Microsoft. All rights reserved.


Terms of Use | Trademarks | Privacy Statement | Feedback

Introduction:
 
When you begin a program for a customer using ASP.Net, you should consider about
security. Security is one of the most important components of any application.
Security is even more important when you are making a web application which is
exposed to million of users. Asp.net provides classes and methods that ensure that
the application is secure from outside attacks. In this article we will investigate the
different types of authentication provided by ASP.Net. In web.config file you can set
authentication mode value 'windows' or 'forms'. What's about difference and how to
you use them? (Authentication have some other values to, this article does not
consider them.)

Configure the Security Settings in the Web.config File:

This section demonstrates how to add and modify the <authentication> and <authorization> configuration
sections to configure the ASP.NET application to use window-based or forms-based authentication.

How to use mode "Windows"?

Change the authentication mode to Windows.

Windows Authentication mode provides the developer to authenticate a user based on Windows user
accounts. This is the default authentication mode provided by ASP.Net. You can easily get the Identity of
the user by using User.Identity.Name. This will return the computer name along with the user name.
Windows authentication also provides IsInRole method to find the role of the user and than you can give
permissions to the user depending on the role.

<authentication mode="Windows">
  <forms name=" AuthenticationDemo" loginUrl="logon.aspx" protection="All"
path="/" timeout="30" />
</authentication>
 
Deny access to the anonymous user in the <authorization> section as follows:
 
<authorization>
     <deny users ="?" />
    <allow users = "*" />
</authorization>
 
Other you can make a special client to access you project with windows authentication.
Code like this (this case you can get value using 'User.Identity.Name', then you can use it
to do other work you like.):
 
<authorization>
     <deny users ="?" />
</authorization>
 
How to use mode "Forms"?

Change the authentication mode to Forms.

Insert the <Forms> tag, and fill the appropriate attributes. (For more information about these attributes,
refer to the MSDN documentation)

First you should specify a page and make sure all clients can found it. Code like this

<authentication mode="Forms">
    <forms name=" AuthenticationDemo" loginUrl="logon.aspx" protection="All"
path="/" timeout="30" />
</authentication>
 
Deny access to the anonymous user in the <authorization> section as follows:
 
<authorization>
    <deny users ="?" />
</authorization>
 
Second in that page you to validate the user's Id and Password. Code like this:

You can use one of two methods to generate the forms authentication cookie and redirect the user to an
appropriate page in the cmdLogin_ServerClick event. Sample code is provided for both scenarios. Use
either of them according to your requirement.

(1). Call the RedirectFromLoginPage method to automatically generate the forms authentication cookie
and redirect the user to an appropriate page in the cmdLogin_ServerClick event:

private void cmdLogin_ServerClick(object sender, System.EventArgs e)


{
 
     If (ValidateUser(txtUserName.Value,txtUserPass.Value) )
     {
          FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, false);
     }
     else
     {
          Response.Redirect("logon.aspx", true);
     }
}
 
(2). Generate the authentication ticket, encrypt it, create a cookie, add it to the response, and redirect the
user. This gives you more control in how you create the cookie. You can also include custom data along
with the FormsAuthenticationTicket in this case.
 
Private void cmdLogin_ServerClick(object sender, System.EventArgs e)
{
    if (ValidateUser(txtUserName.Value,txtUserPass.Value) )
    {
        FormsAuthenticationTicket tkt;
        string cookiestr;
        HttpCookie ck;
        tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now,
DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data");
        cookiestr = FormsAuthentication.Encrypt(tkt);
        ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
       
        if (chkPersistCookie.Checked)
        ck.Expires=tkt.Expiration;   
        ck.Path = FormsAuthentication.FormsCookiePath;
        Response.Cookies.Add(ck);
        string strRedirect;
        strRedirect = Request["ReturnUrl"];
       
        if (strRedirect==null)
        strRedirect = "default.aspx";
        Response.Redirect(strRedirect, true);
    }
    else
    Response.Redirect("logon.aspx", true);
}
 
Additional Notes:
 

You may want to store passwords securely in a database. You can use the
FormsAuthentication class utility function named
HashPasswordForStoringInConfigFile to encrypt the passwords before you store
them in the database or configuration file.

You may want to store the SQL connection information in the configuration file
(Web.config) so that you can easily modify it if necessary.

You may consider adding code to prevent hackers who try to use different
combinations of passwords from logging on. For example, you can include logic that
accepts only two or three logon attempts. If the user cannot log on in a certain
number of attempts, you may want to set a flag in the database to not allow that
user to log on until that user re-enables his or her account by visiting a different
page or by calling your support line. In addition, you should add appropriate error
handling wherever necessary.
Because the user is identified based on the authentication cookie, you may want to
use Secure Sockets Layer (SSL) on this application so that no one can deceive the
authentication cookie and any other valuable information that is being transmitted.

Forms-based authentication requires that your client accept or enable cookies on


their browser.

The timeout parameter of the <authentication> configuration section controls the


interval at which the authentication cookie is regenerated. You can choose a value
that provides better performance and security.

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

Asp .net Web.config Configuration File

  

What is Web.Config File?

Web.config file, as it sounds like is a configuration file for the Asp .net web application. An Asp
.net application has one web.config file which keeps the configurations required for the
corresponding application. Web.config file is written in XML with specific tags having specific
meanings.

What is Machine.config File?

   As web.config file is used to configure one asp .net web application, same way
Machine.config file is used to configure the application according to a particular machine. That is,
configuration done in machine.config file is affected on any application that runs on a particular
machine. Usually, this file is not altered and only web.config is used which configuring
applications.

What can be stored in Web.config file?

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

1. Database connections
2. Session States
3. Error Handling
4. Security

Database Connections:

   The most
important configuration data that can be stored inside the web.config file is the
database connection string. Storing the connection string in the web.config file makes sense,
since any modifications to the database configurations can be maintained at a single location. As
otherwise we'll have to keep it either as a class level variable in all the associated source files or
probably keep it in another class as a public static variable.

   But it this is stored in the Web.config file, it can be read and used anywhere in the program.
This will certainly save us a lot of alteration in different files where we used the old connection.

Lets see a small example of the connection string which is stored in the web.config file.

<configuration>

  <appSettings>

     <add key="ConnectionString"

          value="server=localhost;uid=sa;pwd=;database=DBPerson" />

  </appSettings>

</configuration>

   As you can see it is really simple to store the connection string in the web.config file. The
connection string is referenced by a key which in this case is "ConnectionString". The value
attribute of the configuration file denotes the information about the database. Here we can see
that if has database name, userid and password. You can define more options if you want.

There is a very good website that deals with all sorts of connection strings. Its called
www.connectionstrings.com , in the website you will find the connection strings for most of the
databases.

Lets see how we access the connection string from our Asp .net web application. 

using System.Configuration;

string connectionString = (string )ConfigurationSettings.AppSettings["ConnectionString"];

The small code snippet above is all that is needed to access the value stored inside the
Web.config file.
Session States:

   Session in Asp .net web application is very important. As we know that HTTP is a stateless
protocol and we needs session to keep the state alive. Asp .net stores the sessions in different
ways. By default the session is stored in the asp .net process. You can always configure the
application so that the session will be stored in one of the following ways.

1) Session State Service

   There are two main advantages of using the State Service. First the state service is not running
in the same process as the asp .net application. So even if the asp .net application crashes the
sessions will not be destroyed. Any advantage is sharing the state information across a Web
garden (Multiple processors for the same computer).

Lets see a small example of the Session State Service.

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:55455"


sqlConnectionString="data source=127.0.0.1;user id=sa;password='' cookieless="false"
timeout="20"/>

The attributes are self explanatory but I will go over them.

mode: This can be StateServer or SqlServer. Since we are using StateServer we set the mode
to StateServer.

stateConnectionString: connectionString that is used to locate the State Service. 

sqlConnectionString: The connection String of the sql server database.

cookieless: Cookieless equal to false means that we will be using cookies to store the session
on the client side.  

2) SQL Server  

The final choice to save the session information is using the Sql Server 2000 database. To use
Sql Server for storing session state you need to do the following:

1) Run the InstallSqlState.sql script on the Microsoft SQL Server where you intend to store the
session.

You web.config settings will look something like this:

<sessionState mode = "SqlServer" stateConnectionString="tcpip=127.0.0.1:45565"


sqlConnectionString="data source="SERVERNAME;user id=sa;password='' cookiesless="false"
timeout="20"/>

SQL Server lets you share session state among the processors in a Web garden or the servers in
a Web farm. Apart from that you also get additional space to store the session. And after that you
can take various actions on the session stored.

The downside is SQL Server is slow as compared to storing session in the state in process. And
also SQL Server cost too much for a small company.

3) InProc:

  This is another Session State. This one is mostly used for development purposes. The biggest
advantage of using this approach is the applications will run faster when compared to other
Session state types. But the disadvantage is Sessions are not stored when there is any problem
that occurs with the application, when there is a small change in the files etc., Also there could be
frequent loss of session data experienced.. 

Error Handling: 

Error handling is one of the most important part of any web application. Each error has to be
caught and suitable action has to be taken to resolve that problem. Asp.net web.config file lets us
configure, what to do when an error occurs in our application.

Check the following xml tag in the web.config file that deals with errors:

<customErrors mode = "On">

<error statusCode = "404" redirect = "errorPage.aspx" />

</customErrors>

This tells the Asp.net to display custom errors from a remote client or a local client and to display
a page named errorPage.aspx. Error "404" is "Page not found" error.

If custom error mode is turned "off" than you will see Asp.net default error message. This error
messages are good for debugging purposes but should never be exposed to the users. The
users should always be presented with friendly errors if any.

Security:

The most critical aspect of any application is the security. Asp.net offers many different types of
security method which can be used depending upon the condition and type of security you need.

1) No Authentication: 

No Authentication means "No Authentication" :) , meaning that Asp.net will not implement any
type of security.

2) Windows Authentication:

The Windows authentication allows us to use the windows user accounts. This provider uses IIS
to perform the actual authentication, and then passes the authenticated identity to your code. If
you like to see that what windows user is using the Asp.net application you can use:

User.Identity.Name;

This returns the DOMAIN\UserName of the current user of the local machine.

3) Passport Authentication:

Passport Authentication provider uses Microsoft's Passport service to authenticate users. You
need to purchase this service in order to use it.

4) Forms Authentication:

Forms Authentication uses HTML forms to collect the user information and than it takes required
actions on those HTML collected values.

In order to use Forms Authentication you must set the Anonymous Access checkbox checked.
Now we need that whenever user tries to run the application he/she will be redirected to the
login page.

<authentication mode="Forms">

<forms loginUrl = "frmLogin.aspx" name="3345C" timeout="1"/>

</authentication>

<authorization>

<deny users="?" />

</authorization>

As you can see we set the Authentication mode to "Forms". The forms loginUrl is the first page
being displayed when the application is run by any user.

The authorization tags has the deny users element which contains "?", this means that full
access will be given to the authenticated users and none access will be given to the
unauthenticated users. You can replace "?" with "*" meaning that all access is given to all the
users no matter what.

Final Words: 

As you have seen that Web.config file plays a very important role in the over all Asp.net
application. There are a lot more features that I have not discussed which includes caching. Try
using web.config file when you need to configure the overall application.

Mohammad Azam, also known as Azamsharp have been programming in .NET for 4 years. He is
the author of several articles. Apart from the articles Azamsharp is also the Top 50 poster on
Microsoft official forums (www.asp.net). 
At present Azamsharp is completing his undergraduate degree in Computer Science from
University of Houston and also working as a .NET consultant for cSoft Technologies.

You can reach Azamsharp at xMohammadAzamx (at) yahoo.com

  

  

Home   |   MFC   |   C++   |   Microsoft .Net   |   Asp .Net   |   Win32

Introduction:

Sponsored Links

Caching is one of the coolest features in Asp.net. Caching enables you to store the
expensive data into Cache object and later retrieve it without doing expensive operations.
A very common example where you want to use caching is datagrid paging. I am sure
you all are familiar with datagrid paging which enables you to view the records in
multiple pages. Each time you visit a different page all the records are fetched from the
database. This becomes very expensive operation. Caching can save a lot of expensive
operations since you can store all the records in the cache object and use the cache object
as the data source. In this article we will see some important features that caching
provides.

Output Caching:

Output caching is used for pages and is also known as Page-level caching. All you need
to do to enable output caching is to add a directive in your html view of the aspx page.
The output directive can be written like this:
@ OutputCache Duration="60" VaryByParam="none"

The page will be cached for 60 seconds the VaryByParam attribute is set to "none" which
means that there is no sort of caching implemented. Hence if the first user requested page
which contains item1 than the second user will also see item1 even if he is requesting
item2.

That's why we always specify what the caching depends on.

@ OutputCache Duration="60" VaryByParam="Category"

In the above OutputCache directive you can notice that I changed the VaryByParam
attribute to "Category" which means that now the result of caching depends upon
Category. Here Category represents the name of the column in the database.

Programmatic Page Caching

You can also use caching programmatically, meaning that you can change the value of
cache depending upon the tasks performed by the user. The Response.Cache class let's
you access the functionality to work with the cache object.

You can change the expiration time on the Cache using the SetExpires method of the
Response.Cache class.

Response.Cache.SetExpires(System.DateTime.Now.AddMinutes(10));

In the same way you can also use Response.Cache.VaryByParams to set the Params
programmatically.

Accessing Caching in the Class Libraries

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

Data Caching

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

Sponsored Links

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

private void Button3_Click(object sender, System.EventArgs e)

if(Cache["MyArticles"] == null)

// Go to the database and fetch the result in the DataSet

// Assign the dataset to the Cache object

// Cache["MyArticles"] = ds

else

// This means that Cache is not empty and there is data in the cache

// Extract the value of Cache object to the DataSet

// DataSet ds = (DataSet) Cache["MyArticles"]


}

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

Caching Page Fragments

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

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

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

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

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

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


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

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

4Share

Read Next: Configuring and Deploying ASP.NET Applications

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

Search

Post Your Comment

                                                            

Introduction
The majority [if not all] of the pages in a dynamic website are dynamic. That is, pages
that are created on user request. As we all know, dynamic web pages help to provide
dynamic content, customized for the user requesting the page [e.g.: the user's home page].
Dynamic pages also help provide dynamic content fetched from a changing data store
without the need for the administrator to change the page content every time something
changes in the data store [e.g.: Listing of books in a publisher's website]. The
disadvantage is the overhead in creating the pages for every user request.

To overcome this, some websites have page creation engines which create all pages in
one go and save them as HTML pages which are then served to the users. But this will
only help in scenarios where the page content is the same for all requests [user-
independent] 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:

 Duration - The time in seconds of how long the output should be cached. After
the specified duration has elapsed, the cached output will be removed and page
content generated for the next request. That output will again be cached for 10
seconds and the process repeats.
 VaryByParam - This attribute is compulsory and specifies the querystring
parameters to vary the cache.

In the above snippet, we have specified the VaryByParam attribute as None which
means the page content to be served is the same regardless of the parameters
passed through the querystring [see Example 1 in the sample download].

If there are two requests to the same page with varying querystring parameters,
e.g.: .../PageCachingByParam.aspx?id=12 and .../PageCachingByParam.aspx?
id=15] and separate page content is generated for each of them, the directive
should be:

Collapse

<%@ OutputCache Duration=5 VaryByParam="id" %>

The page content for the two requests will each be cached for the time specified
by the Duration attribute [see Example 2 in the sample download].

To specify multiple parameters, use semicolon to separate the parameter names. If


we specify the VaryByParam attribute as *, the cached content is varied for all
parameters passed through the querystring.

Some pages generate different content for different browsers. In such cases, there is
provision to vary the cached output for different browsers. The @OutputCache directive
has to be modified to:

Collapse
<%@ OutputCache Duration=5 VaryByParam="id" VaryByCustom="browser" %>

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

Caching page fragments


Sometimes we might want to cache just portions of a page. For example, we might have a
header for our page which will have the same content for all users. There might be some
text/image in the header which might change everyday. In that case, we will want to
cache this header for a duration of a day.

The solution is to put the header contents into a user control and then specify that the user
control content should be cached. This technique is called fragment caching.

To specify that a user control should be cached, we use the @OutputCache directive just
like we used it for the page.

Collapse
<%@ OutputCache Duration=10 VaryByParam="None" %>

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

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

Collapse
Cache["name"]="Smitha";

The stored string value can be retrieved like this:

Collapse
if (Cache["name"] != null)
Label1.Text= Cache["name"].ToString();

[See example 4 for an illustration.]

To insert objects into the cache, the Add method or different versions of the Insert
method of the Cache class can be used. These methods allow us to use the more powerful
features provided by the Cache class. One of the overloads of the Insert method is used
as follows:

Collapse
Cache.Insert("Name", strName,
new CacheDependency(Server.MapPath("name.txt"),
DateTime.Now.AddMinutes(2), TimeSpan.Zero);

The first two parameters are the key and the object to be inserted. The third parameter is
of type CacheDependency and helps us set a dependency of this value to the file named
name.txt. So whenever this file changes, the value in the cache is removed. We can
specify null to indicate no dependency. The fourth parameter specifies the time at which
the value should be removed from cache. [See example 5 for an illustration.] The last
parameter is the sliding expiration parameter which shows the time interval after which
the item is to be removed from the cache after its last accessed time.

The cache automatically removes the least used items from memory, when system
memory becomes low. This process is called scavenging. We can specify priority values
for items we add to the cache so that some items are given more priority than others:

Collapse
Cache.Insert("Name", strName,
new CacheDependency(Server.MapPath("name.txt"),
DateTime.Now.AddMinutes(2), TimeSpan.Zero,
CacheItemPriority.High, null);

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

How to Deploy ASP.NET Web Application


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

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

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

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

Copy Web Site


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

The reduced error checking is a direct result to that no compilation is performed and
hence some errors may be discovered by your users later. The initial page load slowness
is also because nothing is compiled yet and the entire web application has to be compiled
at the time the first page is being requested. An advantage of this technique over the
XCOPY deployment is that you have the options to deploy to the File System, the Local
IIS, the FTP Sites, and the Remote Sites. Please see figure 1.

Figure 1

Pre-compilation
All of the deployment methods we mentioned so far suffer from the fact of that no
compilation is performed along with the disadvantages that comes as a direct result from
this fact. To ensure fast page load and some protection of your source code, you should
pre-compile your web site before deployment.

Pre-compilation can be performed in-place by just adding '/Deployment/Precompile.axd'


to the root URL of your web application and opening the resulting URL in Internet
Explore.

Pre-compilation can also be achieved using the command line compiler


'aspnet_compiler'.

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

Figure 2

SETUP Projects

It's always desirable to package your web applications such that they are easy to deploy
on the production server. Microsoft Visual Studio 2005 gives you this rich packaging
option for free ... Just follow the following instructions ...
First of all you need to know that our target is to create a package (and MSI file) that
contain our web application in a form that can be later easily deployed on the final
production server.

Let's start by selecting 'File / New / Project' in Microsoft Visual Studio 2005. This will
present you the famous set of possible project types from which you will select 'Other
Project Types / Setup and Deployment' then you will select the 'Web Setup  Project' icon
from the side to the right. See figure 3.

Figure 3

In figure 3, set the appropriate project name and folder options then click OK.

You can always have the same behavior by adding the SETUP project above to your web
application solution instead of creating a new separate solution. You can achieve this by
selecting  'File / Add / New Project' instead of 'File / New / Project'. This way you will
have a self contained web solution. The 'File / Add / New Project' method is much more
recommended.

Your setup project will then open as in figure 4 below:


Figure 4

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

Figure 5
To tune the properties of our SETUP project, we will need to press F4 while it's name is
selected in the solution explore. This will bring the SETUP project's properties window.
Several useful properties can be set in this window:

Property Purpose
Author, Description,
Manufacturer,
Use all of these properties to identify / describe your
ManufacturerUrl,
application and yourself.
ProductName, Subject, Title,
and Version
Here you can specify the icon to be displayed beside your
AddRemoveProgramsIcon application in Windows Control Panel's Add Remove
Programs.
Specify here whether or not a check is to be performed to
DetectNewerInstalledVersion determine the existence of a new version already installed
of your web application.
Specify here whether you need an older version of your web
RemovePreviousVersions application to be removed if a newer version is being
installed.
Some web applications requires the Internet Information
Service to be stopped and then restarted after the
RestartWWWService
deployment of the application. Use this property to control
such behavior.

The last and most important step is to actually build our SETUP project. This cane be
achieved by right clicking the name of our SETUP project in the solution explorer. It's
this specific step that creates the MSI package / file mentioned above. This is the file you
will need to distribute to your users and this is the file they will use to deploy the web
application on their production server.

It's worth mentioning that the actual deployment process will be some what similar to the
SETUP of any typical desktop application (with some exceptions of course). One of the
many similarities is that the web application after deployment will automatically appear
in the 'Add / Remove Programs' window of Windows Control Panel.

Production Server Deployment


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

Protection and obfuscation of .NET executable files


(.exe, .dll,...)
You must know that every of your .NET products, web application or ASP.NET custom
control, can be easily decompiled. Practically every user can get your source code by
using some free .Net decompiler. If your license doesn't include source code it is not
enough to just exclude source code files from installation. You need additional
protection.

After long analyze, we decided to use Spices.Net for protection of all products of Bean
Software. Even if you can't afford complete suite, consider at least their Obfuscator.
Later, I discovered .NET Reactor which also looks good and it is about ten times
cheaper :). You can check Product Comparison link on NetReactor site where it is
compared to some other products, it looks really impressive, and not only in price issue.

For further information


Refer to the online copy of Microsoft Developers Network at http://msdn.microsoft.com
or use your own local copy of MSDN.
Crystal Reports in ASP.NET
Crystal Reports is the standard reporting tool for Visual Studio .NET used to display data
of presentation quality. You can display multiple-level totals, charts to analyze data, and
much more in Crystal Reports. Creating a Crystal Report requires minimal coding since it
is created in Designer interface. It is available as an integrated feature of Microsoft
Visual Studio .NET, Borland Delphi, and C#Builder.

Advantages of Crystal Reports


Some of the major advantages of using Crystal Reports are:

1. Rapid report development since the designer interface would ease the coding work for
the programmer.

2. Can extend it to complicated reports with interactive charts and enhance the
understanding of the business model

3. Exposes a report object model, can interact with other controls on the ASP.NET Web
form

4. Can programmatically export the reports into widely used formats like .pdf, .doc,
.xls, .html and .rtf

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

The Pull Method


When this model is used to access data from the data source, the database driver directly
retrieves the data from the data source. This model does not require the developer to write
code for creating a connection and retrieving data from the data source. It is the Crystal
report that manages the SQL commands for connecting by using the specified driver.
The Push Method
When this model is used to access data from data source, the developer writes the code to
connect to the data source and retrieve data. The data from the data source is cached in
dataset and multiple crystal reports accesses data from the dataset. The performance can
be optimized in this manner by using connection sharing and manually limiting the
number of records that are passed on to the report.

Crystal Reports Types


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

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

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

Creating Crystal Reports

You can create a Crystal Report by using three methods:

1. Manually i.e. from a blank document


2. Using Standard Report Expert
3. From an existing report
Using Pull Method
Creating Crystal Reports Manually.

We would use the following steps to implement Crystal Reports using the Pull Model:

1. Create the .rpt file (from scratch) and set the necessary database connections using
the Crystal Report Designer interface.

2. Place a CrystalReportViewer control from the toolbox on the .aspx page and set its
properties to point to the .rpt file that we created in the previous step.

3. Call the databind method from your code behind page.

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


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

2) On the "Crystal Report Gallery" pop up, select the "As a Blank Report" radio button
and click "ok".
3) This should open up the Report File in the Crystal Report Designer.

4) Right click on the "Details Section" of the report, and select "Database" ->
"Add/Remove Database".
5) In the "Database Expert" pop up window, expand the "OLE DB (ADO)" option by
clicking the "+" sign, which should bring up another "OLE DB (ADO)" pop up.

6) In the "OLE DB (ADO)" pop up, Select "Microsoft OLE DB Provider for SQL
Server" and click Next.

7) Specify the connection information.

8) Click "Next" and then click "Finish"

9) Now you should be able to see the Database Expert showing the table that have been
selected

10) Expand the "Pubs" database, expand the "Tables", select the "Stores" table and click
on ">" to include it into the "Selected Tables" section.

Note: If you add more than one table in the database Expert and the added tables have
matching fields, when you click the OK button after adding the tables, the links between
the added tables is displayed under the Links tab. You can remove the link by clicking
the Clear Links button.
11) Now the Field Explorer should show you the selected table and its fields under the
"Database Fields" section, in the left window.

12) Drag and drop the required fields into the "Details" section of the report. The field
names would automatically appear in the "Page Header" section of the report. If you want
to modify the header text then right click on the text of the "Page Header" section, select
"Edit Text Object" option and edit it.

13) Save it and we are through.

II. Creating a Crystal Report Viewer Control


1) Drag and drop the "Crystal Report Viewer>" from the web forms tool box on to the
.aspx page

2) Open the properties window for the Crystal Report Viewer control.

3) Click on the [...] next to the "Data Binding" Property and bring up the data binding
pop-up window

4) Select "Report Source".


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

6) You should be able to see the Crystal Report Viewer showing you a preview of actual
report file using some dummy data and this completes the inserting of the Crystal Report
Viewer controls and setting its properties.

Note: In the previous example, the CrystalReportViewer control was able to directly load
the actual data during design time itself as the report was saved with the data. In this case,
it will not display the data during design time as it not saved with the data - instead it will
show up with dummy data during design time and will fetch the proper data only at run
time.

7) Call the Databind method on the Page Load Event of the Code Behind file (.aspx.vb).
Build and run your .aspx page. The output would look like this.

Using a PUSH model


1. Create a Dataset during design time.

2. Create the .rpt file (from scratch) and make it point to the Dataset that we created in the
previous step.
3. Place a CrystalReportViewer control on the .aspx page and set its properties to point to
the .rpt file that we created in the previous step.

4. In your code behind page, write the subroutine to make the connections to the database
and populate the dataset that we created previously in step one.

5. Call the Databind method from your code behind page.

I. Creating a Dataset during Design Time to Define the


Fields of the Reports
1) Right click on "Solution Explorer", select "Add" --> select "Add New Item" --> Select
"DataSet"

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

3) This should create a definition of the "Stores" table within the Dataset
The .xsd file created this way contains only the field definitions without any data in it. It
is up to the developer to create the connection to the database, populate the dataset and
feed it to the Crystal Report.

II. Creating the .rpt File


4) Create the report file using the steps mentioned previously. The only difference here is
that instead of connecting to the Database thru Crystal Report to get to the Table, we
would be using our DataSet that we just created.

5) After creating the .rpt file, right click on the "Details" section of the Report file, select
"Add/Remove Database"

6) In the "Database Expert" window, expand "Project Data" (instead of "OLE DB" that
was selected in the case of the PULL Model), expand "ADO.NET DataSet", "DataSet1",
and select the "Stores"table.

7) Include the "Stores" table into the "Selected Tables" section by clicking on ">" and
then Click "ok"

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

III. Creating a CrystalReportViewer Control


9) Follow the steps mentioned previously in the PULL Model to create a Crystal Report
Viewer control and set its properties.

Code Behind Page Modifications: 10) Call this subroutine in your page load event:

    Sub BindReport()


        Dim myConnection As New SqlClient.SqlConnection()
        myConnection.ConnectionString = "server=
(local)\NetSDK;database=pubs;Trusted_Connection=yes"
        Dim MyCommand As New SqlClient.SqlCommand()
        MyCommand.Connection = myConnection
        MyCommand.CommandText = "Select * from Stores"
        MyCommand.CommandType = CommandType.Text
        Dim MyDA As New SqlClient.SqlDataAdapter()
        MyDA.SelectCommand = MyCommand
        Dim myDS As New Dataset1()
        'This is our DataSet created at Design Time     
        MyDA.Fill(myDS, "Stores")
        'You have to use the same name as that of your Dataset that you created during
design time
        Dim oRpt As New CrystalReport1()
        ' This is the Crystal Report file created at Design Time
        oRpt.SetDataSource(myDS)
        ' Set the SetDataSource property of the Report to the Dataset
        CrystalReportViewer1.ReportSource = oRpt
        ' Set the Crystal Report Viewer's property to the oRpt Report object that we created
    End Sub

Note: In the above code, you would notice that the object oRpt is an instance of the
"Strongly Typed" Report file. If we were to use an "UnTyped" Report then we would
have to use a ReportDocument object and manually load the report file into it.

Enhancing Crystal Reports


Accessing filtered data through Crystal reports
Perform the following steps for the same.

1. Generate a dataset that contains data according to your selection criteria, say "where
(cost>1000)".

2. Create the Crystal Report manually. It would look like this.

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

The group name field is created, since the data needs to be grouped on the basis of the cat
id say.

4. A plus sign is added in front of Group Name Filed in the field explorer window. The
Group Name Field needs to be added to the Group Header section of the Crystal Report.
Notice this is done automatically.

5. Right Click the running total field and select new. Fill the required values through >
and the drop down list.
6. Since the count of number of categories is to be displayed for the total categories, drag
RTotal0 to the footer of the report.

Create a formula
Suppose if the report required some Calculations too. Perform the following steps:

1. Right Click the formula Fields in the field explorer window and select new. Enter any
relevant name, say percentage.

2. A formula can be created by using the three panes in the dialog box. The first pane
contains all the crystal report fields, the second contains all the functions, such as Avg,
Sin, Sum etc and the third contains operators such as arithmetic, conversion and
comparison operators.

3. Double click any relevant field name from the forst pane, say there's some field like
advance from some CustOrder table. Then expand Arithmetic from the third pane and
double click Divide operator.

4. Double click another field name from the first which you want to use as divisor of the
first field name already selected say it is CustOrder.Cost.

5. Double Click the Multiply from third pane and the type 100.

6. The formula would appear as {CustOrder.Advance}/{ CustOrder.Cost} * 100.

7. Save the formula and close Formula Editor:@Percentage dialog box.

8. Insert the percentage formula field in the details pane.

9. Host the Crystal report.

Exporting Crystal reports


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

You can opt to export your report file into one of the following formats:

o PDF (Portable Document Format)


o DOC (MS Word Document)

o XLS (MS Excel Spreadsheet)

o HTML (Hyper Text Markup Language - 3.2 or 4.0 compliant)

o RTF (Rich Text Format)

To accomplish this you could place a button on your page to trigger the export
functionality.

When using Crystal Reports in ASP.NET in a Web Form, the CrystalReportViewer


control does not have the export or the print buttons like the one in Windows Form. We
can still achieve some degree of export and print functionality by writing our own code to
handle exporting. If we export to PDF format, Acrobat can be used to handle the printing
for us and saving a copy of the report.

Exporting a Report File Created using the PULL Model


Here the Crystal Report takes care of connecting to the database and fetching the required
records, so you would only have to use the below given code in the Event of the button.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As


System.EventArgs) Handles Button1.Click
        Dim myReport As CrystalReport1 = New CrystalReport1()
        'Note : we are creating an instance of the strongly-typed Crystal Report file here.
 
        Dim DiskOpts As CrystalDecisions.Shared.DiskFileDestinationOptions = New
CrystalDecisions.Shared.DiskFileDestinationOptions
        myReport.ExportOptions.ExportDestinationType = CrystalDecisions.
[Shared].ExportDestinationType.DiskFile
        ' You also have the option to export the report to other sources
        ' like Microsoft Exchange, MAPI, etc.       
 
        myReport.ExportOptions.ExportFormatType = CrystalDecisions.
[Shared].ExportFormatType.PortableDocFormat
        'Here we are exporting the report to a .pdf format.  You can
        ' also choose any of the other formats specified above.
 
        DiskOpts.DiskFileName = "c:\Output.pdf"
        'If you do not specify the exact path here (i.e. including
        ' the drive and Directory),
        'then you would find your output file landing up in the
        'c:\WinNT\System32 directory - atleast in case of a
        ' Windows 2000 System
        myReport.ExportOptions.DestinationOptions = DiskOpts
        'The Reports Export Options does not have a filename property
        'that can be directly set. Instead, you will have to use
        'the DiskFileDestinationOptions object and set its DiskFileName
        'property to the file name (including the path) of your  choice.
        'Then you would set the Report Export Options
        'DestinationOptions property to point to the
        'DiskFileDestinationOption object.
 
        myReport.Export()
        'This statement exports the report based on the previously set properties.
 
    End Sub

Exporting a Report File Created Using the PUSH


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

Crystal Reports alternatives


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

Creating webservice:

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service () {

        //Uncomment the following line if using designed components


        //InitializeComponent();
    }

    [WebMethod]
    public string HelloWorld() {
        return "Hello World";
    }
    [WebMethod(Description="Sum of two No's")]
    public int sum(int a, int b)
    {
        return a + b;
    }
    [WebMethod]
    public int Mul(int a, int b)
    {
        return a * b;
    }
   
}

After excuting webservice it will generate XML format result.

  <?xml version="1.0" encoding="utf-8" ?>


  <int xmlns="http://tempuri.org/">2</int>

copy the url  before invoke


http://localhost:1103/WebSite1/Service.asmx

After that create website then goto Addwebreference click on it paste the url and click go
button and then give the webservice name click add webreference. it will generate proxy
class with the name of webservice name.

then consume the webservice in website.

Code of Consuming the webservice:

 protected void Mul_Click(object sender, EventArgs e)


    {
        triveniWS.Service ob = new triveniWS.Service();
        Label1.Text =ob.Mul(int.Parse(TextBox1.Text),
int.Parse(TextBox2.Text)).ToString();
    }
    protected void Add_Click(object sender, EventArgs e)
    {
        triveniWS.Service ob = new triveniWS.Service();
        Label1.Text = ob.sum(int.Parse(TextBox1.Text),
int.Parse(TextBox2.Text)).ToString();
    }

Delete

Reply Forw ard

Spam

Move...

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


Go

| Full Headers
Reply Reply All Forward Forward

Check Mail

New

Mail Search
Mail Search

WelcomeInboxNewFoldersMail Options

You might also like