NET NOTES

Embed Size (px)

DESCRIPTION

notes

Citation preview

ASP.NET Page Life Cycle Overview.NET Framework 4Other Versions

260 out of 324 rated this helpful-Rate this topicUpdated: May 2011When an ASP.NET page runs, the page goes through a life cycle in which it performs a series of processing steps. These include initialization, instantiating controls, restoring and maintaining state, running event handler code, and rendering. It is important for you to understand the page life cycle so that you can write code at the appropriate life-cycle stage for the effect you intend.If you develop custom controls, you must be familiar with the page life cycle in order to correctly initialize controls, populate control properties with view-state data, and run control behavior code. The life cycle of a control is based on the page life cycle, and the page raises many of the events that you need to handle in a custom control.This topic contains the following sections: General Page Life-cycle Stages Life-cycle Events Additional Page Life Cycle Considerations Catch-Up Events for Added Controls Data Binding Events for Data-Bound Controls Login Control EventsGeneral Page Life-Cycle Stages

In general terms, the page goes through the stages outlined in the following table. In addition to the page life-cycle stages, there are application stages that occur before and after a request but are not specific to a page. For more information, seeIntroduction to the ASP.NET Application Life CycleandASP.NET Application Life Cycle Overview for IIS 7.0.Some parts of the life cycle occur only when a page is processed as a postback. For postbacks, the page life cycle is the same during a partial-page postback (as when you use anUpdatePanelcontrol) as it is during a full-page postback.StageDescription

Page requestThe 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.

StartIn the start stage, page properties such asRequestandResponseare set. At this stage, the page also determines whether the request is a postback or a new request and sets theIsPostBackproperty. The page also sets theUICultureproperty.

InitializationDuring page initialization, controls on the page are available and each control'sUniqueIDproperty 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.

LoadDuring load, if the current request is a postback, control properties are loaded with information recovered from view state and control state.

Postback event handlingIf the request is a postback, control event handlers are called. After that, theValidatemethod of all validator controls is called, which sets theIsValidproperty 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.)

RenderingBefore rendering, view state is saved for the page and all controls. During the rendering stage, the page calls theRendermethod for each control, providing a text writer that writes its output to theOutputStreamobject of the page'sResponseproperty.

UnloadTheUnloadevent 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 asResponseandRequestare 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 asonclick, 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 theAutoEventWireupattribute of the@Pagedirective is set totrue, page events are automatically bound to methods that use the naming convention ofPage_event, such asPage_LoadandPage_Init. For more information on automatic event wire-up, seeASP.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 page-processing 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 EventTypical Use

PreInitRaised after the start stage is complete and before the initialization stage begins.Use this event for the following: Check theIsPostBackproperty to determine whether this is the first time the page is being processed. TheIsCallbackandIsCrossPagePostBackproperties have also been set at this time. Create or re-create dynamic controls. Set a master page dynamically. Set theThemeproperty dynamically. Read or set profile property values.NoteIf the request is a postback, the values of the controls have not yet been restored from view state. If you set a control property at this stage, its value might be overwritten in the next event.

InitRaised after all controls have been initialized and any skin settings have been applied. TheInitevent of individual controls occurs before theInitevent of the page.Use this event to read or initialize control properties.

InitCompleteRaised at the end of the page's initialization stage. Only one operation takes place between theInitandInitCompleteevents: tracking of view state changes is turned on. View state tracking enables controls to persist any values that are programmatically added to theViewStatecollection. Until view state tracking is turned on, any values added to view state are lost across postbacks. Controls typically turn on view state tracking immediately after they raise theirInitevent.Use this event to make changes to view state that you want to make sure are persisted after the next postback.

PreLoadRaised after the page loads view state for itself and all controls, and after it processes postback data that is included with theRequestinstance.

LoadThePageobject calls theOnLoadmethod on thePageobject, and then recursively does the same for each child control until the page and all controls are loaded. TheLoadevent of individual controls occurs after theLoadevent of the page.Use theOnLoadevent method to set properties in controls and to establish database connections.

Control eventsUse these events to handle specific control events, such as aButtoncontrol'sClickevent or aTextBoxcontrol'sTextChangedevent.NoteIn a postback request, if the page contains validator controls, check theIsValidproperty of thePageand of individual validation controls before performing any processing.

LoadCompleteRaised at the end of the event-handling stage.Use this event for tasks that require that all other controls on the page be loaded.

PreRenderRaised after thePageobject has created all controls that are required in order to render the page, including child controls of composite controls. (To do this, thePageobject callsEnsureChildControlsfor each control and for the page.)ThePageobject raises thePreRenderevent on thePageobject, and then recursively does the same for each child control. ThePreRenderevent of individual controls occurs after thePreRenderevent of the page.Use the event to make final changes to the contents of the page or its controls before the rendering stage begins.

