NOTES
NOTES
Stage
Description
Page request
The page request occurs before the page life cycle begins. When the page
is requested by a user, ASP.NET determines whether the page needs to be
parsed and compiled (therefore beginning the life of a page), or whether a
cached version of the page can be sent in response without running the
page.
Start
In the start stage, page properties such as Request and Response are set.
At this stage, the page also determines whether the request is a postback
or a new request and sets the IsPostBack property. The page also sets
the UICulture property.
Initialization
During page initialization, controls on the page are available and each
control's UniqueID property is set. A master page and themes are also
applied to the page if applicable. If the current request is a postback, the
postback data has not yet been loaded and control property values have
not been restored to the values from view state.
Load
Postback
event
handling
If the request is a postback, control event handlers are called. After that,
the Validate method of all validator controls is called, which sets
the IsValid property of individual validator controls and of the page.
(There is an exception to this sequence: the handler for the event that
caused validation is called after validation.)
Rendering
Before rendering, view state is saved for the page and all controls. During
the rendering stage, the page calls the Render method for each control,
providing a text writer that writes its output to the OutputStream object of
the page's Response property.
Unload
The Unload event is raised after the page has been fully rendered, sent to
the client, and is ready to be discarded. At this point, page properties such
as Response and Request are unloaded and cleanup is performed.
Life-Cycle Events
Within each stage of the life cycle of a page, the page raises events that you can handle
to run your own code. For control events, you bind the event handler to the event, either
declaratively using attributes such as onclick, or in code.
Pages also support automatic event wire-up, meaning that ASP.NET looks for methods
with particular names and automatically runs those methods when certain events are
raised. If the AutoEventWireup attribute of the @ Page directive is set to true, page
events are automatically bound to methods that use the naming convention
of Page_event, such as Page_Load and Page_Init. For more information on automatic
event wire-up, see ASP.NET Web Server Control Event Model.
The following table lists the page life-cycle events that you will use most frequently.
There are more events than those listed; however, they are not used for most pageprocessing scenarios. Instead, they are primarily used by server controls on the ASP.NET
Web page to initialize and render themselves. If you want to write custom ASP.NET server
controls, you need to understand more about these events. For information about
creating custom controls, seeDeveloping Custom ASP.NET Server Controls.
Page Event
Typical Use
PreInit
Raised after the start stage is complete and before the initialization stage begins.
Use this event for the following:
Check the IsPostBack property to determine whether this is the first time th
The IsCallback andIsCrossPagePostBack properties have also been set at
Create or re-create dynamic controls.
Set a master page dynamically.
Set the Theme property dynamically.
Read or set profile property values.
Note
If the request is a postback, the values of the controls have not yet been re
you set a control property at this stage, its value might be overwritten in t
Init
Raised after all controls have been initialized and any skin settings have been app
individual controls occurs before the Init event of the page.
Use this event to read or initialize control properties.
InitComplete
Raised at the end of the page's initialization stage. Only one operation takes plac
the Init and InitComplete events: tracking of view state changes is turned on. Vie
controls to persist any values that are programmatically added to the ViewState c
tracking is turned on, any values added to view state are lost across postbacks. C
view state tracking immediately after they raise their Init event.
Use this event to make changes to view state that you want to make sure are pers
PreLoad
Raised after the page loads view state for itself and all controls, and after it proce
included with theRequest instance.
Load
The Page object calls the OnLoad method on the Page object, and then recursive
child control until the page and all controls are loaded. The Load event of individ
the Load event of the page.
Use the OnLoad event method to set properties in controls and to establish datab
Control events
Use these events to handle specific control events, such as a Button control's Clic
a TextBox control's TextChangedevent.
Note
In a postback request, if the page contains validator controls, check the IsValid p
individual validation controls before performing any processing.
LoadComplete
PreRender
Raised after the Page object has created all controls that are required in order to r
child controls of composite controls. (To do this, the Page object calls EnsureChi
and for the page.)
The Page object raises the PreRender event on the Page object, and then recursiv
child control. ThePreRender event of individual controls occurs after the PreRen
Use the event to make final changes to the contents of the page or its controls be
begins.
PreRenderComplete
Raised after each data bound control whose DataSourceID property is set calls it
more information, seeData Binding Events for Data-Bound Controls later in this
SaveStateComplete
Raised after view state and control state have been saved for the page and for all
page or controls at this point affect rendering, but the changes will not be retrieve
Render
This is not an event; instead, at this stage of processing, the Page object calls this
ASP.NET Web server controls have a Render method that writes out the control's
browser.
If you create a custom control, you typically override this method to output the c
your custom control incorporates only standard ASP.NET Web server controls an
do not need to override theRender method. For more information, see Developin
Controls.
A user control (an .ascx file) automatically incorporates rendering, so you do not
control in code.
Unload
page OnLoad method with the override keyword (Overrides in Visual Basic), you must
explicitly call the base method. For example, if you override the OnLoad method on the
page, you must call base.Load (MyBase.Load in Visual Basic) in order for the base
implementation to be run.
The following illustration shows some of the most important methods of the Page class
that you can override in order to add code that executes at specific points in the page life
cycle. (For a complete list of page methods and events, see the Page class.) The
illustration also shows how these methods relate to page events and to control events.
The sequence of methods and events in the illustration is from top to bottom, and within
each row from left to right.
Control Event
Typical Use
DataBinding
Raised after the control's PreRender event, which occurs after the
page's PreRender event. (This applies to controls whose DataSourceID property
is set declaratively. Otherwise the event happens when you call the
control's DataBind method.)
This event marks the beginning of the process that binds the control to the data.
Use this event to manually open database connections, if required, and to set
parameter values dynamically before a query is run.
RowCreated (Grid
View only)
or ItemCreated(Dat
aList, DetailsView,
SiteMapPath, Data
Grid,FormView, Re
peater,
and ListView contr
ols)
RowDataBound (G
ridView only)
or ItemDataBound(
DataList, SiteMapP
ath, DataGrid, Repe
ater,
andListView contro
ls)
DataBound
controls that depend on values from the current control's content. (For more
information, see Catch-Up Events for Added Controls earlier in this topic.)
Control
Event
Typical Use
LoggingIn
Raised during a postback, after the page's LoadComplete event has occurred.
This event marks the beginning of the login process.
Use this event for tasks that must occur prior to beginning the authentication
process.
Authenticate
LoggedIn
Raised after the user name and password have been authenticated.
Use this event to redirect to another page or to dynamically set the text in the
control. This event does not occur if there is an error or if authentication fails.
LoginError
User makes a request for accessing application resource, a page. Browser sends
this request to the web server.
A unified pipeline receives the first request and the following events take place:
o
The Page class creates a hierarchical tree of all the controls on the page. All the
components on the page, except the directives are part of this control tree. You can see
the control tree by adding trace= "true" to the Page directive. We will cover page
directives and tracing under 'directives' and 'error handling'.
The page life cycle phases are:
Initialization
Page rendering
Understanding the page cycle helps in writing codes for making some specific thing
happen at any stage of the page life cycle. It also helps in writing custom controls and
initializing them at right time, populate their properties with view-state data and run
control behavior code.
Following are the different stages of an ASP.Net page:
Page request . when ASP.Net gets a page request, it decides whether to parse
and compile the page or there would be a cached version of the page; accordingly
the response is sent
Starting of page life cycle . at this stage, the Request and Response objects
are set. If the request is an old request or post back, the IsPostBack property of
the page is set to true. The UICulture property of the page is also set.
Page initialization . at this stage, the controls on the page are assigned unique
ID by setting the UniqueID property and themes are applied. For a new request
postback data is loaded and the control properties are restored to the view-state
values.
Page load . at this stage, control properties are set using the view state and
control state values.
Postback event handling . if the request is a postback (old request), the related
event handler is called.
Page rendering . at this stage, view state for the page and all controls are
saved. The page calls the Render method for each control and the output of
rendering is written to the OutputStream class of the Page's Response property.
Unload . the rendered page is sent to the client and page properties, such as
Response and Request are unloaded and all cleanup done.
PreInit . PreInit is the first event in page life cycle. It checks the IsPostBack
property and determines whether the page is a postback. It sets the themes and
master pages, creates dynamic controls and gets and sets profile property values.
This event can be handled by overloading the OnPreInit method or creating a
Page_PreInit handler.
Init . Init event initializes the control property and the control tree is built. This
event can be handled by overloading the OnInit method or creating a Page_Init
handler.
InitComplete . InitComplete event allows tracking of view state. All the controls
turn on view-state tracking.
LoadPostData . during this phase, the contents of all the input fields defined
with the <form> tag are processed.
PreLoad . PreLoad occurs before the post back data is loaded in the controls. This
event can be handled by overloading the OnPreLoad method or creating a
Page_PreLoad handler.
Load . the Load event is raised for the page first and then recursively for all child
controls. The controls in the control tree are created. This event can be handled
by overloading the OnLoad method or creating a Page_Load handler.
LoadComplete . the loading process is completed, control event handlers are run
and page validation takes place. This event can be handled by overloading the
OnLoadComplete method or creating a Page_LoadComplete handler.
PreRender . the PreRender event occurs just before the output is rendered. By
handling this event, pages and controls can perform any updates before the
output is rendered.
Later, if user requests a page from your site again, when the user enters the URL the
browser looks on the local hard disk for a cookie associated with the URL. If the cookie
exists, the browser sends the cookie to your site along with the page request. Your
application can then determine the date and time that the user last visited the site. You
might use the information to display a message to the user or check an expiration date.
Cookies are associated with a Web site, not with a specific page, so the browser and
server will exchange cookie information no matter what page the user requests from your
site. As the user visits different sites, each site might send a cookie to the user's browser
as well; the browser stores all the cookies separately.
Cookies help Web sites store information about visitors. More generally, cookies are one
way of maintaining continuity in a Web applicationthat is, of performing state
management. Except for the brief time when they are actually exchanging information,
the browser and Web server are disconnected. Each request a user makes to a Web
server is treated independently of any other request. Many times, however, it's useful for
the Web server to recognize users when they request a page. For example, the Web
server on a shopping site keeps track of individual shoppers so the site can manage
shopping carts and other user-specific information. A cookie therefore acts as a kind of
calling card, presenting pertinent identification that helps an application know how to
proceed.
Cookies are used for many purposes, all relating to helping the Web site remember users.
For example, a site conducting a poll might use a cookie simply as a Boolean value to
indicate whether a user's browser has already participated in voting so that the user
cannot vote twice. A site that asks a user to log on might use a cookie to record that the
user already logged on so that the user does not have to keep entering credentials.
Cookie Limitations
Most browsers support cookies of up to 4096 bytes. Because of this small limit, cookies
are best used to store small amounts of data, or better yet, an identifier such as a user
ID. The user ID can then be used to identify the user and read user information from a
database or other data store. (See the section "Cookies and Security" below for
information about security implications of storing user information.)
Browsers also impose limitations on how many cookies your site can store on the user's
computer. Most browsers allow only 20 cookies per site; if you try to store more, the
oldest cookies are discarded. Some browsers also put an absolute limit, usually 300, on
the number of cookies they will accept from all sites combined.
A cookie limitation that you might encounter is that users can set their browser to refuse
cookies. If you define a P3P privacy policy and place it in the root of your Web site, more
browsers will accept cookies from your site. However, you might have to avoid cookies
altogether and use a different mechanism to store user-specific information. A common
method for storing user information is session state, but session state depends on
cookies, as explained later in the section "Cookies and Session State."
Note
For more information on state management and options for saving information in a Web application, s
Management Overview andASP.NET State Management Recommendations.
Although cookies can be very useful in your application, the application should not
depend on being able to store cookies. Do not use cookies to support critical features. If
your application must rely on cookies, you can test to see whether the browser will
accept cookies. See the "Checking Whether a Browser Accepts Cookies" section later in
this topic.
Writing Cookies
The browser is responsible for managing cookies on a user system. Cookies are sent to
the browser via the HttpResponse object that exposes a collection called Cookies. You
can access the HttpResponse object as the Response property of your Page class. Any
cookies that you want to send to the browser must be added to this collection. When
creating a cookie, you specify a Name and Value. Each cookie must have a unique name
so that it can be identified later when reading it from the browser. Because cookies are
stored by name, naming two cookies the same will cause one to be overwritten.
You can also set a cookie's date and time expiration. Expired cookies are deleted by the
browser when a user visits the site that wrote the cookies. The expiration of a cookie
should be set for as long as your application considers the cookie value to be valid. For a
cookie to effectively never expire, you can set the expiration date to be 50 years from
now.
Note
Users can clear the cookies on their computer at any time. Even if you store cookies with long expirat
decide to delete all cookies, wiping out any settings you might have stored in cookies.
If you do not set the cookie's expiration, the cookie is created but it is not stored on the
user's hard disk. Instead, the cookie is maintained as part of the user's session
information. When the user closes the browser, the cookie is discarded. A non-persistent
cookie like this is useful for information that needs to be stored for only a short time or
that for security reasons should not be written to disk on the client computer. For
example, non-persistent cookies are useful if the user is working on a public computer,
where you do not want to write the cookie to disk.
You can add cookies to the Cookies collection in a number of ways. The following
example shows two methods to write cookies:
C#
VB
Response.Cookies["userName"].Value = "patrick";
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(1);
HttpCookie aCookie = new HttpCookie("lastVisit");
aCookie.Value = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
The example adds two cookies to the Cookies collection, one named userName and the
other named lastVisit. For the first cookie, the values of theCookies collection are set
directly. You can add values to the collection this way because Cookies derives from a
specialized collection of typeNameObjectCollectionBase.
For the second cookie, the code creates an instance of an object of type HttpCookie, sets
its properties, and then adds it to the Cookies collection via theAdd method. When you
instantiate an HttpCookie object, you must pass the cookie name as part of the
constructor.
Both examples accomplish the same task, writing a cookie to the browser. In both
methods, the expiration value must be of type DateTime. However, thelastVisited value
is also a date-time value. Because all cookie values are stored as strings, the date-time
value has to be converted to a String .
Cookies with More Than One Value
You can store one value in a cookie, such as user name and last visit. You can also store
multiple name-value pairs in a single cookie. The name-value pairs are referred to as
subkeys. (Subkeys are laid out much like a query string in a URL.) For example, instead of
creating two separate cookies nameduserName and lastVisit, you can create a single
cookie named userInfo that has the subkeys userName and lastVisit.
You might use subkeys for several reasons. First, it is convenient to put related or similar
information into a single cookie. In addition, because all the information is in a single
cookie, cookie attributes such as expiration apply to all the information. (Conversely, if
you want to assign different expiration dates to different types of information, you should
store the information in separate cookies.)
A cookie with subkeys also helps you limit the size of cookie files. As noted earlier in the
"Cookie Limitations" section, cookies are usually limited to 4096 bytes and you can't
store more than 20 cookies per site. By using a single cookie with subkeys, you use fewer
of those 20 cookies that your site is allotted. In addition, a single cookie takes up about
50 characters for overhead (expiration information, and so on), plus the length of the
value that you store in it, all of which counts toward the 4096-byte limit. If you store five
subkeys instead of five separate cookies, you save the overhead of the separate cookies
and can save around 200 bytes.
To create a cookie with subkeys, you can use a variation of the syntax for writing a single
cookie. The following example shows two ways to write the same cookie, each with two
subkeys:
C#
VB
Response.Cookies["userInfo"]["userName"] = "patrick";
Response.Cookies["userInfo"]["lastVisit"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);
HttpCookie aCookie = new HttpCookie("userInfo");
aCookie.Values["userName"] = "patrick";
aCookie.Values["lastVisit"] = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
Controlling Cookie Scope
By default, all cookies for a site are stored together on the client, and all cookies are sent
to the server with any request to that site. In other words, every page in a site gets all of
the cookies for that site. However, you can set the scope of cookies in two ways:
Limit the scope of cookies to a folder on the server, which allows you to limit
cookies to an application on the site.
Set scope to a domain, which allows you to specify which subdomains in a domain
can access a cookie.
Limiting Cookies to a Folder or Application
To limit cookies to a folder on the server, set the cookie's Path property, as in the
following example:
C#
VB
HttpCookie appCookie = new HttpCookie("AppCookie");
appCookie.Value = "written " + DateTime.Now.ToString();
appCookie.Expires = DateTime.Now.AddDays(1);
appCookie.Path = "/Application1";
Response.Cookies.Add(appCookie);
Note
You can also write cookies by adding them to the Cookies collection directly as shown in earlier examp
The path can either be a physical path under the site root or a virtual root. The effect will
be that the cookie is available only to pages in the Application1 folder or virtual root. For
example, if your site is called www.contoso.com, the cookie created in the previous
example will be available to pages with the path http://www.contoso.com/Application1/
and to any pages beneath that folder. However, the cookie will not be available to pages
in other applications such as http://www.contoso.com/Application2/ or just
http://www.contoso.com/.
Note
In some browsers, the path is case sensitive. You cannot control how users type URLs into their browse
depends on cookies tied to a specific path, be sure that the URLs in any hyperlinks you create match t
the Path property value.
Limiting Cookie Domain Scope
By default, cookies are associated with a specific domain. For example, if your site is
www.contoso.com, the cookies you write are sent to the server when users request any
page from that site. (This might not include cookies with a specific path value.) If your
site has subdomainsfor example, contoso.com, sales.contoso.com, and
support.contoso.comthen you can associate cookies with a specific subdomain. To do
so, set the cookie's Domain property, as in this example:
C#
VB
Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "support.contoso.com";
When the domain is set in this way, the cookie will be available only to pages in the
specified subdomain. You can also use the Domain property to create a cookie that can
be shared among multiple subdomains, as shown in the following example:
C#
VB
Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "contoso.com";
The cookie will then be available to the primary domain as well as to sales.contoso.com
and support.contoso.com domains.
Reading Cookies
When a browser makes a request to the server, it sends the cookies for that server along
with the request. In your ASP.NET applications, you can read the cookies using
the HttpRequest object, which is available as the Request property of your Page class.
The structure of the HttpRequest object is essentially the same as that of
the HttpResponse object, so you can read cookies out of the HttpRequest object much
the same way you wrote cookies into theHttpResponse object. The following code
example shows two ways to get the value of a cookie named username and display its
value in a Label control:
C#
VB
if(Request.Cookies["userName"] != null)
Label1.Text = Server.HtmlEncode(Request.Cookies["userName"].Value);
if(Request.Cookies["userName"] != null)
{
HttpCookie aCookie = Request.Cookies["userName"];
Label1.Text = Server.HtmlEncode(aCookie.Value);
}
Before trying to get the value of a cookie, you should make sure that the cookie exists; if
the cookie does not exist, you will get a NullReferenceExceptionexception. Notice also
that the HtmlEncode method was called to encode the contents of a cookie before
displaying it in the page. This makes certain that a malicious user has not added
executable script into the cookie. For more about cookie security, see the "Cookies and
Security" section.
Note
Because different browsers store cookies differently, different browsers on the same computer won't n
each other's cookies. For example, if you use Internet Explorer to test a page one time, but then later
test again, the second browser won't find the cookies saved by Internet Explorer.
Reading the value of a subkey in a cookie is likewise similar to setting it. The following
code example shows one way to get the value of a subkey:
C#
VB
if(Request.Cookies["userInfo"] != null)
{
Label1.Text =
Server.HtmlEncode(Request.Cookies["userInfo"]["userName"]);
Label2.Text =
Server.HtmlEncode(Request.Cookies["userInfo"]["lastVisit"]);
}
In the preceding example, the code reads the value of the subkey lastVisit, which was set
earlier to the string representation of a DateTime value. Cookies store values as strings,
so if you want to use the lastVisit value as a date, you have to convert it to the
appropriate type, as in this example:
C#
VB
DateTime dt;
dt = DateTime.Parse(Request.Cookies["userInfo"]["lastVisit"]);
The subkeys in a cookie are typed as a collection of type NameValueCollection.
Therefore, another way to get an individual subkey is to get the subkeys collection and
then extract the subkey value by name, as shown in the following example:
C#
VB
if(Request.Cookies["userInfo"] != null)
{
System.Collections.Specialized.NameValueCollection
UserInfoCookieCollection;
UserInfoCookieCollection = Request.Cookies["userInfo"].Values;
Label1.Text =
Server.HtmlEncode(UserInfoCookieCollection["userName"]);
Label2.Text =
Server.HtmlEncode(UserInfoCookieCollection["lastVisit"]);
}
Changing a Cookie's Expiration Date
The browser is responsible for managing cookies, and the cookie's expiration time and
date help the browser manage its store of cookies. Therefore, although you can read the
name and value of a cookie, you cannot read the cookie's expiration date and time.
When the browser sends cookie information to the server, the browser does not include
the expiration information. (The cookie's Expires property always returns a date-time
value of zero.) If you are concerned about the expiration date of a cookie, you must reset
it, which is covered in the "Modifying and Deleting Cookies" section.
Note
You can read the Expires property of a cookie that you have set in the HttpResponse object, before the
the browser. However, you cannot get the expiration back in the HttpRequest object.
Reading Cookie Collections
You might occasionally need to read through all the cookies available to the page. To read
the names and values of all the cookies available to the page, you can loop through
the Cookies collection using code such as the following.
C#
VB
System.Text.StringBuilder output = new System.Text.StringBuilder();
HttpCookie aCookie;
for(int i=0; i<Request.Cookies.Count; i++)
{
aCookie = Request.Cookies[i];
output.Append("Cookie name = " + Server.HtmlEncode(aCookie.Name)
+ "<br />");
output.Append("Cookie value = " + Server.HtmlEncode(aCookie.Value)
+ "<br /><br />");
}
Label1.Text = output.ToString();
Note
When you run this code, you might see a cookie named ASP.NET_SessionId. That is a cookie that ASP.N
identifier for your session. The session cookie is not persisted on your hard disk. For more about sessio
"Cookies and Session State" later in this topic.
A limitation of the preceding example is that if the cookie has subkeys, the display shows
the subkeys as a single name/value string. You can read a cookie's HasKeys property to
determine whether the cookie has subkeys. If so, you can read the subkey collection to
get individual subkey names and values. You can read subkey values from
the Values collection directly by index value. The corresponding subkey names are
available in the AllKeysmember of the Values collection, which returns an array of strings.
You can also use the Keys member of the Values collection. However, the AllKeysproperty
is cached the first time it is accessed. In contrast, the Keys property builds an array each
time it is accessed. For this reason, the AllKeys property is much faster on subsequent
accesses within the context of the same page request.
The following example shows a modification of the preceding example. It uses
the HasKeys property to test for subkeys, and if subkeys are detected, the example gets
subkeys from the Values collection:
C#
VB
for(int i=0; i<Request.Cookies.Count; i++)
{
aCookie = Request.Cookies[i];
output.Append("Name = " + aCookie.Name + "<br />");
if(aCookie.HasKeys)
{
for(int j=0; j<aCookie.Values.Count; j++)
{
subkeyName = Server.HtmlEncode(aCookie.Values.AllKeys[j]);
subkeyValue = Server.HtmlEncode(aCookie.Values[j]);
output.Append("Subkey name = " + subkeyName + "<br />");
output.Append("Subkey value = " + subkeyValue +
"<br /><br />");
}
}
else
{
output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +
"<br /><br />");
}
}
Label1.Text = output.ToString();
Alternatively, you can extract the subkeys as a NameValueCollection object as shown in
the following example:
C#
VB
System.Text.StringBuilder output = new System.Text.StringBuilder();
HttpCookie aCookie;
string subkeyName;
string subkeyValue;
for (int i = 0; i < Request.Cookies.Count; i++)
{
aCookie = Request.Cookies[i];
output.Append("Name = " + aCookie.Name + "<br />");
if (aCookie.HasKeys)
{
System.Collections.Specialized.NameValueCollection CookieValues =
aCookie.Values;
string[] CookieValueNames = CookieValues.AllKeys;
for (int j = 0; j < CookieValues.Count; j++)
{
subkeyName = Server.HtmlEncode(CookieValueNames[j]);
subkeyValue = Server.HtmlEncode(CookieValues[j]);
output.Append("Subkey name = " + subkeyName + "<br />");
output.Append("Subkey value = " + subkeyValue +
"<br /><br />");
}
}
else
{
output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +
"<br /><br />");
}
}
Label1.Text = output.ToString();
Modifying and Deleting Cookies
You cannot directly modify a cookie. Instead, changing a cookie consists of creating a
new cookie with new values and then sending the cookie to the browser to overwrite the
old version on the client. The following code example shows how you can change the
value of a cookie that stores a count of the user's visits to the site:
C#
VB
int counter;
if (Request.Cookies["counter"] == null)
counter = 0;
else
{
counter = int.Parse(Request.Cookies["counter"].Value);
}
counter++;
Response.Cookies["counter"].Value = counter.ToString();
Response.Cookies["counter"].Expires = DateTime.Now.AddDays(1);
Deleting Cookies
Deleting a cookiephysically removing it from the user's hard diskis a variation on
modifying it. You cannot directly remove a cookie because the cookie is on the user's
computer. However, you can have the browser delete the cookie for you. The technique
is to create a new cookie with the same name as the cookie to be deleted, but to set the
cookie's expiration to a date earlier than today. When the browser checks the cookie's
expiration, the browser will discard the now-outdated cookie. The following code example
shows one way to delete all the cookies available to the application:
C#
VB
HttpCookie aCookie;
string cookieName;
int limit = Request.Cookies.Count;
for (int i=0; i<limit; i++)
{
cookieName = Request.Cookies[i].Name;
aCookie = new HttpCookie(cookieName);
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(aCookie);
}
The Cookies property does not indicate whether cookies are enabled. It indicates only whether the cur
supports cookies.
One way to determine whether cookies are accepted is by trying to write a cookie and
then trying to read it back again. If you cannot read the cookie you wrote, you assume
that cookies are turned off in the browser.
The following code example shows how you might test whether cookies are accepted.
The sample consists of two pages. The first page writes out a cookie, and then redirects
the browser to the second page. The second page tries to read the cookie. It in turn
redirects the browser back to the first page, adding to the URL a query string variable
with the results of the test.
The code for the first page (AcceptsCookies.aspx) looks like the following example:
C#
VB
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["AcceptsCookies"] == null)
{
Response.Cookies["TestCookie"].Value = "ok";
Response.Cookies["TestCookie"].Expires =
DateTime.Now.AddMinutes(1);
Response.Redirect("TestForCookies.aspx?redirect=" +
Server.UrlEncode(Request.Url.ToString()));
}
else
{
Label1.Text = "Accept cookies = " +
Server.UrlEncode(
Request.QueryString["AcceptsCookies"]);
}
}
}
The page first tests to see if this is a postback, and if not, the page looks for the query
string variable name AcceptsCookies that contains the test results. If there is no query
string variable, the test has not been completed, so the code writes out a cookie
named TestCookie. After writing out the cookie, the sample calls Redirect to transfer to
the test page TestForCookies.aspx. Appended to the URL of the test page is a query
string variable named redirectcontaining the URL of the current page; this will allow you
to redirect back to this page after performing the test.
The test page can consist entirely of code; it does not need to contain controls. The
following example illustrates the test page (TestForCookies.aspx).
C#
VB
protected void Page_Load(object sender, EventArgs e)
{
string redirect = Request.QueryString["redirect"];
string acceptsCookies;
if(Request.Cookies["TestCookie"] ==null)
acceptsCookies = "no";
else
{
acceptsCookies = "yes";
// Delete test cookie.
Response.Cookies["TestCookie"].Expires =
DateTime.Now.AddDays(-1);
}
Response.Redirect(redirect + "?AcceptsCookies=" + acceptsCookies,
true);
}
After reading the redirect query string variable, the code tries to read the cookie. For
housekeeping purposes, if the cookie exists, it is immediately deleted. When the test is
finished, the code constructs a new URL from the URL passed to it in the redirect query
string variable. The new URL also includes a query string variable containing test results.
The final step is to use the new URL to redirect the browser to the original page.
An improvement in the example would be to keep the cookie test results in a persistent
store such as a database so that the test does not have to be repeated each time the
user views the original page. (Storing the test results in session state by default requires
cookies.)
Cookies and Session State
When a user navigates to your site, the server establishes a unique session for that user
that lasts for the duration of the user's visit. For each session, ASP.NET maintains session
state information where applications can store user-specific information. For more
information, see ASP.NET Session State Overview topic.
ASP.NET must track a session ID for each user so that it can map the user to session state
information on the server. By default, ASP.NET uses a non-persistent cookie to store the
session state. However, if a user has disabled cookies on the browser, session state
information cannot be stored in a cookie.
ASP.NET offers an alternative in the form of cookieless sessions. You can configure your
application to store session IDs not in a cookie, but in the URLs of pages in your site. If
your application relies on session state, you might consider configuring it to use
cookieless sessions. However, under some limited circumstances, if the user shares the
URL with someone elseperhaps to send the URL to a colleague while the user's session
is still activethen both users can end up sharing the same session, with unpredictable
results. For more information on configuring your application to use cookieless sessions,
see the ASP.NET State Management Overview topic.
Serialization is the process of converting an object into a stream of bytes in order to store
the object or transmit it to memory, a database, or a file. Its main purpose is to save the
state of an object in order to be able to recreate it when needed. The reverse process is
called deserialization.
For examples of serialization, see Related Topics and Examples later in this topic.
How Serialization Works
This illustration shows the overall process of serialization.
The object is serialized to a stream, which carries not just the data, but information about
the object's type, such as its version, culture, and assembly name. From that stream, it
can be stored in a database, a file, or memory.
Uses for Serialization
Serialization allows the developer to save the state of an object and recreate it as
needed, providing storage of objects as well as data exchange. Through serialization, a
developer can perform actions like sending the object to a remote application by means
of a Web Service, passing an object from one domain to another, passing an object
through a firewall as an XML string, or maintaining security or user-specific information
across applications.
Making an Object Serializable
To serialize an object, you need the object to be serialized, a stream to contain the
serialized object, and aFormatter. System.Runtime.Serialization contains the classes
necessary for serializing and deserializing objects.
Apply the SerializableAttribute attribute to a type to indicate that instances of this type
can be serialized. A SerializationException exception is thrown if you attempt to serialize
but the type does not have theSerializableAttribute attribute.
If you do not want a field within your class to be serializable, apply
the NonSerializedAttribute attribute. If a field of a serializable type contains a pointer, a
handle, or some other data structure that is specific to a particular environment, and the
field cannot be meaningfully reconstituted in a different environment, then you may want
to make it nonserializable.
If a serialized class contains references to objects of other classes that are
marked SerializableAttribute, those objects will also be serialized.
Binary and XML Serialization
Either binary or XML serialization can be used. In binary serialization, all members, even
those that are read-only, are serialized, and performance is enhanced. XML serialization
provides more readable code, as well as greater flexibility of object sharing and usage for
interoperability purposes.
Binary Serialization
Binary serialization uses binary encoding to produce compact serialization for uses such
as storage or socket-based network streams.
XML Serialization
XML serialization serializes the public fields and properties of an object, or the
parameters and return values of methods, into an XML stream that conforms to a specific
XML Schema definition language (XSD) document. XML serialization results in strongly
typed classes with public properties and fields that are converted to
XML. System.Xml.Serialization contains the classes necessary for serializing and
deserializing XML.
You can apply attributes to classes and class members in order to control the way
the XmlSerializerserializes or deserializes an instance of the class.
SOAP Serialization
XML serialization can also be used to serialize objects into XML streams that conform to
the SOAP specification. SOAP is a protocol based on XML, designed specifically to
transport procedure calls using XML. As with regular XML serialization, attributes can be
used to control the literal-style SOAP messages generated by an XML Web service.
Basic and Custom Serialization
Serialization can be performed in two ways, basic and custom. Basic serialization uses
the .NET Framework to automatically serialize the object.
Basic Serialization
Used to restrict types that might be used as arguments for a type parameter in a
generic declaration.
In the following example, a struct object and a class object are created and initialized by
using the new operator and then assigned values. The default and the assigned values
are displayed.
C#
struct SampleStruct
{
public int x;
public int y;
public SampleStruct(int x, int y)
{
this.x = x;
this.y = y;
}
}
class SampleClass
{
public string name;
public int id;
public SampleClass() {}
public SampleClass(int id, string name)
{
this.id = id;
this.name = name;
}
}
class ProgramClass
{
static void Main()
{
// Create objects using default constructors:
SampleStruct Location1 = new SampleStruct();
SampleClass Employee1 = new SampleClass();
// Display values:
Console.WriteLine("Default values:");
Console.WriteLine(" Struct members: {0}, {1}",
Location1.x, Location1.y);
Notice in the example that the default value of a string is null. Therefore, it is not
displayed.
{
public int x;
public void Invoke() { }
}
public class DerivedC : BaseC
{
new public void Invoke() { }
}
In this example, a nested class hides a class that has the same name in the base class.
The example demonstrates how to use the new modifier to eliminate the warning
message and how to access the hidden class members by using their fully qualified
names.
C#
public class BaseC
{
public class NestedC
{
public int x = 200;
public int y;
}
}
public class DerivedC : BaseC
{
// Nested type hiding the base type members.
new public class NestedC
{
public int x = 100;
public int y;
public int z;
}
static void Main()
{
// Creating an object from the overlapping class:
NestedC c1 = new NestedC();
// Creating an object from the hidden class:
BaseC.NestedC c2 = new BaseC.NestedC();
Console.WriteLine(c1.x);
Console.WriteLine(c2.x);
}
}
/*
Output:
100
200
*/
If you remove the new modifier, the program will still compile and run, but you will get
the following warning:
The keyword new is required on 'MyDerivedC.x' because it hides inherited member
'MyBaseC.x'.
Apply the new constraint to a type parameter when your generic class creates new
instances of the type, as shown in the following example:
C#
class ItemFactory<T> where T : new()
{
public T GetNewItem()
{
return new T();
}
}
When you use the new() constraint with other constraints, it must be specified last:
C#
Blogs Home |
This is very basic stuff we use in our daily coding life but we are not aware of these
concepts . Let me explain you :
Objects always have some relationships and association, composition and aggregation is
all about relationships.
Inheritance: It's Is A relation : Parent-child relationship. e.g :Saurabh is a business
manager of some company, Beer is a Alcohol. So in both examples we have is a
relationship like in first example : Employee would be a base class and manager will be
child class and in the second example Beer would be a child class for Alcohol.
Conclusion : Inheritance is nothing it's just Is A : parent child relation ship
Association: It's Has a relation : In simple words : I have a Watch. There is a relation ship
between Me and my watch but we are not dependent on each other. I can exist without
my watch and my watch can exist without me so this is called Association.
Let me explain this concept with code :
//Subtract
private int Sub(int x, int y)
{
Sub objSub = new Sub();
return objSub.Subtraction(x, y);
}
}
public class Add
{
In the above example we can easily see that life cycle of BodyParts and Body goes
parallel. If object is body gets deleted then BodyParts also not exist .
When you initialize a new process, the runtime reserves a contiguous region of address
space for the process. This reserved address space is called the managed heap. The
managed heap maintains a pointer to the address where the next object in the heap will
be allocated. Initially, this pointer is set to the managed heap's base address.
All reference types are allocated on the managed heap. When an application creates the
first reference type, memory is allocated for the type at the base address of the
managed heap. When the application creates the next object, the garbage collector
allocates memory for it in the address space immediately following the first object. As
long as address space is available, the garbage collector continues to allocate space for
new objects in this manner.
Allocating memory from the managed heap is faster than unmanaged memory allocation.
Because the runtime allocates memory for an object by adding a value to a pointer, it is
almost as fast as allocating memory from the stack. In addition, because new objects
that are allocated consecutively are stored contiguously in the managed heap, an
application can access the objects very quickly.
Releasing Memory
The garbage collector's optimizing engine determines the best time to perform a
collection based on the allocations being made. When the garbage collector performs a
collection, it releases the memory for objects that are no longer being used by the
application. It determines which objects are no longer being used by examining the
application's roots. Every application has a set of roots. Each root either refers to an
object on the managed heap or is set to null. An application's roots include global and
static object pointers, local variables and reference object parameters on a thread's
stack, and CPU registers. The garbage collector has access to the list of active roots that
the just-in-time (JIT) compiler and the runtime maintain. Using this list, it examines an
application's roots, and in the process creates a graph that contains all the objects that
are reachable from the roots.
Objects that are not in the graph are unreachable from the application's roots. The
garbage collector considers unreachable objects garbage and will release the memory
allocated for them. During a collection, the garbage collector examines the managed
heap, looking for the blocks of address space occupied by unreachable objects. As it
discovers each unreachable object, it uses a memory-copying function to compact the
reachable objects in memory, freeing up the blocks of address spaces allocated to
unreachable objects. Once the memory for the reachable objects has been compacted,
the garbage collector makes the necessary pointer corrections so that the application's
roots point to the objects in their new locations. It also positions the managed heap's
pointer after the last reachable object. Note that memory is compacted only if a
collection discovers a significant number of unreachable objects. If all the objects in the
managed heap survive a collection, then there is no need for memory compaction.
To improve performance, the runtime allocates memory for large objects in a separate
heap. The garbage collector automatically releases the memory for large objects.
However, to avoid moving large objects in memory, this memory is not compacted.
Generations and Performance
To optimize the performance of the garbage collector, the managed heap is divided into
three generations: 0, 1, and 2. The runtime's garbage collection algorithm is based on
several generalizations that the computer software industry has discovered to be true by
experimenting with garbage collection schemes. First, it is faster to compact the memory
for a portion of the managed heap than for the entire managed heap. Secondly, newer
objects will have shorter lifetimes and older objects will have longer lifetimes. Lastly,
newer objects tend to be related to each other and accessed by the application around
the same time.
The runtime's garbage collector stores new objects in generation 0. Objects created early
in the application's lifetime that survive collections are promoted and stored in
generations 1 and 2. The process of object promotion is described later in this topic.
Because it is faster to compact a portion of the managed heap than the entire heap, this
scheme allows the garbage collector to release the memory in a specific generation
rather than release the memory for the entire managed heap each time it performs a
collection.
In reality, the garbage collector performs a collection when generation 0 is full. If an
application attempts to create a new object when generation 0 is full, the garbage
collector discovers that there is no address space remaining in generation 0 to allocate
for the object. The garbage collector performs a collection in an attempt to free address
space in generation 0 for the object. The garbage collector starts by examining the
objects in generation 0 rather than all objects in the managed heap. This is the most
efficient approach, because new objects tend to have short lifetimes, and it is expected
that many of the objects in generation 0 will no longer be in use by the application when
a collection is performed. In addition, a collection of generation 0 alone often reclaims
enough memory to allow the application to continue creating new objects.
After the garbage collector performs a collection of generation 0, it compacts the
memory for the reachable objects as explained in Releasing Memoryearlier in this topic.
The garbage collector then promotes these objects and considers this portion of the
managed heap generation 1. Because objects that survive collections tend to have
longer lifetimes, it makes sense to promote them to a higher generation. As a result, the
garbage collector does not have to reexamine the objects in generations 1 and 2 each
time it performs a collection of generation 0.
After the garbage collector performs its first collection of generation 0 and promotes the
reachable objects to generation 1, it considers the remainder of the managed heap
generation 0. It continues to allocate memory for new objects in generation 0 until
generation 0 is full and it is necessary to perform another collection. At this point, the
garbage collector's optimizing engine determines whether it is necessary to examine the
objects in older generations. For example, if a collection of generation 0 does not reclaim
enough memory for the application to successfully complete its attempt to create a new
object, the garbage collector can perform a collection of generation 1, then generation 2.
If this does not reclaim enough memory, the garbage collector can perform a collection
of generations 2, 1, and 0. After each collection, the garbage collector compacts the
reachable objects in generation 0 and promotes them to generation 1. Objects in
generation 1 that survive collections are promoted to generation 2. Because the garbage
collector supports only three generations, objects in generation 2 that survive a
collection remain in generation 2 until they are determined to be unreachable in a future
collection.
Releasing Memory for Unmanaged Resources
For the majority of the objects that your application creates, you can rely on the garbage
collector to automatically perform the necessary memory management tasks. However,
unmanaged resources require explicit cleanup. The most common type of unmanaged
resource is an object that wraps an operating system resource, such as a file handle,
window handle, or network connection. Although the garbage collector is able to track
the lifetime of a managed object that encapsulates an unmanaged resource, it does not
have specific knowledge about how to clean up the resource. When you create an object
that encapsulates an unmanaged resource, it is recommended that you provide the
necessary code to clean up the unmanaged resource in a publicDispose method. By
providing a Dispose method, you enable users of your object to explicitly free its
memory when they are finished with the object. When you use an object that
encapsulates an unmanaged resource, you should be aware of Dispose and call it as
necessary. For more information about cleaning up unmanaged resources and an
example of a design pattern for implementing Dispose, see Garbage Collection.
Problem of Dll-Hell
Introduction
Before some time, if we install an application then dll of that application get stored in the
registry, then if we install other application that has same name .dll that means
previously installed .dll get overwrite by the same name new .dll. Ok for newly installed
application but previously installed application cant get execute further. This is big
problem in context of version of same application. This is Dell-Hell problem.
OR
Dll Hell refers to a set of problems caused when multiple applications attempt to share a
common component like a dynamic link library (DLL).The reason for this issue was that
the version information about the different components of an application was not
recorded by the system.
Solution of Dll-Hell Problem
This problem of dynamic link library (.dll) is resolved through Versioning.
Versioning:
Versioning is the technique to provide version to the .dll to prevent them from
replacement. GAC (Global assembly cache) is the separate memory like cache it is used
to remove load form operating system.
To add version in assembly we just write in Program :
We can do versioning only with shared assembly because to install .dll in GAC so we need
to have strong key name.
Authentication:verification, to be verify.
Authorization :Providing Role, to provide power ,step after authentication in role.
To see the parts of an assembly:
open cmd prompt of Visual studio and write - ILDASM
ILDASM: is a tool to see the content (metadata) of Assembly.
A Dispose method should call the GC.SuppressFinalize method for the object it is
disposing. If the object is currently on the finalization
queue,GC.SuppressFinalize prevents its Finalize method from being called.
Remember that executing a Finalize method is costly to performance. If
your Disposemethod has already done the work to clean up the object, then it is not
necessary for the garbage collector to call the object's Finalize method.
The purpose of the following code example is to illustrate one possible design pattern for
implementing a Dispose method for classes that encapsulate unmanaged resources. You
might find this pattern convenient to use because it is implemented throughout the .NET
Framework. However, this is not the only possible implementation of a Dispose method.
Resource classes are typically derived from complex native classes or APIs and must be
customized accordingly. Use this code pattern as a starting point for creating a resource
class and provide the necessary customization based on the resources you are
encapsulating. You cannot compile this sample and use it directly in an application.
In this example, the base class BaseResource implements a public Dispose method that
can be called by users of the class. It in turn calls the methodvirtual Dispose(bool
disposing) (virtual Dispose(disposing As Boolean) in Visual Basic).
Either true or false is passed depending upon the identity of the caller. The appropriate
cleanup code for the object is executed in the virtual Dispose method.
Dispose(bool disposing) executes in two distinct scenarios. If disposing equals true,
the method has been called directly or indirectly by a user's code and managed and
unmanaged resources can be disposed. If disposing equals false, the method has been
called by the runtime from inside the finalizer and only unmanaged resources can be
disposed. When an object is executing its finalization code, it should not reference other
objects, because finalizers do not execute in any particular order. If an executing finalizer
references another object that has already been finalized, the executing finalizer will fail.
The base class provides a Finalize method or destructor as a safeguard in the event
that Dispose is not called. The Finalize method calls the Disposemethod that takes
parameters, passing false. You should not re-create Dispose clean-up code within
the Finalize method. Calling Dispose(false) is optimal for code readability and
maintainability.
The class MyResourceWrapper illustrates how to derive from a class that implements
resource management using Dispose. MyResourceWrapperoverrides the virtual
Dispose(bool disposing) method and provides clean-up code for the managed and
unmanaged resources that it creates.MyResourceWrapper also calls Dispose on its base
class BaseResource to make sure that its base gets the opportunity to clean up properly.
Note that the derived class MyResourceWrapper does not have a Finalize method or
a Dispose method without parameters, because it inherits them from the base
class BaseResource.
Note The protected Dispose(bool disposing) method in this example does not
enforce thread safety because the method cannot be called from a user thread and a
finalizer thread at the same time. In addition, a client application using
the BaseResource should never allow multiple user threads to call the protected
Dispose(bool disposing) method at the same time. An application or class library
should be designed to allow only one thread to own the lifetime of a resource and to
call Dispose when the resource is no longer needed. Depending on the resource,
unsynchronized thread access when disposing of resources can pose a security risk.
Developers should carefully review their code to determine the best approach to
enforcing thread safety.
VB
' Design pattern for the base class.
' By implementing IDisposable, you are announcing that instances
' of this type allocate scarce resources.
Public Class BaseResource
Implements IDisposable
' Pointer to an external unmanaged resource.
Private handle As IntPtr
' Other managed resource this class uses.
Private Components As Component
' Track whether Dispose has been called.
Private disposed As Boolean = False
' Constructor for the BaseResource Object.
Public Sub New()
' Insert appropriate constructor code here.
End Sub
' Implement IDisposable.
' Do not make this method Overridable.
' A derived class should not be able to override this method.
Public Overloads Sub Dispose()Implements IDisposable.Dispose
Dispose(true)
' Take yourself off of the finalization queue
' to prevent finalization code for this object
' from executing a second time.
GC.SuppressFinalize(Me)
End Sub
' Dispose(disposing As Boolean) executes in two distinct scenarios.
' If disposing is true, the method has been called directly
' or indirectly by a user's code. Managed and unmanaged resources
' can be disposed.
' If disposing equals false, the method has been called by the runtime
' from inside the finalizer and you should not reference other
' objects. Only unmanaged resources can be disposed.
Protected Overloads Overridable Sub Dispose(disposing As Boolean)
' Check to see if Dispose has already been called.
If Not (Me.disposed) Then
' If disposing equals true, dispose all managed
' and unmanaged resources.
If (disposing) Then
' Dispose managed resources.
Components.Dispose()
End If
' Release unmanaged resources. If disposing is false,
' only the following code is executed.
CloseHandle(handle)
handle = IntPtr.Zero
' Note that this is not thread safe.
' Another thread could start disposing the object
' after the managed resources are disposed,
' but before the disposed flag is set to true.
' If thread safety is necessary, it must be
' implemented by the client.
End If
Me.disposed = true
End Sub
' This Finalize method will run only if the
' Dispose method does not get called.
' By default, methods are NotOverridable.
' This prevents a derived class from overriding this method.
Protected Overrides Sub Finalize()
' Do not re-create Dispose clean-up code here.
' Calling Dispose(false) is optimal in terms of
' readability and maintainability.
Dispose(false)
End Sub
' Allow your Dispose method to be called multiple times,
' but throw an exception if the object has been disposed.
' Whenever you do something with this class,
' check to see if it has been disposed.
Public Sub DoSomething()
If Me.disposed Then
Throw New ObjectDisposedException()
End if
End Sub
End Class
' Design pattern for a derived class.
' Note that this derived class inherently implements the
' IDisposable interface because it is implemented in the base class.
Public Class MyResourceWrapper
Inherits BaseResource
' A managed resource that you add in this derived class.
private addedManaged As ManagedResource
' A native unmanaged resource that you add in this derived class.
private addedNative As NativeResource
' Track whether Dispose has been called.
Private disposed As Boolean = False
' Constructor for the MyResourceWrapper object.
Public Sub New()
MyBase.New()
' Insert appropriate constructor code here for the
' added resources.
End Sub
Protected Overloads Overrides Sub Dispose(disposing As Boolean)
Object.Finalize Method
.NET Framework 4.5
Other Versions
Syntax
C#
C++
F#
VB
protected virtual void Finalize()
Remarks
The Finalize method is used to perform cleanup operations on unmanaged resources held
by the current object before the current object is destroyed. The method is protected and
therefore is accessible only through this class or through a derived class.
This method is automatically called after an object becomes inaccessible, unless the
object has been exempted from finalization by a call toGC.SuppressFinalize. During
shutdown of an application domain, Finalize is automatically called on objects that are
not exempt from finalization, even those that are still accessible. Finalize is automatically
called only once on a given instance, unless the object is re-registered using a
mechanism such asGC.ReRegisterForFinalize and GC.SuppressFinalize has not been
subsequently called.
Every implementation of Finalize in a derived type must call its base type's
implementation of Finalize. This is the only case in which application code is allowed to
call Finalize.
Note
Because the C# compiler does not allow you to directly implement the Finalize method, a C# destructor au
destructor of its base class.
Finalize operations have the following limitations:
The exact time when the finalizer executes during garbage collection is undefined.
Resources are not guaranteed to be released at any specific time, unless calling
a Close method or a Dispose method.
The finalizers of two objects are not guaranteed to run in any specific order, even
if one object refers to the other. That is, if Object A has a reference to Object B
and both have finalizers, Object B might have already finalized when the finalizer
of Object A starts.
The thread on which the finalizer is run is unspecified.
The Finalize method might not run to completion or might not run at all in the following
exceptional circumstances:
Another finalizer blocks indefinitely (goes into an infinite loop, tries to obtain a
lock it can never obtain and so on). Because the runtime attempts to run finalizers
to completion, other finalizers might not be called if a finalizer blocks indefinitely.
The process terminates without giving the runtime a chance to clean up. In this
case, the runtime's first notification of process termination is a
DLL_PROCESS_DETACH notification.
The runtime continues to Finalize objects during shutdown only while the number of
finalizable objects continues to decrease.
If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by
an application that overrides the default policy, the runtime terminates the process and
no active try-finally blocks or finalizers are executed. This behavior ensures process
integrity if the finalizer cannot free or destroy resources.
Notes to Implementers
Object.Finalize does nothing by default. It must be overridden by a derived class only if
necessary, because reclamation during garbage collection tends to take much longer if
a Finalize operation must be run.
Examples
The following example verifies that the Finalize method is called when an object that
overrides Finalize is destroyed. Note that, in a production application, the Finalize method
would be overridden to release unmanaged resources held by the object. Also note that
the C# example provides a destructor instead of overriding the Finalize method.
C#
VB
using System;
using System.Diagnostics;
public class ExampleClass
{
Stopwatch sw;
public ExampleClass()
{
sw = Stopwatch.StartNew();
Console.WriteLine("Instantiated object");
}
public void ShowDuration()
{
Console.WriteLine("This instance of {0} has been in existence for {1}",
this, sw.Elapsed);
}
~ExampleClass()
{
Console.WriteLine("Finalizing object");
sw.Stop();
Console.WriteLine("This instance of {0} has been in existence for {1}",
this, sw.Elapsed);
}
}
public class Demo
{
ASP.NET State
Management
Recommendations
.NET Framework 4
Other Versions
Storing page information using client-side options doesn't use server resources. These
options typically have minimal security but fast server performance because the demand
on server resources is modest. However, because you must send information to the client
for it to be stored, there is a practical limit on how much information you can store this
way.
The following are the client-side state management options that ASP.NET supports:
View state
Control state
Hidden fields
Cookies
Query strings
View State
Web Forms pages provide the ViewState property as a built-in structure for automatically
retaining values between multiple requests for the same page. View state is maintained
as a hidden field in the page. For more information, see ASP.NET State Management
Overview.
You can use view state to store your own page-specific values across round trips when
the page posts back to itself. For example, if your application is maintaining user-specific
information that is, information that is used in the page but is not necessarily part of
any control you can store it in view state.
Advantages of using view state are:
No server resources are required The view state is contained in a structure
within the page code.
Simple implementation View state does not require any custom programming
to use. It is on by default to maintain state data on controls.
Enhanced security features The values in view state are hashed, compressed,
and encoded for Unicode implementations, which provides more security than
using hidden fields.
Disadvantages of using view state are:
Performance considerations Because the view state is stored in the page
itself, storing large values can cause the page to slow down when users display it
and when they post it. This is especially relevant for mobile devices, where
bandwidth is often a limitation.
Device limitations Mobile devices might not have the memory capacity to
store a large amount of view-state data.
Potential security risks The view state is stored in one or more hidden fields
on the page. Although view state stores data in a hashed format, it can still be
tampered with. The information in the hidden field can be seen if the page output
source is viewed directly, creating a potential security issue. For more information,
see ASP.NET Web Application Security and Basic Security Practices for Web
Applications.
For more information about using view state, see View State Overview.
Control State
The ASP.NET page framework provides the ControlState property as way to store custom
control data between server trips. For example, if you have written a custom control that
has different tabs showing different information, in order for that control to work as
expected, the control needs to know which tab is selected between round trips. View
state can be used for this purpose, but developers can turn view state off at the page
level, effectively breaking your control. Unlike view state, control state cannot be turned
off, so it provides a more reliable way to store control-state data.
Advantages of using control state are:
Hidden Fields
You can store page-specific information in a hidden field on your page as a way of
maintaining the state of your page.
If you use hidden fields, it is best to store only small amounts of frequently changed data
on the client.
Note
If you use hidden fields, you must submit your pages to the server using the HTTP POST method rather th
the page URL (the HTTP GET method).
Advantages of using hidden fields are:
No server resources are required The hidden field is stored and read from
the page.
Widespread support Almost all browsers and client devices support forms with
hidden fields.
Simple implementation Hidden fields are standard HTML controls that require
no complex programming logic.
Disadvantages of using hidden fields are:
Potential security risks The hidden field can be tampered with. The
information in the hidden field can be seen if the page output source is viewed
directly, creating a potential security issue. You can manually encrypt and decrypt
the contents of a hidden field, but doing so requires extra coding and overhead. If
security is a concern, consider using a server-based state mechanism so that no
sensitive information is sent to the client. For more information, see ASP.NET Web
Application Security and Basic Security Practices for Web Applications.
Simple storage architecture The hidden field does not support rich data
types. Hidden fields offer a single string value field in which to place information.
To store multiple values, you must implement delimited strings and the code to
parse those strings. You can manually serialize and de-serialize rich data types to
and from hidden fields, respectively. However, it requires extra code to do so. If
you need to store rich data types on the client, consider using view state instead.
View state has serialization built-in, and it stores data in hidden fields.
Performance considerations Because hidden fields are stored in the page
itself, storing large values can cause the page to slow down when users display it
and when they post it.
Storage limitations If the amount of data in a hidden field becomes very large,
some proxies and firewalls will prevent access to the page that contains them.
Because the maximum amount can vary with different firewall and proxy
Cookies
Cookies are useful for storing small amounts of frequently changed information on the
client. The information is sent with the request to the server. For details about creating
and reading cookies, see ASP.NET Cookies Overview.
Advantages of using cookies are:
Configurable expiration rules The cookie can expire when the browser
session ends, or it can exist indefinitely on the client computer, subject to the
expiration rules on the client.
No server resources are required The cookie is stored on the client and read
by the server after a post.
Simplicity The cookie is a lightweight, text-based structure with simple keyvalue pairs.
Data persistence Although the durability of the cookie on a client computer is
subject to cookie expiration processes on the client and user intervention, cookies
are generally the most durable form of data persistence on the client.
Disadvantages of using cookies are:
Size limitations Most browsers place a 4096-byte limit on the size of a cookie,
although support for 8192-byte cookies is becoming more common in newer
browser and client-device versions.
User-configured refusal Some users disable their browser or client device's
ability to receive cookies, thereby limiting this functionality.
Potential security risks Cookies are subject to tampering. Users can
manipulate cookies on their computer, which can potentially cause a security risk
or cause the application that is dependent on the cookie to fail. Also, although
cookies are only accessible by the domain that sent them to the client, hackers
have historically found ways to access cookies from other domains on a user's
computer. You can manually encrypt and decrypt cookies, but it requires extra
coding and can affect application performance because of the time that is
required for encryption and decryption. For more information, see ASP.NET Web
Application Security and Basic Security Practices for Web Applications.
Note
Cookies are often used for personalization, where content is customized for a known user. In most o
is the issue rather than authentication. Thus, you can typically secure a cookie that is used for ident
name, account name, or a unique user ID (such as a GUID) in the cookie and then using the cookie
personalization infrastructure of a site.
Query Strings
A query string is information that is appended to the end of a page URL. For more
information, see ASP.NET State Management Overview.
You can use a query string to submit data back to your page or to another page through
the URL. Query strings provide a simple but limited way of maintaining some state
information. For example, query strings are an easy way to pass information from one
page to another, such as passing a product number to another page where it will be
processed.
Advantages of using query strings are:
No server resources are required The query string is contained in the HTTP
request for a specific URL.
Widespread support Almost all browsers and client devices support using
query strings to pass values.
Simple implementation ASP.NET provides full support for the query-string
method, including methods of reading query strings using the Paramsproperty of
the HttpRequest object.
Disadvantages of using query strings are:
Potential security risks The information in the query string is directly visible
to the user via the browser's user interface. A user can bookmark the URL or send
the URL to other users, thereby passing the information in the query string along
with it. If you are concerned about any sensitive data in the query string, consider
using hidden fields in a form that uses POST instead of using query strings. For
more information, see ASP.NET Web Application Security and Basic Security
Practices for Web Applications.
Limited capacity Some browsers and client devices impose a 2083-character
limit on the length of URLs.
The following table lists the client-side state management options that are available with
ASP.NET, and provides recommendations about when you should use each option.
State management
option
Recommended usage
View state
Use when you need to store small amounts of information for a page that will p
the ViewState property provides functionality with basic security.
Control state
Use when you need to store small amounts of state information for a control be
server.
Hidden fields
Use when you need to store small amounts of information for a page that will p
another page, and when security is not an issue.
Note
You can use a hidden field only on pages that are submitted to the server.
Cookies
Use when you need to store small amounts of information on the client and secu
Query string
Use when you are transferring small amounts of information from one page to a
issue.
Note
You can use query strings only if you are requesting the same page, or another p
Server-side options for storing page information typically have higher security than
client-side options, but they can use more Web server resources, which can lead to
scalability issues when the size of the information store is large. ASP.NET provides several
options to implement server-side state management. For more information, see ASP.NET
State Management Overview.
The following are the server-side state management options that ASP.NET supports:
Application state
Session state
Profile properties
Database support
Application State
Session State
ASP.NET provides a session state, which is available as the HttpSessionState class, as a
method of storing session-specific information that is visible only within the session.
ASP.NET session state identifies requests from the same browser during a limited time
window as a session, and provides the ability to persist variable values for the duration of
Profile Properties
ASP.NET provides a feature called profile properties, which allows you to store userspecific data. It is similar to session state, except that unlike session state, the profile
data is not lost when a user's session expires. The profile properties feature uses an
ASP.NET profile, which is stored in a persistent format and associated with an individual
user. The ASP.NET profile allows you to easily manage user information without requiring
you to create and maintain your own database. In addition, the profile makes the user
information available using a strongly typed API that you can access from anywhere in
your application. You can store objects of any type in the profile. The ASP.NET profile
feature provides a generic storage system that allows you to define and maintain almost
any kind of data while still making the data available in a type-safe manner. For more
information, see ASP.NET Profile Properties Overview.
Advantages of using profile properties are:
Data persistence Data placed in profile properties is preserved through IIS
restarts and worker-process restarts without losing data because the data is
Database Support
In some cases, you might want to use database support to maintain state on your Web
site. Typically, database support is used in conjunction with cookies or session state. For
example, it is common for an e-commerce Web site to maintain state information by
using a relational database for the following reasons:
Security
Personalization
Consistency
Data mining
The following are typical features of a cookie-supported database Web site:
Security The visitor types an account name and password into a site logon
page. The site infrastructure queries the database with the logon values to
determine whether the user has rights to utilize your site. If the database
validates the user information, the Web site will distribute a valid cookie
containing a unique ID for that user on that client computer. The site grants
access to the user.
Personalization With security information in place, your site can distinguish
each user by reading the cookie on the client computer. Typically, sites have
information in the database that describes the preferences of a user (identified by
a unique ID). This relationship is known as personalization. The site can research
the user's preferences using the unique ID contained in the cookie, and then place
content and information in front of the user that pertains to the user's specific
wishes, reacting to the user's preferences over time.
Consistency If you have created a commerce Web site, you might want to keep
transactional records of purchases made for goods and services on your site. This
information can be reliably saved in your database and referenced by the user's
unique ID. It can be used to determine whether a purchase transaction has been
The following table lists the server-side state management options that are available with
ASP.NET, and provides recommendations about when you should use each option.
State
management
option
Recommended usage
Application state
Use when you are storing infrequently changed, global information that is used by
not an issue. Do not store large quantities of information in application state.
Session state
Use when you are storing short-lived information that is specific to an individual se
issue. Do not store large quantities of information in session state. Be aware that a s
created and maintained for the lifetime of every session in your application. In appl
this can occupy significant server resources and affect scalability.
Profile properties
Use when you are storing user-specific information that needs to be persisted after
and needs to be retrieved again on subsequent visits to your application.
Database support
Use when you are storing large amounts of information, managing transactions, or
survive application and session restarts. Data mining is a concern, and security is a
Background
ASP.NET session state enables you to store and retrieve values for a user as the user
navigates ASP.NET pages in a Web application. HTTP is a stateless protocol. This means
that a Web server treats each HTTP request for a page as an independent request. The
server retains no knowledge of variable values that were used during previous requests.
ASP.NET session state identifies requests from the same browser during a limited time
window as a session, and provides a way to persist variable values for the duration of
that session. By default, ASP.NET session state is enabled for all ASP.NET applications.
Alternatives to session state include the following:
Application state, which stores variables that can be accessed by all users of an
ASP.NET application.
Profile properties, which persists user values in a data store without expiring
them.
ASP.NET caching, which stores values in memory that is available to all ASP.NET
applications.
View state, which persists values in a page.
Cookies.
The query string and fields on an HTML form that are available from an HTTP
request.
Session Variables
Note
When you use a session-state mode other than InProc, the session-variable type must be either a primitive
This is because the session-variable value is stored in an external data store. For more information, see Ses
Session Identifiers
Sessions are identified by a unique identifier that can be read by using
the SessionID property. When session state is enabled for an ASP.NET application, each
request for a page in the application is examined for a SessionID value sent from the
browser. If no SessionID value is supplied, ASP.NET starts a new session and
the SessionID value for that session is sent to the browser with the response.
By default, SessionID values are stored in a cookie. However, you can also configure the
application to store SessionID values in the URL for a "cookieless" session.
A session is considered active as long as requests continue to be made with the
same SessionID value. If the time between requests for a particular session exceeds the
specified time-out value in minutes, the session is considered expired. Requests made
with an expired SessionID value result in a new session.
Security Note
SessionID values are sent in clear text, whether as a cookie or as part of the URL. A malicious user could g
another user by obtaining the SessionID value and including it in requests to the server. If you are storing s
session state, it is recommended that you use SSL to encrypt any communication between the browser and
the SessionID value.
Cookieless SessionIDs
By default, the SessionID value is stored in a non-expiring session cookie in the browser.
However, you can specify that session identifiers should not be stored in a cookie by
setting the cookieless attribute to true in the sessionState section of the Web.config
file.
The following example shows a Web.config file that configures an ASP.NET application to
use cookieless session identifiers.
<configuration>
<system.web>
<sessionState cookieless="true"
regenerateExpiredSessionId="true" />
</system.web>
</configuration>
ASP.NET maintains cookieless session state by automatically inserting a unique session
ID into the page's URL. For example, the following URL has been modified by ASP.NET to
include the unique session ID lit3py55t21z5v55vlm25s55:
http://www.example.com/(S(lit3py55t21z5v55vlm25s55))/orderform.aspx
When ASP.NET sends a page to the browser, it modifies any links in the page that use an
application-relative path by embedding a session ID value in the links. (Links with
absolute paths are not modified.) Session state is maintained as long as the user clicks
links that have been modified in this manner. However, if the client rewrites a URL that is
supplied by the application, ASP.NET may not be able to resolve the session ID and
associate the request with an existing session. In that case, a new session is started for
the request.
The session ID is embedded in the URL after the slash that follows the application name
and before any remaining file or virtual directory identifier. This enables ASP.NET to
resolve the application name before involving the SessionStateModule in the request.
Note
To improve the security of your application, you should allow users to log out of your application, at which
should call theAbandon method. This reduces the potential for a malicious user to get the unique identifier
retrieve private user data stored in the session.
Regenerating Expired Session Identifiers
By default, the session ID values that are used in cookieless sessions are recycled. That
is, if a request is made with a session ID that has expired, a new session is started by
using the SessionID value that is supplied with the request. This can result in a session
unintentionally being shared when a link that contains a cookieless SessionID value is
used by multiple browsers. (This can occur if the link is passed through a search engine,
through an e-mail message, or through another program.) You can reduce the chance of
session data being shared by configuring the application not to recycle session
identifiers. To do this, set the regenerateExpiredSessionId attribute of
the sessionState configuration element to true. This generates a new session ID when a
cookieless session request is made with an expired session ID.
Note
If the request that is made with the expired session ID is made by using the HTTP POST method, any post
whenregenerateExpiredSessionId is true. This is because ASP.NET performs a redirect to make sure tha
session identifier in the URL.
Custom Session Identifiers
You can implement a custom class to supply and validate SessionID values. To do so,
create a class that inherits the SessionIDManager class and override
the CreateSessionID and Validate methods with your own implementations. For an
example, see the example provided for the CreateSessionID method.
You can replace the SessionIDManager class by creating a class that implements
the ISessionIDManager interface. For example, you might have a Web application that
associates a unique identifier with non-ASP.NET pages (such as HTML pages or images)
by using an ISAPI filter. You can implement a custom SessionIDManager class to use this
unique identifier with ASP.NET session state. If your custom class supports cookieless
session identifiers, you must implement a solution for sending and retrieving session
identifiers in the URL.
Session Modes
ASP.NET session state supports several storage options for session variables. Each option
is identified as a session-state Mode type. The default behavior is to store session
variables in the memory space of the ASP.NET worker process. However, you can also
specify that session state should be stored in a separate process, in a SQL Server
database, or in a custom data source. If you do not want session state enabled for your
application, you can set the session mode to Off.
For more information, see Session-State Modes.
Session Events
ASP.NET provides two events that help you manage user sessions.
The Session_OnStart event is raised when a new session starts, and
the Session_OnEndevent is raised when a session is abandoned or expires. Session
events are specified in the Global.asax file for an ASP.NET application.
The Session_OnEnd event is not supported if the session Mode property is set to a
value other than InProc, which is the default mode.
Note
If the Global.asax file or Web.config file for an ASP.NET application is modified, the application will be re
stored in application state or session state will be lost. Be aware that some anti-virus software can update th
time of the Global.asax or Web.config file for an application.
For more information, see Session-State Events.
Access to ASP.NET session state is exclusive per session, which means that if two
different users make concurrent requests, access to each separate session is granted
concurrently. However, if two concurrent requests are made for the same session (by
using the same SessionID value), the first request gets exclusive access to the session
information. The second request executes only after the first request is finished. (The
second session can also get access if the exclusive lock on the information is freed
because the first request exceeds the lock time-out.) If the EnableSessionState value in
the @ Pagedirective is set to ReadOnly, a request for the read-only session information
does not result in an exclusive lock on the session data. However, read-only requests for
session data might still have to wait for a lock set by a read-write request for session
data to clear.
Procedure can return zero or n values whereas function can return one value
which is mandatory.
Procedures can have input/output parameters for it whereas functions can
have only input parameters.
Procedure allows select as well as DML statement in it whereas function allows
only select statement in it.
Functions can be called from procedure whereas procedures cannot be called
from function.
Exception can be handled by try-catch block in a procedure whereas try-catch
block cannot be used in a function.
In depth
Stored Procedure
A Stored Procedure is a program (or procedure) which is physically stored within a
database. They are usually written in a proprietary database language like PL/SQL for
Oracle database or PL/PgSQL for PostgreSQL. The advantage of a stored procedure is
that when it is run, in response to a user request, it is run directly by the database
engine, which usually runs on a separate database server. As such, it has direct
access to the data it needs to manipulate and only needs to send its results back to
the user, doing away with the overhead of communicating large amounts of data
back and forth.
User-defined Function
A user-defined function is a routine that encapsulates useful logic for use in other
queries. While views are limited to a single SELECT statement, user-defined
functions can have multiple SELECT statements and provide more powerful logic
than is possible with views.
User defined functions have three main categories:
1.
Download InternetMVC4AppDefault-noexe.zip - 1 MB
Download InternetMVC4AppDefault.zip - 3 MB
Table Of Contents
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
Introduction
Over View - Project Items
Solution File
Project File
Application Information
Properties
References
Special Folder
Bin Folder
ASP.NET Platform Folder
App_GlobalResources Folder
App_LocalResources Folder
App_Browsers Folder
App_Themes Folder
App_Data Folder
App_Code Folder
Application Folders
App_Start Folder
Areas Folder
Content Folder
Controllers Folder
Filters Folder
Images Folder
Models Folder
Scripts Folder
Views Folder
Configuration files
Global.asax
packages.config
Web.config
Summary
Introduction
ASP.NET MVC relies on Convention over Configuration. If you want to make your
website development easy and productive it's important to understand the Project
Items or Application Folder Structure of an ASP.NET MVC Application. In this article I
will explain the Project Items of an Internet Application Template of ASP.NET MVC 4. If
you are new to MVC then you might want to check my previous article
on Introduction to MVC 4.
I hope you will enjoy this article.I have put my time and efforts on all of my articles,
Please don't forget to mark yourvotes, suggestions and feedback to improve the
quality of this and upcoming articles.
Its very important to know the structure of application and file/folder conventions. In
this article Im going to explain all the above project items from
a beginners perspective. For getting a clear picture I have added more files and
folders to the newly created solution. Some of the folders are not exactly useful for
ASP.NET MVC but still I have added that folders too so that a new comer also can
understand which is used for what. Lets explore the Files/Folders from the above
Solution (InternetMVC4App).
Note: The attached files doesn't have any functionalities implemented, it's just the
application used for this article.
Solution File
Solution is a grouping of one or more projects that work together to create an
application. In a simple way we can say a solution is a structure for organizing
projects in Visual Studio.
Project File
The project file is an XML document that contains all the information and instructions
that MSBuild needs in-order to build your project, like the contents to include, the
platform requirements, versioning information, web server or database server
settings, and the tasks that must be performed. Every Visual Studio project includes
an MSBuild project file, with a file extension that reflects the type of projectfor
example, a C# project (.csproj), a Visual Basic.NET project (.vbproj), or a database
project (.dbproj).
Read more from www.asp.net.
Properties Folder
When talking about the "Properties" Folder, the first thing I wanted to mention is
the AppDesignerFolder entry in project file in our case .csproj file.
Properties folder is the first folder in the project node. If you expand the "Properties"
Folder, you can see a file namedAssemblyInfo.cs.
The AssemblyInfo.cs contains the details related to assembly version information and
other information about the assembly that will be displayed in detail section of
properties window of the assembly. The content of AssemblyInfo.cs is given below,
The below given screenshot shows the assembly version details in the 'properties'
window of assembly file.
If you double-click on this folder then it will show Project Properties page instead of
expanding it. Click here to view larger image
If required, the properties folder name can be renamed but we need to update
the .csproj file accordingly. If you are deleting the file AssemblyInfo.cs or
folder Properties then the assembly details wont be available in the details tab. The
below given screenshot shows the assembly version details after deleting the folder
or file.
Reference Folder
These are assemblies that have been referenced in our current project. If you want to add any
assembly reference or any service (WCF / Web Service) reference you can add it from here.
To add an assembly reference just right click on the Reference folder and click on the 'Add
Reference' menu, please refer the below screenshot.
Once you click on the above (Add Reference) menu then a popup will be shown like below
screen, select the required assembly and click on OK.
If you wanted to add a service reference then click on 'Add Service' menu, once you clicked on
'Add Service ' menu, you will get a screen a screen like below where you can give the service
URL,
give the service URL ( you can give .svc or .asmx URL here) if you want to get the old Add Web
Service menu then click on 'Advanced' option there you can see the 'Add Web Reference' menu.
After clicking on 'Add Web Reference' menu , now you got the old Web Service screen where you
used to give.asmx URL.
App_Browsers Folder
App_Browsers folder contains browser definitions ( .browser files). Browser definition
files contain definitions for individual browsers. At run time, ASP.NET uses the
information in the request header to determine what type of browser has made the
request. Then ASP.NET uses .browser files to determine the capabilities of the
browser.
Browser definition files were introduced in .NET Framework version 2.0. In earlier
versions of the .NET Framework, thebrowserCaps element was used to define
browser definitions in configuration files.
You can find existing browser definition files at
%SystemRoot%\Microsoft.NET\Framework\[VERSION]\Config\Browsers\
here [VERSION] is the framework version that you have already installed.
If you want to change the definitions of any of these browser definition files, Just
copy the appropriate file to our project's App_Browsers folder and modify the
definition as per the requirement. The below screen shot shows the content of newly
added BrowserFile1.browser file, We can see that it's just an XML file that describes
the capabilities of the browser.
App_Code Folder
App_Code is used for keeping class files , typed objects etc. Code from the App_Code
folder is referenced automatically in our application.The App_Code folder can contain
subdirectories of files, which can include class files that in different programming
languages (eg:- .cs,.vb).
As per my understanding App_Code is not really meant for Web Application Projects,
if we are using App_Code in WAP (Web Application Project) then we need to change
the "Build Action" to 'Content' from 'Compile' to work everything as expected, Read
more on Shared Code Folders in ASP.NET Web Site Projects
App_Data Folder
To add an ASP.NET Folder you can refer the below screen-shot,
The folder will be disabled if already that folder is added. You can see that the
App_Data is disabled as its already exists in our application.
This folder is meant for keeping data files such as XML, .mdf, .mdb files. In our
default MVC template this folder is used to manage membership and role
information. If you are using App_Data folder then you can mention the folder as |
DataDirectory| (enclosed in pipe symbols) in connection string. |DataDirectory| is a
substitution string that indicates the path to the App_Data folder. The files from the
App_Data folder are safe as IIS will not process any files from this folder. You can find
a sample code of DataDirectory in a project here App_Data in real application.
App_GlobalResources Folder
App_GlobalResource Folder contains resources (.resx and .resources files) that are
compiled into assemblies with global scope. Resources in the App_GlobalResources
folder are strongly typed and can be accessed programmatically
Read More on Web Page Resource from MSDN
App_LocalResources Folder
App_LocalResources Folder contains resources (.resx and .resources files) that are
associated with a specific page, user control, or master page in an application.
Read More on Web Page Resource from MSDN
App_Start Folder
This folder is just a convention and it separates some code from Global.asax,
And also we can avoid touching Global.asax file when using any new nugget
packages that needs to use Application_Start from Global.asax
AuthConfig.cs
AuthConfig.cs files helps us to login with our social networking sites like Facebook,
Twitter, Google etc.
BundleConfig.cs
FilerConfig.cs
The main purpose of App_Start and containing files are to move configuration logic
from Global.asax to set of static classes in the App_Start directory.
App_Themes Folder
Areas Folder
ASP.NET MVC allows us to partition our web application into smaller parts using
"Areas" Areas provide a way to separate a large MVC Web application into smaller
functional groupings. An area is effectively an MVC structure inside an application.
An application could contain several MVC structures (areas).
You can add an Area to a ASP.NET MVC project as shown below
I have named the area as "Admin" and after clicking on "Add" button a folder created
with "Areas" with subfolder "Admin".
The created "Area", "Admin" have all the entries/folders/files to work the
RazorViewEngine properly
Bin Folder
Normally this folder wont be listed in solution explorer until you click on Show All
menu. To get the "Show All" menu click on the Project Menu like below,
Other wise you can also get the menu from the Solution Explorer itself.
The compiled assembly for your MVC application is placed here, along with any
referenced assemblies that are not in the GAC. This folder contents are not served by
IIS. Click here to the contents of bin folder.
Content Folder
This is where we put our static contents like CSS, Images. This folder is just a
convention and its not mandatory to put our static files in this folder..
Controllers Folder
This is where we put our controller classes. This folder is just a convention we can
create our controller classes any where in the application. MVC will recognize any
class that implements the IController interface as a Controller regardless of the
location.
Filters Folder
Images Folder
All Images are kept in this folder and this folder is being referenced from the
Content\Site.css.
Models Folder
This is where you put your view model and domain model classes. This is a
convention and we can define model class anywhere in the project or in different
project also.
Scripts Folder
This directory is intended to hold the JavaScript libraries for your application. When
we created our application itself Visual Studio added many JavaScript libraries like
jQuery, knockout etc. This is just a convention.If we want we can keep this all in
other folder also.
Views Folder
/Views/Shared
This directory holds layouts (master-page in-terms of web forms) and views which
are not specific to a single controller.
/Views/[FolderName]
Views or Partial Views specific to that folder or single controller.
/Views/Web.config
This is not the configuration file for your application. It contains the configuration
required to make views work with ASP.NET and prevents views from being served by
IIS.
FavIcon File
This is the favicon for our web application.
Global.asax File
This is the global ASP.NET application class. Its code-behind class (Global.asax.cs) is
the place to register routing configuration, as well as set up any code to run on
application initialization or shutdown, or when unhandled exceptions occur.
Packages.config File
This file is used by NuGet. While creating the project itself the IDE interanlly used
NuGet for installing packages. This file is used to track the installed NuGet packages
with their respective versions.
Web.config File
Web.config is the main settings and configuration file for an ASP.NET web application
Summary
In this article I have explained ASP.NET MVC 4 Project Items from a beginner's
perspective. I hope you have enjoyed this article and got some value addition to your
knowledge.
I have put my time and efforts on all of my articles, Please don't forget to mark
your votes, suggestions and feedbackto improve the quality of this and upcoming
articles. Thanks for reading.
Introduction
MVC is one of three ASP.NET programming models.
MVC is a framework for building web applications using an MVC (Model View
Controller) design:
The Model represents the application core (for instance a list of database
records).
The View displays the data (the database records).
The Controller handles the input (to the database records).
The MVC model also provides full control over HTML, CSS, and JavaScript.
Prerequisites
Install
Install
Install
Install
Getting Started
The following steps will show how to build a MVC4 Mobile application.
Step 1
Open Visual Studio, select New Project -> ASP.NET MVC4 Web Application.
Step 2
Select Mobile Application from the Project Template.
Step 3
Go to Solution Explorer, right-click on the App_Data folder, and click on Add New
Item.
Select SQL Server Compact 4.0 Local Database and name it as Movies.sdf.
Step 4
Database is added to the App_Data folder.
Step 5
Create a table and name it MovieDBs.
Step 6
Add ConnectionString in Web.config.
Step 7
Right-click on Model->Add->Class and paste the following code:
Step 9
Run application using Opera Mobile Emulator and it shows the following result.
Introduction
In this article, I will walk you through a simple application using MVC4 and Entity
Framework 5 and will demonstrate how one can make use of code first technology. I
will be using MvsScaffold for quick creation of controllers and views. We will be
creating a TODO application.
Prerequisites
Background
Code first Code First enables you to describe a model by using C# or Visual
Basic .NET classes. Code First is a new development methodology available
beginning with the Entity Framework 4.1. You can use Code First to generate a new
database from a model, or map your model to an existing database. You can read
more here.
Entity Framework - Entity Framework (EF) is an object-relational mapper
that enables .NET developers to work with relational data using domain-specific
objects. It eliminates the need for most of the data-access code that developers
usually need to write. You can learn more about this here.
MVC 4 Successor of MVC3, ASP.NET MVC 4 is a framework for building
scalable, standards-based web applications using well-established design patterns
and the power of ASP.NET and the .NET Framework. Find all the related
information here.
MVC Scaffolding This is a Scaffolding package for ASP.NET which is
installed via NuGet using Install-Package MvcScaffolding command. Thanks
to Scott Hanselman and Steven Anderson.
Quick Preparation
Before we start, lets make sure you have NuGet package manager and SQL
component if you dont already have it.
In Visual Studio 2010 (I use professional one), go to Tools > Extension Manager
Click on the Online Gallery in search box type NuGet and hit enter. It will show the
NuGet Pakage Manager, I already have it installed to you can see the green click
mark. If you do not have install, double click it to install, and follow the instructions.
When you have the NuGet pakage install, you should be able to see the library
package manager. Tools-> Library Package Manager > Package Manager Console
Walk-through
Step 1: Create new MVC 4 application
Create a new MVC4 application, lets say its TODO
1:
2:
3:
4:
//Install
Install-Package EntityFramework
//Or Update
Update-Package EntityFramework
1: Install-Package MvcScaffolding
In case you are not already aware, hitting tab key brings up the options, make use of
it whenever you need it in Package Manager Console.
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.ComponentModel.DataAnnotations;
6: using System.ComponentModel.DataAnnotations.Schema;
7:
8: namespace TODO.Models
9: {
10:
public class Task
11:
{
12:
[Key]
13:
public int TaskId { get; set; }
14:
public string Name { get; set; }
15:
public string Description { get; set; }
16:
public int? StatusId { get; set; }
17:
[ForeignKey("StatusId")]
18:
public virtual Status Status { get; set; }
19:
public virtual ICollection<Note> Notes { get; set; }
20:
public DateTime? CreatedOn { get; set; }
21:
public DateTime? ModifiedOn { get; set; }
22:
}
23:
24:
public class Status
25:
{
26:
[Key]
27:
public int StatusId { get; set; }
28:
public string Name { get; set; }
29:
}
30:
31:
public class Note
32:
{
33:
[Key]
34:
public int NoteId { get; set; }
35:
public string Description { get; set; }
36:
public int? TaskId { get; set; }
37:
public DateTime? CreatedOn { get; set; }
38:
public DateTime? ModifiedOn { get; set; }
39:
}
40: }
Data Annotations
Line 5,6: References so that I could use the Data Annotation as you can see in line
12, 17, 26 and 33. You can refer following article for more information on Data
Annotations.
Defining Relations
Notice line 18, as it can see this property should be the virtual with an attribute
named ForeignKey with the FK, also check line 16, you need to have the StatusId to
link the tables.
Also if you notice line 36, Note should belong to some Task but do not need to have a
Note itself.
I have used [Key] is to explicitly mention the primary keys.
Step 5: Create Controller and Views
Go to Package Manager Console, run following commands
Collapse | Copy Code
Before we start entering data and check investigate the database lets hide the
CreatedOn and ModifiedOn fields from the view and get them updated from the code
itself.
Comment out the divs in _CreateOrEdit.cshtml of Notes and Tasks view which display
the ModifiedOn and CreatedOn fields.
Go to NoteRepository.cs and TaskRepository.cs, find InsertOrUpdate() method and
modify them as follows
Collapse | Copy Code
Notice line 5 and 9, where I am modifying the ModifiedOn and CreatedOn before
saving and updating the model.
Update: Adding some information about line 10 as per a user comment
Line 10: context.Entry(task).State = EntityState.Modified; This is a way to tell the
dbContext that some properties of the entity has been modified but SaveChanges()
is not called. Entity framework takes care of updating the entity with the modified
values. Calling the context.Entry() returns DbEntityEntry<TEntity> object which
provide access to information about and control of entities that are being tracked
by the DbContext.
In a simple words, it's the way to tell Entity Framework to update an entity with the
modified values.
You would also need to have following line in _CreateOrEdit.cshtml of tasks so persist
the values of CreatedOn.
Collapse | Copy Code
1: @Html.HiddenFor(m=>m.CreatedOn)
Run the application again and you should be able to add, update and delete the data
This is not it, this has automatically created the database for you, you can check that
out, Browse to SQLExpress database there you should be able to see a database for
this application.
Check the Tables, Columns, Primary Keys and Foreign Keys they are all in place
exactly as you created them in the models.
There is too much explain, however, as per the scope of this article, consider this
article as starting point to plunge deep into this. Before I wrap up this article, one
last thing want to inform you about which is called database initializer.
Go to TODOContext.cs in the Model folder, create a constructor of TODOContext as
follows:
Collapse | Copy Code
public TODOContext()
{
System.Data.Entity.Database.SetInitializer(
new System.Data.Entity.DropCreateDatabaseIfModelChanges<TODO.Models.TODOContext>());
}
I have already mentioned the database will be created in the SQLExpress, do not be
surprised if you do not see the database getting created in the database specified by
you in the connectionstring of the web.config.
Note: Entity framework will always try to connect to the local SQL Server Express
database (.\SQLEXPRESS). Starting with EF 5, Ef will use LocalDb if it doesnt detect
SQL Express running. SQL Express will always get precedence if it is installed, even if
you are using Visual Studio 2012.
Introduction
A few years ago, mobile web sites were more of an after-thought for many
developers unless you were involved in developing apps specifically targeted for
mobile devices. I was surprised to read on wiki that it was only March 2010 when
Apple began taking pre-orders for the iPad. What a different landscape we have seen
since. Desktops, Tablet and Mobile support are now a major design goal for any site
that needs a broad reach and this is only set to increase.
This article will demonstrate how MVC4, almost out of the box allows us to deliver
views that cater for specific mobile devices and keep the code base shared as much
as possible, creating mobile friendly web applications.
Sample Application
The sample web application for this article uses MVC 4, Microsofts latest web
development platform and Visual Studio 2012.
This article will walk through some fairly simple steps to mobile enable the Internet
Application template. By running the application, you will be able to send requests
for the home page which targets a Desktop, iPad and iPhone either by using different
devices to view the application or by sending a different User Agent string as
explained in the article. The code supports Desktop, iPad and iPhone as examples of
how to support mobile devices.
Background
There are a number of popular approaches for designing mobile sites
including Dedicated sites and Responsive Design and in MVC4 the 'Mobile
Website' template.
Dedicated sites for mobile and separate sites for desktops. One of the problems
with this model is the maintenance of two (if not three) different sites.
Responsive Design where the site gets designed with stylesheets that adapt to
screen size and available screen real-estate. When deciding on a responsive design
model, the choice needs to be made as to whether to start with a mobile site and
then perform progressive enhancement or whether to start with the desktop design
and do graceful degradation, each of which has its own design challenges. Added to
this is the need to cater for mobile devices with typically lower bandwidth and less
visible content, where this can often lead to downloading less optimal pages over
capped download limits.
MVC4 Mobile Website Template: When I first installed the preview release
of MVC4, I was drawn to the new mobile template. I was quite impressed as JQuery
and JQuery mobile where baked in and it performed pretty well. It soon became
apparent though that this was specifically a mobile orientated site and not suitable
for the desktop.
Considering Layout
When designing for the mobile platform, some obvious differences exist with
available real-estate. This commonly leads to single column layouts for mobiles,
multi column layouts for desktops and something in the middle for tablets. As you
start designing a mobile friendly site, it soon becomes apparent that to we are
dealing with Small, Medium and Large layouts.
After building and running this boiler plate site, results for a desktop and mobile can
be seen below.
After re-sizing the browser window, the page re-flowed based on a responsive
container.
The reason why this works is because of the following code snippet found in the
layout file _Layout.cshtml.
Collapse | Copy Code
The webkit based browsers found in the majority of mobile phones will automatically
attempt to reflow the page if this tag is present. Not too much work for a fairly
impressive result. Still some way to go though for a truly mobile experience.
/// <summary>
/// Evaluates incoming request and determines and adds an entry into the Display mode table
/// </summary>
private static void EvaluateDisplayMode()
{
DisplayModeProvider.Instance.Modes.Insert(0,
new DefaultDisplayMode("Phone")
{ //...modify file (view that is served)
//Query condition
ContextCondition = (ctx => (
//look at user agent
(ctx.GetOverriddenUserAgent() != null) &&
(//...either iPhone or iPad
(ctx.GetOverriddenUserAgent().IndexOf("iPhone",
StringComparison.OrdinalIgnoreCase) >= 0) ||
(ctx.GetOverriddenUserAgent().IndexOf("iPod", StringComparison.OrdinalIgnoreCase)
>= 0)
)
))
});
DisplayModeProvider.Instance.Modes.Insert(0,
new DefaultDisplayMode("Tablet")
{
ContextCondition = (ctx => (
(ctx.GetOverriddenUserAgent() != null) &&
(
(ctx.GetOverriddenUserAgent().IndexOf("iPad", StringComparison.OrdinalIgnoreCase)
>= 0) ||
(ctx.GetOverriddenUserAgent().IndexOf("Playbook",
StringComparison.OrdinalIgnoreCase) >= 0)
)
))
});
}
The code evaluates the User Agent string and if it finds a match for an iPad or
Playbook it adds an entry into the DisplayModes table for a Tablet. It also performs
checks for an iPhone or iPod and sets the Phone DisplayMode, respectively. In the
case of a desktop, currently this is the default so no need to add anything else at the
moment. You can see how easy it would be to add additional devices and the code
could be refactored further.
Note* There are obviously other frameworks geared specifically to identifying
requests to ascertain the client device but this method works with all the common
device types I have come across for mass market coverage. What you do have here
is a point in the pipeline to perform the necessary checks.
The table below shows examples of views that will be served if available based on
the User Agent.
Device
Client Request
View
PC
/YourMVCApp/Home
(controller)
Index.cshtml
iPad
iPhone
/YourMVCApp/Home
(controller)
Index.Phone.cshtml
Well thats a leap forward , we can now easily create a unique view based on
different devices!
The Visual Studio 2012 Solution explorer screen shot below shows the views we
created to support the new devices.
Note**
If you cannot see the Develop menu, enable it via Settings -> Preferences ->
Advanced and tick Show Develop menu in menu bar
Its quite re-assuring to see this working and already at this point we have some
reasonable control over the views we can render/return back to the client.
Now we have the Layout pages in place, we need to update our views to use them.
Collapse | Copy Code
@{
ViewBag.Title = "Tablet";
Layout = "../Shared/_Layout.Tablet.cshtml";
}
You can see we are also setting the title so that we can easily identify the current
view in the title bar of the browser.
Microsoft have fully embraced jQuery and jQuery Mobile now which is great. Because
we started with the Internet Application template, jQuery Mobile is not included so
we will go ahead and include it via the Package Manager. Right click the solution
and select Package Manager (this can also be done via the cmd line if you prefer).
The screenshot below shows the package manager after we entered and selected
JQuery Mobile.
Once this is added, we will see scripts and stylesheets added to Scripts and
Content respectively as shown below in Solution Explorer.
bundles.Add(new StyleBundle("~/Content/mobilecss").Include("~/Content/jquery.mobile*"));
bundles.Add(new ScriptBundle("~/bundles/jquerymobile").Include("~/Scripts/jquery.mobile*"));
Now the scripts and stylesheets have been added to the bundling tables, we can
utilise them inside our views by adding a render call in
the _Layout.Mobile.cshtml head section as show below.
Collapse | Copy Code
<head>
@Styles.Render("~/Content/mobileCss", "~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
This now fits in with the convention of the other configuration classes. (Maybe we will
see something like this in the next release of MVC)
The new DeviceConfig class can be seen below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.WebPages;
namespace MvcDesktop
{
/// <summary>
/// Device specific startup configuration
/// </summary>
public static class DeviceConfig
{
const string DeviceTypePhone = "Phone";
const string DeviceTypeTablet = "Tablet";
/// <summary>
/// Evaluates incoming request and determines device.
/// Adds an entry into the Display mode table
/// </summary>
public static void EvaluateDisplayMode()
{
//... refactored code here, similar to before...
}
}
}
Limitations
We did not add any web application tags or media queries to enhance our
decisions when rendering views.
We would in practice leverage more partial and shared views to ensure the
content could be managed centrally in a real world project.
The sample project only affects the Home page for the three devices.
Final Results
Our home page when requested by a Mobile, Tablet or Desktop can be seen below.
Mobile View
Tablet View
Desktop View
Conclusion
The separation of views for different device scenarios is certainly a model which sits
comfortably with an MVC developer like myself and can if approached carefully, lead
to very light weight views being served to mobile devices.
If you already possess MVC skills and spend most of your time developing for the
Microsoft platform, the new MVC baked in support for mobile devices is the best we
have had up to now. Of course you could have achieved the same in MVC3 but with a
bit more work.
Download WebAPIRc-noexe.zip - 1 MB
Download WebAPIRc.zip - 2.8 MB
Introduction
Ive spent last year working on ASP.NET MVC3 and felling good this year on MVC4. I
got some new exciting features after updating to MVC4, Web API is one of those
exciting features. I have read a lot on this feature and got a lot good articles on web.
But I didn't get any article that covers all concepts in one place. So I tried to combine
those in one place for beginners. Please don't consider this article as my own
invention.. all are taken from several articles. Please navigate links in the history
section for further detail.
Prerequisites
ASP.NET MVC 4
You can also use the Web API on MVC3. Just install the WebAPI pieces using the
Nuget Package Manager dialog.
Or use the Package Manager Console and type: Install-Package AspNetWebApi.
connections, for example. You can call an API from jQuery and better utilize the
client's machine and browser.
In this article we will show the basic database operations (CRUD) in an HTTP service
using ASP.NET Web API. Many HTTP services also model CRUD operations through
REST or REST-like APIs.
These two are very complimentary, but different enough that trying to build out HTTP
services using ASP.NET MVC took a lot of work to get right. The inclusion
of ASP.NET Web API in ASP.NET MVC (and availability elsewhere,
including ASP.NET Web Pages) means that you can build top-notch HTTP services in
an ASP.NET MVC application, taking advantage of a common base and using the
same underlying paradigms.
ASP.NET Web API includes support for the following features:
Modern HTTP programming model: Directly access and manipulate HTTP
requests and responses in your Web APIs using a new, strongly typed HTTP object
model. The same programming model and HTTP pipeline is symmetrically available
on the client through the new HttpClient type.
Full support for routes: Web APIs now support the full set of route
capabilities that have always been a part of the Web stack, including route
parameters and constraints. Additionally, mapping to actions has full support for
Select New Project from the Start page/File menu then New Project.
From the list of project templates: select ASP.NET MVC 4 Web Application.
Select your preferred location then type your desired project name and click OK.
3.
In the New ASP.NET MVC 4 Project dialog, select Web API. The View engine
will be Razor by default then clickOK.
Add a Model
A model is an object that represents the data in your application. ASP.NET Web API
can automatically serialize your model to JSON, XML or others. Then serialized and
write those data into the body of HTTP response message. As long as a client can
read the serialization format, it can deserialize the object. Most of the clients are able
to parse XML or JSON. By setting the Accept header in the HTTP request message the
client can indicate which format it wants.
We will prove the above concepts step by step. Let's start by creating a simple
model.
In Solution Explorer, right-click the Models folder then select Add then select Class.
Name the class "Book". Next, add the following properties to the Book class.
Collapse | Copy Code
Add a Repository
For serving our article purposes lets store list in memory and the HTTP service needs
to store a list of books.
Lets separate the book object from our service implementation. This is because we
can change the backing store without rewriting the service class. This type of design
is called the repository pattern. For this purpose we need a generic interface. Lets
see the following steps to know, how to define a generic interface for a book
repository.
In Solution Explorer, right-click the Models folder. Select Add, then select New Item.
Then add another class to the Models folder, named "BookRepository" which will
implement theIBookRespository interface derived from IBookRepository:
Following are the implementations:
Collapse | Copy Code
return true;
}
}
The repository will keep books in local memory. We already mentioned and we can
compromise for article purpose but in a real application please don't do it. Because
you need to store data either in a database or in cloud storage. The repository
pattern will make it easier to change the implementation later.
Add a Web API Controller
If you have worked with ASP.NET MVC, then you are already familiar with
controllers. In ASP.NET Web API, a controller is a class that handles HTTP requests
from the client. The New Project wizard created two controllers for you when it
created the project. To see them, expand the Controllers folder in Solution Explorer.
HomeController is a traditional ASP.NET MVC controller. It is responsible for serving
HTML pages for the site, and is not directly related to our Web API
service. ValuesController is an example WebAPI controller.
As we want to start from the scratch, go ahead and delete ValuesController. Do we
need to mention how to delete? ...ok right-clicking the file in Solution Explorer and
select Delete.
Now add a new controller, as follows:
In Solution Explorer, right-click the Controllers folder. Select Add and then
select Controller.
In the Add Controller wizard, name the controller BooksController. In the Template
drop-down list, select Empty API Controller. Then click Add.
The Add Controller wizard will create a file named BooksController.cs in the
Controllers folder. If this file is not open already, double-click the file to open it.
Add the following using statements and add a field for holding
an IBookRepository instance.
Collapse | Copy Code
using WebAPI.Models;
using System.Net;
Collapse | Copy Code
using Microsoft.Practices.Unity;
using WebAPI.Models;
Getting Book
The book service will expose two "read" methods: one that returns a list of all books,
and another that looks up a book by ID. The method name starts with "Get", so by
convention it maps to GET requests. Further, the method has no parameters, so it
maps to a URI with no "id" segment in the path. The second method name also starts
with "Get", but the method has a parameter named id. This parameter is mapped to
the "id" segment of the URI path. TheASP.NET Web API framework automatically
converts the ID to the correct data type (int) for the parameter.
Notice that GetBook throws an exception of type HttpResponseException if id is not
valid. This exception will be translated by the framework into a 404 (Not
Found) error.
Collapse | Copy Code
}
return book;
}
Creating a Book
To create a new book, the client sends an HTTP POST request, with the new book
in the body of the request message.
Here is a simple implementation of the method:
Collapse | Copy Code
To handle POST requests, we define a method whose name starts with "Post...". The
method takes a parameter of type Book. By default, parameters with complex types
are deserialized from the request body. Therefore, we expect the client to send us a
serialized representation of a Book object, using either XML or JSON for the
serialization.
This implementation will work, but it is missing a couple of things to complete.
Response code: By default, the Web API framework sets the response status
code to 200 (OK). But according to the HTTP/1.1 protocol, when a POST request
results in the creation of a resource, the server should reply with status 201
(Created).
Location: When the server creates a resource, it should include the URI of the
new resource in the Location header of the response.
ASP.NET Web API makes it easy to manipulate the HTTP response message. Here is
the improved implementation:
Collapse | Copy Code
Updating a Book
Updating a book with PUT is straightforward. Simply define a method whose name
starts with "Put...":
Collapse | Copy Code
This method takes two parameters, the book ID and the updated book. The id
parameter is taken from the URI path, and the book parameter is deserialized from
the request body. By default, the ASP.NET Web API framework takes simple
parameter types from the route and complex types from the request body.
Deleting a Book
To delete a book, define a "Delete..." method.
Collapse | Copy Code
_repository.Remove(id);
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
<script type="text/javascript">
$(function() {
$.getJSON(
"api/books",
function(data) {
$.each(data,
function(index, value) {
$("#bookTemplate").tmpl(value).appendTo("#books");
}
);
$("#loader").hide();
$("#addBook").show();
}
);
$("#addBook").submit(function() {
$.post(
"api/books",
$("#addBook").serialize(),
function(value) {
$("#bookTemplate").tmpl(value).appendTo("#books");
$("#name").val("");
$("#price").val("");
},
"json"
);
return false;
});
$(".removeBook").live("click", function() {
$.ajax({
type: "DELETE",
url: $(this).attr("href"),
context: this,
success: function() {
$(this).closest("li").remove();
}
});
return false;
});
The above examples demonstrate Get all books, Add Book and Remove a Book from
the list. The find function helps us to get a book by ID. For binding all the book list
we used jQuery template over here. Following portion also needed for that:
Collapse | Copy Code
<label id="book">
</label>
</div>
<div class="grid_8 omega">
<ul class="books" id="books">
</ul>
</div>
</div>
We have used jQuery template for making the right site book list. Please download
source code for more detail.
Points of Interest
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Introduction
Majority of web projects needs handling users and therefore user login section. In
this article I'm writing about how quickly create user login, logout functionality and
display that status.
This article is not related to any specific database so you can use whatever you
need, e.g. MSSQL, PostgreSQL, MySQL etc... In this case I'm showing example with
MSSQL.
In those screenshots I'm creating MVC4 project, but this tutorial should work on
MVC3 too.
Then select that you are using Razor engine. Check create Tests if you are planning
to use it later in your project. If not - leave it unchecked.
Now paste code below to that query window and click execute (shortcut
CTRL+SHIFT+E)
Collapse | Copy Code
This code has created a table and inserted user test with password test. Password is
encoded with SHA1. To generate your own - google online converter to sha1, but in
this example better leave it as it is.
Call it Index (The same as method name) and select to use layout.
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel.DataAnnotations;
System.Data;
System.Data.SqlClient;
System.Linq;
System.Web;
namespace Creating_a_custom_user_login_form.Models
{
public class User
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember on this computer")]
public bool RememberMe { get; set; }
/// <summary>
/// Checks if user with given password exists in the database
/// </summary>
/// <param name="_username">User name</param>
/// <param name="_password">User password</param>
/// <returns>True if user exist and password is correct</returns>
public bool IsValid(string _username, string _password)
{
using (var cn = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename" +
@"='C:\Tutorials\1 - Creating a custom user login form\Creating " +
@"a custom user login form\App_Data\Database1.mdf';Integrated Security=True"))
{
string _sql = @"SELECT [Username] FROM [dbo].[System_Users] " +
@"WHERE [Username] = @u AND [Password] = @p";
var cmd = new SqlCommand(_sql, cn);
cmd.Parameters
.Add(new SqlParameter("@u", SqlDbType.NVarChar))
.Value = _username;
cmd.Parameters
.Add(new SqlParameter("@p", SqlDbType.NVarChar))
.Value = Helpers.SHA1.Encode(_password);
cn.Open();
var reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Dispose();
cmd.Dispose();
return true;
}
else
{
reader.Dispose();
cmd.Dispose();
return false;
}
}
}
}
}
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
namespace Helpers
{
public class SHA1
{
public static string Encode(string value)
{
var hash = System.Security.Cryptography.SHA1.Create();
var encoder = new System.Text.ASCIIEncoding();
var combined = encoder.GetBytes(value ?? "");
return BitConverter.ToString(hash.ComputeHash(combined)).ToLower().Replace("-", "");
}
}
}
using
using
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Web;
System.Web.Mvc;
System.Web.Security;
namespace Creating_a_custom_user_login_form.Controllers
{
public class UserController : Controller
{
//
// GET: /User/
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Models.User user)
{
if (ModelState.IsValid)
{
if (user.IsValid(user.UserName, user.Password))
{
FormsAuthentication.SetAuthCookie(user.UserName, user.RememberMe);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Login data is incorrect!");
}
}
return View(user);
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
}
}
@model Creating_a_custom_user_login_form.Models.User
@{
ViewBag.Title = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
@Html.ValidationSummary(true, "Login failed. Check your login details.");
<div>
<fieldset>
<legend>Login</legend>
<div class="editor-label">
@Html.LabelFor(u => u.UserName)
</div>
<div class="editor-field">
@Html.TextBoxFor(u => u.UserName)
@Html.ValidationMessageFor(u => u.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(u => u.Password)
</div>
<div class="editor-field">
@Html.PasswordFor(u => u.Password)
@Html.ValidationMessageFor(u => u.Password)
</div>
<div class="editor-label">
@Html.CheckBoxFor(u => u.RememberMe)
@Html.LabelFor(u => u.RememberMe)
</div>
<input type="submit" value="Log In" />
</fieldset>
</div>
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div style="width: auto; background-color: #728ea7;">
@if (Request.IsAuthenticated) {
<strong>@Html.Encode(User.Identity.Name)</strong>
@Html.ActionLink("Sign Out", "Logout", "User")
}
else {
@Html.ActionLink("Register", "Register", "User")
<span> | </span>
@Html.ActionLink("Sign In", "Login", "User")
}
</div>
@RenderBody()
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
Thats it!
The source code can be downloaded here.
Review
So what we have did here. We created a table with test user. Data is hashed, so we
can call it kind of secure. We have included external project with helper functions. It
can be filled with more useful stuff and shared with other your projects in the same
way you did here. (I like to seperate Interfaces and Business logic like this too).
Next we build two controllers and views. One for first page and other for user login.
We have edited our Layout so we could see some information and login buttons all
the time (while we are using that layout)
I hope this article helped you to understand basic usage and will help you in future.