|
|
Want to know more about Packt's Article Network? Interested in contributing your article ideas? Please visit our FAQ for more information. See More BROWSE
All Titles WordPress Web Services SOA BPEL Web Graphics & Video Web Development RAW Portugues, Espanol, Italiano, French PHP/MySQL Oracle Open Source Networking & Telephony Moodle Microsoft & .NET Linux Servers jQuery Joomla! JBoss Java e-Learning e-Commerce Dynamics Drupal CRM Cookbook Content Management Beginner Guides Architecture and Analysis AJAX Future Titles Recently Published Titles Ever since Microsoft started working on the ASP.NET MVC framework, one of the primary concerns was the framework's ability to re-use as many features as possible from ASP.NET Webforms. In this article by Maarten Balliauw, we will see how we can mix ASP.NET Webforms and ASP.NET MVC in one application and how data is shared between both these technologies. See More |
Customizing and Extending the ASP.NET MVC Framework
Creating a controlWhen building applications, you probably also build controls. Controls are re-usable components that contain functionality that can be re-used in different locations. In ASP.NET Webforms, a control is much like an ASP.NET web page. You can add existing web server controls and markup to a custom control and define properties and methods for it. When, for example, a button on the control is clicked, the page is posted back to the server that performs the actions required by the control. The ASP.NET MVC framework does not support ViewState and postbacks, and therefore, cannot handle events that occur in the control. In ASP.NET MVC, controls are mainly re-usable portions of a view, called partial views, which can be used to display static HTML and generated content, based on ViewData received from a controller. In this topic, we will create a control to display employee details. We will start by creating a new ASP.NET MVC application using File | New | Project... in Visual Studio, and selecting ASP.NET MVC Application under Visual C# - Web. First of all, we will create a new Employee class inside the Models folder. The code for this Employee class is: public class Employee On the home page of our web application, we will list all of our employees. In order to do this, modify the Index action method of the HomeController to pass a list of employees to the view in the ViewData dictionary. Here's an example that creates a list of two employees and passes it to the view: public ActionResult Index() The corresponding view, Index.aspx in the Views | Home folder of our ASP.NET MVC application, should be modified to accept a List<Employee> as a model. To do this, edit the code behind the Index.aspx.cs file and modify its contents as follows: using System.Collections.Generic; In the Index.aspx view, we can now use this list of employees. Because we will display details of more than one employee somewhere else in our ASP.NET MVC web application, let's make this a partial view. Right-click the Views | Shared folder, click on Add | New Item... and select the MVC View User Control item template under Visual C# | Web | MVC. Name the partial view, DisplayEmployee.ascx.
The ASP.NET MVC framework provides the flexibility to use a strong-typed version of the ViewUserControl class, just as the ViewPage class does. The key difference between ViewUserControl and ViewUserControl<T>is that with the latter, the type of view data is explicitly passed in, whereas the non-generic version will contain only a dictionary of objects. Because the DisplayEmployee.aspx partial view will be used to render items of the type Employee, we can modify the DisplayEmployee. ascx code behind the file DisplayEmployee.ascx.cs and make it strong-typed: using ControlExample.Models; In the view markup of our partial view, the model can now be easily referenced. Just as with a regular ViewPage, the ViewUserControl will have a ViewData property containing a Model property of the type Employee. Add the following code to DisplayEmployee.ascx: <%@ Control Language="C#" AutoEventWireup="true" The control can now be used on any view or control in the application. In the Views | Home | Index.aspx view, use the Model property (which is a List<Employee>) and render the control that we have just created for each employee: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site. In case the control's ViewData type is equal to the view page's ViewData type, another method of rendering can also be used. This method is similar to ASP.NET Webforms controls, and allows you to specify a control as a tag. Optionally, a ViewDataKey can be specified. The control will then fetch its data from the ViewData dictionary entry having this key. <uc1:EmployeeDetails ID="EmployeeDetails1" For example, if the ViewData contains a key emp that is filled with an Employee instance, the user control could be rendered using the following markup: <uc1:EmployeeDetails ID="EmployeeDetails1" After running the ASP.NET MVC web application, the result will appear as shown in the following screenshot:
ASP.NET MVC 1.0 Quickly
Creating a filter attributeAn action filter is an attribute that can be applied to a controller class or an action method. Whenever the controller or action method is called, the action filter will be triggered both before and after the execution. Typically, action filters are used for solving problems that can occur in more than one class—the so called cross-cutting concerns. A typical cross-cutting concern is output caching or authentication—both can be required for more than one action method. One cross-cutting concern of an action method might be logging. For example, one wants to log when an action was called, and whether its result was executed, in a log file as shown here: [2008-09-02 - 03:03:13] Controller: Home; Action: Index; Action To achieve this, a filter attribute can be created by implementing the IActionFilter and IResultFilter interfaces, and optionally overloading the FilterAttribute class. An action filter allows you to run code before and after an action method is called, but before the result of the action method is executed. A result filter is very similar to an action filter except that it is executed before and after the result is returned from the action that has been executed. The IActionFilter interface defines two methods:
The IResultFilter interface defines two methods:
Let's create a class called LoggingAttribute which implements these two interfaces, and will run whenever an action is executing or an action result is executing. First of all, let's define the class and apply the AttributeUsage attribute to it. This attribute tells the compiler that the LoggingAttribute we are creating can only be applied to classes and methods. The LoggingAttribute class implements IActionFilter and IResultFilter. We also add a property named LogName, which will hold the path to our log file. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Because we will be logging some things, let's also add a method that writes a log message to the file referenced by the LogName property. This method will simply open the file, append a new line to it, and close it again. private void LogMessage(string controller, string action, string Now, it is time to implement the IActionFilter and IResultFilter interfaces. For the IActionFilter, we'll add the OnActionExecuting and OnActionExecuted methods. For IResultFilter, we'll add the OnResultExecuting and OnResultExecuted methods. All of these methods will use the LogMessage method that we've just created and pass in some information for logging to the file. public void OnActionExecuting(ActionExecutingContext filterContext) The source of information that is being logged originates in the parameter passed to the On... methods. This is always an object containing information about the current execution context, such as the controller that is executing, the view that is being rendered, and HTTP request data. Here's the full LoggingAttribute class that we have been creating: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, The filter can now be applied to any controller, which in turn will apply the filter to all of the action methods, or to individual action methods: [Logging(LogName = "C:tempApplicationLog.log")] Now, when the SomeAction action method of the HomeController is called, a log entry will be created when the view is being rendered. Creating a custom ActionResultThe ASP.NET MVC framework's action method implements the concept of returning an ActionResult instance, which will typically render a specific view, or redirect the user to a different location on the web site. An ActionResult that renders a view is returned as a RenderViewResult . The ExecuteResult() method is called in order to render specific contents to the HTTP response stream. An ActionResult can take any form as long as it has something to do with the HTTP response stream. For example, you can create a FileDownloadResult that streams a file on the HTTP response stream, or a PermanentRedirectResult that renders HTTP status code 302. One of the problems that many web designers face is the fact that a user's web browser may or may not have the specific fonts needed to display the contents. This may be a problem, say, if the web designer wants to style a title element in some exotic font face. Because the ASP.NET MVC framework has a modular architecture, a custom ActionResult class can easily be created to achieve this goal. This custom ActionResult will render a JPEG image based on input text, which can be used to display a page title. This ActionResult class will be named ImageResult.
The new ImageResult class will inherit the abstract class ActionResult and implement its ExecuteResult method. This method basically performs communication over the HTTP response stream. It accepts an Image object as a property as well as an ImageFormat. This means that a custom image can easily be rendered to the HTTP response stream, whether as JPEG, BMP, PNG, or GIF. using System; The ImageResult class defines two properties: Image and ImageFormat. These properties can be set in the ImageResult constructor . When the ImageResult is executed in the ExecuteResult method , the in-memory image is rendered to the HTTP response stream in the specified image format. using System.Drawing; The ShowTitle action method creates a new in-memory bitmap and renders a text and text shadow on a white background. This bitmap is then passed into a new ImageResult instance, which will render the image to the HTTP response stream. As an extra feature, this image-rendered page title can be added to the web page in an easy manner. <%=Html.PageTitle("Welcome to ASP.NET MVC!", 400, 40)%>This HtmlHelper extension method will render an HTML image tag such as <img src="/PageTitle/ShowTitle?pageTitle=Welcome to ASP.NET MVC!&width=400&height=40" width="400" height="40" alt="Welcome to ASP.NET MVC!" />. It is implemented as follows: using System.Web.Mvc; We have used a new namespace here (Microsoft.Web.Mvc) to make use of the LinkBuilder class. This namespace contains several classes that may be included in the ASP.NET MVC framework in future, but are currently not considered to be stable by the ASP.NET MVC development team. The MVC features can be downloaded from the official CodePlex site at http://www.codeplex.com/aspnet If all of the classes are in place, we can now add an image-based title in our view in an easy, intuitive manner. The following code will replace the default home page by an enhanced version using our newly-created ImageResult. The HtmlHelper class now has a new method, PageTitle, which we can use to create a title image of a specified width and height. <asp:Content ID="indexContent" After running the application, the index page will look like the screenshot presented earlier in this article. SummaryIn this article, we learned how to extend the ASP.NET MVC framework. We created a control, which is also called a partial view. We learned more about filter attributes, and also created one of our own. Finally, we looked at how to create a custom ActionResult, which displays an image containing text based on a controller's action method. If you have read this article you may be interested to view : ASP.NET MVC 1.0 Quickly
About the AuthorMaarten Balliauw has a Bachelor's Degree in Software Engineering and has about eight years of experience in software development. He started his career during his studies where he founded a company that did web development in PHP and ASP.NET. After graduation, he sold his shares and joined one of the largest ICT companies in Belgium, RealDolmen, where he continued web application development in ASP.NET and application life cycle management in Visual Studio Team System. He is a Microsoft Certifi ed Technology Specialist in ASP.NET and works with the latest Microsoft technologies such as LINQ and ASP.NET 3.5. He has published many articles in both .NET and PHP literature, such as MSDN magazine Belgium, and PHP Architect. Ever since the fi rst announcement of the ASP.NET MVC framework, he has been following all its developments and features. He can be contacted on his blog-http://blog.maartenballiauw.be or by email at maarten@maartenballiauw.be. Books from Packt |
When downloading and installing the ASP.NET MVC framework SDK, a new project template is installed in Visual Studio—the ASP.NET MVC project template. This article by Maarten Balliauw describes how to use this template. We will briefly touch all aspects of ASP.NET MVC by creating a new ASP.NET MVC web application based on this Visual Studio template. Besides view, controller, and model, new concepts including ViewData—a means of transferring data between controller and view, routing—the link between a web browser URL and a specific action method inside a controller, and unit testing of a controller are also illustrated in this article. See More |
| ||||||||