PreRenderCompleteRaised after each data bound control whoseDataSourceIDproperty is set calls itsDataBindmethod. For more information, seeData Binding Events for Data-Bound Controlslater in this topic.

SaveStateCompleteRaised after view state and control state have been saved for the page and for all controls. Any changes to the page or controls at this point affect rendering, but the changes will not be retrieved on the next postback.

RenderThis is not an event; instead, at this stage of processing, thePageobject calls this method on each control. All ASP.NET Web server controls have aRendermethod that writes out the control's markup to send to the browser.If you create a custom control, you typically override this method to output the control's markup. However, if your custom control incorporates only standard ASP.NET Web server controls and no custom markup, you do not need to override theRendermethod. For more information, seeDeveloping Custom ASP.NET Server Controls.A user control (an .ascx file) automatically incorporates rendering, so you do not need to explicitly render the control in code.

UnloadRaised for each control and then for the page.In controls, use this event to do final cleanup for specific controls, such as closing control-specific database connections.For the page itself, use this event to do final cleanup work, such as closing open files and database connections, or finishing up logging or other request-specific tasks.NoteDuring the unload stage, the page and its controls have been rendered, so you cannot make further changes to the response stream. If you attempt to call a method such as theResponse.Writemethod, the page will throw an exception.

Additional Page Life Cycle Considerations

Individual ASP.NET server controls have their own life cycle that is similar to the page life cycle. For example, a control'sInitandLoadevents occur during the corresponding page events.Although bothInitandLoadrecursively occur on each control, they happen in reverse order. TheInitevent (and also theUnloadevent) for each child control occur before the corresponding event is raised for its container (bottom-up). However theLoadevent for a container occurs before theLoadevents for its child controls (top-down). Master pages behave like child controls on a page: the master pageInitevent occurs before the pageInitandLoadevents, and the master pageLoadevent occurs after the pageInitandLoadevents.When you create a class that inherits from thePageclass, in addition to handling events raised by the page, you can override methods from the page's base class. For example, you can override the page'sInitializeCulturemethod to dynamically set culture information. Note that when an event handler is created using thePage_eventsyntax, the base implementation is implicitly called and therefore you do not need to call it in your method. For example, the base page class'sOnLoadmethod is always called, whether you create aPage_Loadmethod or not. However, if you override the pageOnLoadmethod with theoverridekeyword (Overridesin Visual Basic), you must explicitly call the base method. For example, if you override theOnLoadmethod on the page, you must callbase.Load(MyBase.Loadin Visual Basic) in order for the base implementation to be run.The following illustration shows some of the most important methods of thePageclass 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 thePageclass.) 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.

Catch-Up Events for Added Controls

If controls are created dynamically at run time or declaratively within templates of data-bound controls, their events are initially not synchronized with those of other controls on the page. For example, for a control that is added at run time, theInitandLoadevents might occur much later in the page life cycle than the same events for controls created declaratively. Therefore, from the time that they are instantiated, dynamically added controls and controls in templates raise their events one after the other until they have caught up to the event during which it was added to theControlscollection.Data Binding Events for Data-Bound Controls

To help you understand the relationship between the page life cycle and data binding events, the following table lists data-related events in data-bound controls such as theGridView,DetailsView, andFormViewcontrols.Control EventTypical Use

DataBindingRaised after the control'sPreRenderevent, which occurs after the page'sPreRenderevent. (This applies to controls whoseDataSourceIDproperty is set declaratively. Otherwise the event happens when you call the control'sDataBindmethod.)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(GridViewonly) orItemCreated(DataList,DetailsView,SiteMapPath,DataGrid,FormView,Repeater, andListViewcontrols)Raised after the control'sDataBindingevent.Use this event to manipulate content that is not dependent on data binding. For example, at run time, you might programmatically add formatting to a header or footer row in aGridViewcontrol.

RowDataBound(GridViewonly) orItemDataBound(DataList,SiteMapPath,DataGrid,Repeater, andListViewcontrols)Raised after the control'sRowCreatedorItemCreatedevent.When this event occurs, data is available in the row or item, so you can format data or set theFilterExpressionproperty on child data source controls in order to display related data within the row or item.

DataBoundRaised at the end of data-binding operations in a data-bound control. In aGridViewcontrol, data binding is complete for all rows and any child controls.Use this event to format data-bound content or to initiate data binding in other controls that depend on values from the current control's content. (For more information, seeCatch-Up Events for Added Controlsearlier in this topic.)

Nested Data-Bound ControlsIf a child control has been data bound, but its container control has not yet been data bound, the data in the child control and the data in its container control can be out of sync. This is true particularly if the data in the child control performs processing based on a data-bound value in the container control.For example, suppose you have aGridViewcontrol that displays a company record in each row, and it displays a list of the company officers in aListBoxcontrol. To fill the list of officers, you would bind theListBoxcontrol to a data source control (such asSqlDataSource) that retrieves the company officer data using the company ID in a query.If theListBoxcontrol's data-binding properties, such asDataSourceIDandDataMember, are set declaratively, theListBoxcontrol will try to bind to its data source during the containing row'sDataBindingevent. However, the CompanyID field of the row does not contain a value until theGridViewcontrol'sRowDataBoundevent occurs. In this case, the child control (theListBoxcontrol) is bound before the containing control (theGridViewcontrol) is bound, so their data-binding stages are out of sync.To avoid this condition, put the data source control for theListBoxcontrol in the same template item as theListBoxcontrol itself, and do not set the data binding properties of theListBoxdeclaratively. Instead, set them programmatically at run time during theRowDataBoundevent, so that theListBoxcontrol does not bind to its data until the CompanyID information is available.For more information, seeBinding to Data Using a Data Source Control.Login Control Events

TheLogincontrol can use settings in the Web.config file to manage membership authentication automatically. However, if your application requires you to customize how the control works, or if you want to understand howLogincontrol events relate to the page life cycle, you can use the events listed in the following table.Control EventTypical Use

LoggingInRaised during a postback, after the page'sLoadCompleteevent 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.

AuthenticateRaised after theLoggingInevent.Use this event to override or enhance the default authentication behavior of aLogincontrol.

LoggedInRaised 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.

LoginErrorRaised if authentication was not successful.Use this event to set text in the control that explains the problem or to direct the user to a different page.

ASP.Net life cycle specifies, how: ASP.Net processes pages to produce dynamic output The application and its pages are instantiated and processed ASP.Net compiles the pages dynamicallyThe ASP.Net life cycle could be divided into two groups:1. Application Life Cycle2. Page Life CycleASP.Net Application Life Cycle:The application life cycle has the following stages: 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: An object of the ApplicationManager class is created. An object of the HostingEnvironment class is created to provide information regarding the resources. Top level items in the application are compiled. Response objects are created . the application objects: HttpContext, HttpRequest and HttpResponse are created and initialized. An instance of the HttpApplication object is created and assigned to the request. The request is processed by the HttpApplication class. Different events are raised by this class for processing the request.ASP.Net Page Life Cycle:When a page is requested, it is loaded into the server memory, processed and sent to the browser. Then it is unloaded from the memory. At each of this steps, methods and events are available, which could be overridden according to the need of the application. In other words, you can write your own code to override the default code.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 Instantiation of the controls on the page Restoration and maintenance of the state Execution of the event handler codes Page renderingUnderstanding 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. Validation .Validate method of the validation control is called and if it runs successfully, the IsValid property of the page is set to true. 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.ASP.Net Page Life Cycle Events:At each stage of the page life cycle, the page raises some events, which could be coded. An event handler is basically a function or subroutine, bound to the event, using declarative attributes like Onclick or handle.Following are the page life cycle events: 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. LoadViewState .LoadViewState event allows loading view state information into the controls. LoadPostData .during this phase, the contents of all the input fields defined with the 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. PreRenderComplete .as the PreRender event is recursively fired for all child controls, this event ensures the completion of the pre-rendering phase. SaveStateComplete .state of control on the page is saved. Personalization, control state and view state information is saved. The HTML markup is generated. This stage can be handled by overriding the Render method or creating a Page_Render handler. UnLoad .the UnLoad phase is the last phase of the page life cycle. It raises the UnLoad event for all controls recursively and lastly for the page itself. Final cleanup is done and all resources and references, such as database connections, are freed. This event can be handled by modifying the OnUnLoad method or creating a Page_UnLoad handler.

ASP.NET Cookies Overview.NET Framework 4Other Versions

53 out of 63 rated this helpful-Rate this topicA cookie is a small bit of text that accompanies requests and pages as they go between the Web server and browser. The cookie contains information the Web application can read whenever the user visits the site.A Visual Studio project with source code is available to accompany this topic:Download.This topic contains the following: Scenarios Background Code Examples Class Reference Additional Resources What's NewScenarios

Cookies provide a means in Web applications to store user-specific information. For example, when a user visits your site, you can use cookies to store user preferences or other information. When the user visits your Web site another time, the application can retrieve the information it stored earlier.Back to topBackground

A cookie is a small bit of text that accompanies requests and pages as they go between the Web server and browser. The cookie contains information the Web application can read whenever the user visits the site.For example, if a user requests a page from your site and your application sends not just a page, but also a cookie containing the date and time, when the user's browser gets the page, the browser also gets the cookie, which it stores in a folder on the user's hard disk.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 LimitationsMost 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, seeASP.NET State Management OverviewandASP.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 CookiesThe browser is responsible for managing cookies on a user system. Cookies are sent to the browser via theHttpResponseobject that exposes a collection calledCookies. You can access theHttpResponseobject as theResponseproperty of yourPageclass. Any cookies that you want to send to the browser must be added to this collection. When creating a cookie, you specify aNameandValue. 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 expiration times, a user might 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 theCookiescollection in a number of ways. The following example shows two methods to write cookies:C#VBResponse.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 theCookiescollection, one nameduserNameand the other namedlastVisit. For the first cookie, the values of theCookiescollection are set directly. You can add values to the collection this way becauseCookiesderives from a specialized collection of typeNameObjectCollectionBase.For the second cookie, the code creates an instance of an object of typeHttpCookie, sets its properties, and then adds it to theCookiescollection via theAddmethod. When you instantiate anHttpCookieobject, 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 typeDateTime. However, thelastVisitedvalue is also a date-time value. Because all cookie values are stored as strings, the date-time value has to be converted to aString.Cookies with More Than One ValueYou 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 nameduserNameandlastVisit, you can create a single cookie nameduserInfothat has the subkeysuserNameandlastVisit.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 4096bytes and you can't store more than 20cookies per site. By using a single cookie with subkeys, you use fewer of those 20cookies 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 200bytes.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#VBResponse.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 ScopeBy 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 ApplicationTo limit cookies to a folder on the server, set the cookie'sPathproperty, as in the following example:C#VBHttpCookie 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 theCookiescollection directly as shown in earlier examples.

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 browsers, but if your application depends on cookies tied to a specific path, be sure that the URLs in any hyperlinks you create match the case of thePathproperty value.

Limiting Cookie Domain ScopeBy 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'sDomainproperty, as in this example:C#VBResponse.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 theDomainproperty to create a cookie that can be shared among multiple subdomains, as shown in the following example:C#VBResponse.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 CookiesWhen 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 theHttpRequestobject, which is available as theRequestproperty of yourPageclass. The structure of theHttpRequestobject is essentially the same as that of theHttpResponseobject, so you can read cookies out of theHttpRequestobject much the same way you wrote cookies into theHttpResponseobject. The following code example shows two ways to get the value of a cookie namedusernameand display its value in aLabelcontrol:C#VBif(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 aNullReferenceExceptionexception. Notice also that theHtmlEncodemethod 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 necessarily be able to read each other's cookies. For example, if you use Internet Explorer to test a page one time, but then later use a different browser to 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#VBif(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 subkeylastVisit, which was set earlier to the string representation of aDateTimevalue. Cookies store values as strings, so if you want to use thelastVisitvalue as a date, you have to convert it to the appropriate type, as in this example:C#VBDateTime dt;dt = DateTime.Parse(Request.Cookies["userInfo"]["lastVisit"]);The subkeys in a cookie are typed as a collection of typeNameValueCollection. 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#VBif(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 DateThe 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'sExpiresproperty 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 theExpiresproperty of a cookie that you have set in theHttpResponseobject, before the cookie has been sent to the browser. However, you cannot get the expiration back in theHttpRequestobject.

Reading Cookie CollectionsYou 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 theCookiescollection using code such as the following.C#VBSystem.Text.StringBuilder output = new System.Text.StringBuilder();HttpCookie aCookie;for(int i=0; im.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 calleddatabase initializer.Go toTODOContext.csin theModelfolder, create a constructor ofTODOContextas follows:Collapse|Copy Codepublic TODOContext(){ System.Data.Entity.Database.SetInitializer( new System.Data.Entity.DropCreateDatabaseIfModelChanges()); }It does as the name saysDropCreateDatabaseIfModelChangeswhen you change any Model by adding or deleting some properties, the current database will be dropped and it will be recreated. If you modify the model without having this constructor, you might see an error as follows

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 theweb.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.Bottom of FormMVC4 Mobile Friendly Web ApplicationsByCarl Randall,13 Sep 2012

4.92(23 votes)

Top of Form Download MvcMobileFriendlyV1_1.zip - 9.5 MBIntroductionA 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 howMVC4, 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 ApplicationThe 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.BackgroundThere are a number of popular approaches for designing mobile sites includingDedicated sitesandResponsive Designand inMVC4the'Mobile Website'template.Dedicated sitesfor mobile and separate sites for desktops. One of the problems with this model is the maintenance of two (if not three) different sites.Responsive Designwhere 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.MVC4Mobile WebsiteTemplate: When I first installed the preview release ofMVC4, 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 LayoutWhen 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.Creating the Web applicationChoosing the Internet Application template gives us a site that is primarily optimised for the desktop. We will start by creating our mobile friendly site here as shown below.

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.Detecting Mobile DevicesTime to enable our site to detect requests made to our site from different mobile devices. We are going to do this by examining the User Agent string and make decisions based on this understanding.We will add a new method to ourGlobal.asax.csfile that gets called in the methodApplication_Start()and name itEvaluateDisplayMode.Collapse|Copy Codeprotected void Application_Start(){ AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); /* Boilerplate code above... */ EvaluateDisplayMode(); //Evaluate incoming request and update Display Mode table}TheEvaluateDisplayMode()method itself.Collapse|Copy Code/// /// Evaluates incoming request and determines and adds an entry into the Display mode table/// 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.Delivering Device Specific ViewsAs a result of the Display Modes table having been updated from the detection above, the MVC engine will then modify the view it was going to serve, to match the mobile device request if available.The table below shows examples of views that will be served if available based on the User Agent.DeviceClient RequestView

PC/YourMVCApp/Home(controller)Index.cshtml

iPad/YourMVCApp/Home (controller)Index.Tablet.cshtml

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.

Testing what we have so far...Although there is no substitute for testing on a hardware mobile device, during initial development, Safari makes it easy to send a request to the server with a specific user agent. You can also add your own User Agent strings for devices not available out of the box with Safari using Safari to send a specific User Agent.You can set a new User agent string via Menu->Develop->User Agent. The Safari screen shot below shows the User Agent string being set for a request.

Note**If you cannot see the Develop menu, enable it via Settings -> Preferences -> Advanced and tick Show Develop menu in menu barIts 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.Enhancing our Mobile ViewAlthough we have made good progress, our mobile views still leave a lot to be desired. We could just amend our mobile view at this point and in some circumstances that would be appropriate. We will take it one step further and create Layout pages for each of our device types as can be seen below.

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.Adding Mobile scriptsMicrosoft 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.

Enabling Mobile scriptsAlthough we now have the mobile scripts available, we still need to reference them in our mobile views. The release ofMVC4Bundles appears to work well now for scripts and stylesheets. We will add our new mobile scripts and stylesheets to the bundling tables with the following entries inside theRegisterBundlesmethod located inBundleConfig.csin theApp_StartSolution folder.Collapse|Copy Codebundles.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.cshtmlhead section as show below.Collapse|Copy Code

@Styles.Render("~/Content/mobileCss", "~/Content/css")@Scripts.Render("~/bundles/modernizr")

Styling the mobile views with jQuery mobileAlthough styling the mobile view with JQuery Mobile is beyond the scope of this article, I went ahead and added a little just to get our views looking differently.Folowing convention (a touch of refactoring)As we have added code to our Global.asax 'Application_Start()', it makes sense to extract our current 'EvaluateDisplayMode()' into it's own Device configuration, so that as it grows, it doesn't bloat the view of startup and makes it more maintainable. The other configuration classes reside in the 'App_Start' solution folder and we will use the same convention and create astatic'DeviceConfig' class as shown below.

This enables us to reduces our device evaluation to one line in 'Application_Start()' as shown below.Collapse|Copy CodeDeviceConfig.EvaluateDisplayMode(); //Evaluate incoming request and update Display Mode tableThis 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.Collapse|Copy Codeusing System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.WebPages;namespace MvcDesktop{ /// /// Device specific startup configuration /// public static class DeviceConfig { const string DeviceTypePhone = "Phone"; const string DeviceTypeTablet = "Tablet"; /// /// Evaluates incoming request and determines device. /// Adds an entry into the Display mode table /// 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 ResultsOur home page when requested by a Mobile, Tablet or Desktop can be seen below.Mobile View

Tablet View

Desktop View

ConclusionThe 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.The areas we looked at1. Developing a single site for all devices2. Evaluating the client device making the request3. Serving different views depending on device4. Being able to leverage jQuery, jQuery Mobile and script management with Layouts.Hope you enjoyed the article!Bottom of FormASP.NET WebAPI: Getting Started with MVC4 and WebAPIByMonjurul Habib,31 Jul 2012

4.88(90 votes)

Top of Form Download WebAPIRc-noexe.zip - 1 MB Download WebAPIRc.zip - 2.8 MB

IntroductionIve spent last year working onASP.NETMVC3 and felling good this year onMVC4. I got some new exciting features after updating toMVC4, 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.PrerequisitesASP.NETMVC 4You 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.What isASP.NETWeb API?ASP.NETWeb API is a framework for building and consuming HTTP services that can reach a broad range of clients including browsers, phones and tablets. You can use XML or JSON or something else with your API. JSON is nice for mobile apps with slow 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 usingASP.NETWeb API. Many HTTP services also model CRUD operations through REST or REST-like APIs.

Why useASP.NETWeb API?ASP.NETWeb API is built for all the other, non-human interactions your site or service needs to support. Think about jQuery code that's making an Ajax request, or a service interface that supports a mobile client. In these cases, the requests are coming from code and expect some kind of structured data and specific HTTP Status Codes.These two are very complimentary, but different enough that trying to build out HTTP services usingASP.NETMVC took a lot of work to get right. The inclusion ofASP.NETWeb API inASP.NETMVC (and availability elsewhere, includingASP.NETWeb Pages) means that you can build top-notch HTTP services in anASP.NETMVC application, taking advantage of a common base and using the same underlying paradigms.ASP.NETWeb 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 conventions, so you no longer need to apply attributes such as [HttpPost] to your classes and methods. Content negotiation:The client and server can work together to determine the right format for data being returned from an API. We provide default support for XML, JSON, and Form URL-encoded formats, and you can extend this support by adding your own formatters, or even replace the default content negotiation strategy. Model binding and validation: Model binders provide an easy way to extract data from various parts of an HTTP request and convert those message parts into .NET objects which can be used by the Web API actions. Filters: Web APIs now supports filters, including well-known filters such as the [Authorize] attribute. You can author and plug in your own filters for actions, authorization and exception handling. Query composition: By simply returning IQueryable, your Web API will support querying via the OData URL conventions. Improved testability of HTTP details: Rather than setting HTTP details in static context objects, Web API actions can now work with instances of HttpRequestMessage and HttpResponseMessage. Generic versions of these objects also exist to let you work with your custom types in addition to the HTTP types. Improved Inversion of Control (IoC) via DependencyResolver: Web API now uses the service locator pattern implemented by MVCs dependency resolver to obtain instances for many different facilities. Code-based configuration: Web API configuration is accomplished solely through code, leaving your config files clean. Self-host: Web APIs can be hosted in your own process in addition to IIS while still using the full power of routes and other features of Web API.How To Create a New Web API ProjectStart Visual Studio 2010 and follow the steps:1. SelectNew Projectfrom theStart page/File menuthenNew Project.2. From the list of project templates: selectASP.NETMVC 4Web Application. Select your preferred location then type your desired project name and click OK.3. In theNewASP.NETMVC 4Project dialog, selectWeb API. The View engine will be Razor by default then clickOK.

Add a ModelA model is an object that represents the data in your application.ASP.NETWeb 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 theModelsfolder then selectAddthen selectClass.

Name the class "Book". Next, add the following properties to the Book class.Collapse|Copy Codepublic int Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }Add a RepositoryFor 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 theModelsfolder, named "BookRepository" which will implement theIBookRespositoryinterface derived fromIBookRepository:Following are the implementations:Collapse|Copy Codepublic interface IBookRepository{ IEnumerable GetAll(); Book Get(int id); Book Add(Book item); void Remove(int id); bool Update(Book item);}

Collapse|Copy Code public class BookRepository : IBookRepository { private BookStore db = new BookStore();

public BookRepository() { }

public IEnumerable GetAll() { return db.Books; }

public Book Get(int id) { return db.Books.Find(id); }

public Book Add(Book item) { db.Books.Add(item); db.SaveChanges(); return item; }

public void Remove(int id) { Book book = db.Books.Find(id); db.Books.Remove(book); db.SaveChanges(); }

public bool Update(Book item) { db.Entry(item).State = EntityState.Modified; db.SaveChanges(); return true; } }

The repository will keep books inlocal memory. We already mentioned and we can compromise for article purpose but in areal applicationplease don't do it. Because you need to store data either in adatabase or in cloud storage. Therepository patternwill make it easier to change the implementation later.Add a Web API ControllerIf you have worked withASP.NETMVC, then you are already familiar with controllers. InASP.NETWeb 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 traditionalASP.NETMVC controller. It is responsible for serving HTML pages for the site, and is not directly related to our Web API service.ValuesControlleris an example WebAPIcontroller.As we want to start from the scratch, go ahead and deleteValuesController.Do we need to mention how to delete? ...ok right-clicking the file in Solution Explorer and select Delete.Nowadda newcontroller, as follows:In Solution Explorer, right-click theControllersfolder. SelectAddand then selectController.In the Add Controller wizard, name the controller BooksController. In the Template drop-down list, select Empty API Controller. Then click Add.

TheAdd Controller wizardwill create a file namedBooksController.csin 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 anIBookRepositoryinstance.Collapse|Copy Codeusing WebAPI.Models;using System.Net; Collapse|Copy Codepublic class BooksController : ApiController{ static readonly IBookRepository _repository = new BookRepository();}Dependency Injection with IoC ContainersA dependency is an object or interface that another object requires. For example, in this article we defined a BooksController class that requires an IBookRepository instance.Above is the implementation looked like .This is not the best design, because the call to new theBookRepositoryis hard-coded into the controller class. Later, we might want to switch to another implementation ofIBookRespository, and then we would need to change the implementation ofBooksController. It is better if theBooksControlleris loosely decoupled from any concrete instance ofIBookRespoitory.Dependency injection addresses this problem. With dependency injection, an object is not responsible for creating its own dependencies. Instead, the code that creates the object injects the dependency, usually through a constructor parameter or a setter method.Here is a revised implementation ofBooksController:Collapse|Copy Codepublic class BooksController : ApiController{ static IBookRepository _repository; public BooksController(IBookRepository repository) { if (repository == null) { throw new ArgumentNullException("repository"); } _repository = repository; }}

AnIoCcontainer is a software component that is responsible for creating dependencies.IoC containers provide a general framework fordependency injection. If you use an IoC container, then you dont need to wire up objects directly in code. Several open-source .NET IoC containers are available. The following example usesUnity, anIoCcontainer developed byMicrosoft Patterns & Practices.In Solution Explorer, double-clickGlobal.asax. Visual Studio will open the file namedGlobal.asax.csfile, which is the code-behind file forGlobal.asax. This file contains code for handlingapplication-levelandsession-levelevents inASP.NET.Add a static method namedConfigureApito theWebApiApplicationclass.Add the followingusingstatements:Collapse|Copy Codeusing Microsoft.Practices.Unity;using WebAPI.Models;Add the following implementation:Collapse|Copy Code void ConfigureApi(HttpConfiguration config) { var unity = new UnityContainer(); unity.RegisterType(); unity.RegisterType( new HierarchicalLifetimeManager()); config.DependencyResolver = new IoCContainer(unity); }Now modify theApplication_Startmethod to callRegisterDependencies:Collapse|Copy Code protected void Application_Start() { AreaRegistration.RegisterAllAreas();

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); ConfigureApi(GlobalConfiguration.Configuration); Database.SetInitializer(new BookInitializer()); }Getting BookThe 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.NETWeb API framework automatically converts the ID to the correct data type (int) for the parameter.Notice thatGetBookthrows an exception of typeHttpResponseExceptionif id is not valid. This exception will be translated by the framework into a404 (Not Found)error.Collapse|Copy Codepublic IEnumerable GetAllBooks(){ return _repository.GetAll();} public Book GetBook(int id) { Book book = _repository.Get(id); if (book == null) { throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); } return book; }

Creating a BookTo create a new book, the client sends anHTTP POST request, with the new book in the body of the request message.Here is a simple implementation of the method:Collapse|Copy Codepublic Book PostBook(Book book){ book = _repository.Add(book); return book;}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 aredeserializedfrom the request body. Therefore, we expect the client to send us a serialized representation of a Book object, using eitherXML 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.NETWeb API makes it easy to manipulate the HTTP response message. Here is the improved implementation:Collapse|Copy Code public HttpResponseMessage PostBook(Book book) { book = _repository.Add(book); var response = Request.CreateResponse(HttpStatusCode.Created, book); string uri = Url.Route(null, new { id = book.Id }); response.Headers.Location = new Uri(Request.RequestUri, uri); return response; }

Notice that the method return type is nowHttpResponseMessage. TheHttpResponseMessageclass is a strongly typed representation of an HTTP response message. The generic parameter T gives theCLRtype that will be serialized to the message body. This was in the Beta version.You will get compilation errors. The new way to handle this is via the Request property in your controllers:You will need to change any return types from HttpResponseMessageto HttpResponseMessage.In the constructor, we specify the Book instance to serialize and theHTTP status codeto return:Collapse|Copy Codevar response = Request.CreateResponse(HttpStatusCode.Created, book);

Updating a BookUpdating a book with PUT is straightforward. Simply define a method whose name starts with "Put...":Collapse|Copy Codepublic void PutBook(int id, Book book){ book.Id = id; if (!_repository.Update(book)) { //throw new HttpResponseException(HttpStatusCode.NotFound);throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); }}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 isdeserializedfrom the request body. By default, theASP.NETWeb API framework takes simple parameter types from the route and complex types from the request body.Deleting a BookTo delete a book, define a "Delete..." method.Collapse|Copy Codepublic HttpResponseMessage DeleteBook(int id){ _repository.Remove(id); return new HttpResponseMessage(HttpStatusCode.NoContent);}According to the HTTP specification, the DELETE method must be idempotent, meaning that several DELETE requests to the same URI must have the same effect as a single DELETE request. Therefore, the method should not return an error code if the book was already deleted.If a DELETE request succeeds, it can returnstatus 200 (OK)with an entity-body that describes the status, orstatus 202 (Accepted)if the deletion is still pending, or status204 (No Content)with no entity body. In this example, the method returnsstatus 204.Using the HTTP Service with Javascript, jQuery and jQuery TemplateIn Solution Explorer, expand the Views folder, and expand the Home folder under that. You should see a file namedIndex.cshtml. Double-click this file to open it.Add the following code:Collapse|Copy Code

$(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; }); $("input[type=\"submit\"], .removeBook, .viewImage").button(); }); function find() { var id = $('#bookId').val(); $.getJSON("api/books/" + id, function(data) { var str = data.Name + ': $' + data.Price; $('#book').html(str); }) .fail( function(jqXHR, textStatus, err) { $('#book').html('Error: ' + err); }); }

The presentation of data on View looks like the following:

The above examples demonstrate Get all books, Add Book and Remove a Book from the list. The find function helps us to get abook by ID. For binding all the book list we usedjQuery templateover here. Following portion also needed for that:Collapse|Copy Code Book Name: ${ Name } Price:${ Price } Remove

And the HTML should look like the following:Collapse|Copy Code

Name Price Serach By ID

We have used jQuery template for making the right site book list. Please download source code for more detail.Points of Interest1. Full Support For Routes2. Model Binding3. Filters4. Content Negotiation5. Bundling by default6. oData style query support7. Razor Enhancements8. URL Resolution - Support for ~/ syntax9. Conditional attribute rendering10. NuGet Based Project Installationand many more...Bottom of FormCreating a custom user login form with .NET C# MVC 4 RazorByVygandas Pliasas,23 Oct 2012

4.30(10 votes)

Top of FormIntroductionMajority 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.Steps to reach the goalStep 1. Creating a project.In those screenshots I'm creatingMVC4project, 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.

Step 2. Creating a databaseRight click on App_Data -> Add -> New item... ->Data -> SQL Server Database -> OK.Now we need a users table.Right click on Tables and open New Query window.

Now paste code below to that query window and click execute (shortcut CTRL+SHIFT+E)Collapse|Copy CodeCREATE TABLE [dbo].[System_Users]([Id] INT NOT NULL IDENTITY ,[Username] NVARCHAR(50) NOT NULL,[Password] NVARCHAR(MAX) NOT NULL,[RegDate] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,[Email] NVARCHAR(50) NOT NULL,PRIMARY KEY ([Id]))GOCREATE INDEX [IX_System_Users_Username] ON [dbo].[System_Users] ([Username])GOINSERT INTO [dbo].[System_Users]([Username], [Password], [Email])VALUES('test', 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', '[email protected]')GOThis 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.Step 3. Creating a HomeControllerOK. Now we need a home controller which will be our first page.

Step 4. Creating a Home view.Right click on method name -> Create view.

Call it Index (The same as method name) and select to use layout.

Step 5. Creating a User modelUser model is required to handle user information and for form creation.Right click on Models -> Add -> New item... -> Code -> Class; Name itUser.cs.In User class code should look like this:Collapse|Copy Codeusing System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Data;using System.Data.SqlClient;using System.Linq;using 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; } /// /// Checks if user with given password exists in the database /// /// User name /// User password /// True if user exist and password is correct 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; } } } }}It could be necessary to modify a connection string on your computer.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")It can be found here:

NOTE: connection string must be placed in web.config!Step 6. Creating additional helpersAs you may notedHelpers.SHA1.Encode(_password);is underlined in red. It's because there's no such class and method yet.Now we are going to add additional shared project to our solution and create our Helper.In solution Explorer right click on Solution then Add -> New Project... -> Windows -> Class Library; Name itHelpers.In Solution Explorer right click on Helpers project and Add -> New item... -> Code -> Class; Name itSHA1.Code int his class must should look like this:Collapse|Copy Codeusing System;using System.Collections.Generic;using System.Linq;using System.Text;using 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("-", ""); } }}Now we need to reference it to our main project. Right click on our websiteprojectthen Add Reference... -> Select Helpers (checkbox) and hit OK.Step 7. Creating User ControllerWe need a user controller to manage user who's about to log in or log out. Create controller as you did previous and name it UserController. I preffer naming it User (not Users) becouse it stands for ONE user.This is code which should appear in it.Collapse|Copy Codeusing System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using 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"); } }}Step 8. Creating a login viewRight click on Login method name and create view.

Use layout template as previously.Step 9. Making login formCode should look like this:Collapse|Copy Code@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."); Login @Html.LabelFor(u => u.UserName) @Html.TextBoxFor(u => u.UserName) @Html.ValidationMessageFor(u => u.UserName) @Html.LabelFor(u => u.Password) @Html.PasswordFor(u => u.Password) @Html.ValidationMessageFor(u => u.Password) @Html.CheckBoxFor(u => u.RememberMe) @Html.LabelFor(u => u.RememberMe) }Here we create our form, add labels and validators.Step 10. Editing _Layout.cshtml page (add login button)This file is in Views -> Shared folder.We are going to add this code so it will allow us to login, log out and displays our name.Collapse|Copy Code

@if (Request.IsAuthenticated) { @Html.Encode(User.Identity.Name) @Html.ActionLink("Sign Out", "Logout", "User") } else { @Html.ActionLink("Register", "Register", "User") | @Html.ActionLink("Sign In", "Login", "User") } It checks (Request.IsAuthenticated) if user is logged in and then displays its name. Also it displays Register button, but in this article I'm not going further with it.The whole _Layout.cshtml code should look something like this:Collapse|Copy Code

@ViewBag.Title @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr")

@if (Request.IsAuthenticated) { @Html.Encode(User.Identity.Name) @Html.ActionLink("Sign Out", "Logout", "User") } else { @Html.ActionLink("Register", "Register", "User") | @Html.ActionLink("Sign In", "Login", "User") } @RenderBody() @Scripts.Render("~/bundles/jquery") @RenderSection("scripts", required: false)

Thats it!The source code can be downloaded here.ReviewSo 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.Bottom of Form