ASP. net mvc Case Study (6) (1)

Source: Internet
Author: User

A small problem

We continue to improve the "MVC announcement publishing system". This time, we need to add logging capabilities to the announcement publishing function, that is, to record the announcement once before it is released. After the announcement is published successfully, record it again. Then, you need to handle exceptions. That is, when a service component encounters a problem, the system jumps to the corresponding error page and displays the corresponding prompt.

Some people may have laughed. What is the problem? The corresponding log function was added to the beginning and end of the DoRelease Action soon. For Exception Handling, try... catch directly.

Yes, the above method works, but there are two problems:

1. duplicate code. A lot of log processing code is very similar to the Exception Processing code, which leads to a lot of repeated code in each Action.

2. Responsibility is damaged. Don't forget that our Controller is just a Controller. It should only represent the logic, and should not be surrounded by a lot of log processing code and try... catch blocks. The Action we need should be clean, neat, and contain only actions that represent logic.

The above two points cause bad code in our system. So how can we solve this problem?

From chef to AOP

Imagine a scenario: How do senior chefs work in a restaurant? We know that he doesn't need to wash vegetables, cut vegetables, or serve dishes with dishes. If he finds that the beef in his hand has deteriorated, he doesn't need to take the beef to the butcher's theory. His job is very simple: cooking.

After the raw materials are sent, a special food slicer will wash and cut the food, and then send the processed food to the cook. The cook will just fry the food in the pan. Naturally, you do not have to worry about the food after it is fried, because there are dedicated waiters responsible for this. If it finds that the beef has deteriorated, it just needs to say that there will naturally be people who will handle it.

This scenario is typical AOP for Aspect-Oriented Programming ). A cook can be regarded as a business component. One method is "Cooking". However, before cooking, you have to cut the food and someone else needs to deliver the food. This is not a concern of the cook! As a result, our cut-off workers and waiters are equivalent to interceptions. The cut-off workers intercept and cut the dishes before cooking. The cut-off workers intercept the dishes after cooking and are responsible for delivering the dishes. Of course, we also have an exception Interceptor: the person who handles the problem is the one who will handle the problem when the cook finds that the meat has deteriorated and shouted.

Based on this scenario, let's take a look at the benefits. First, the cook has a single responsibility. He can focus on his own job: cooking without worrying about the issues he is not concerned about. In addition, "interceptors" can be reused. For example, a stingy boss can find three chefs, but only recruit one waiter. In this way, a waiter can serve three chefs, the reuse of the interceptor makes the code repeated disappear!

Back

Now, let's go back to our "MVC announcement publishing system ". I believe that after reading the above scenario, your inspiration must come: Right, isn't Action a chef? If we can make the log function an interceptor, the log recording function is intercepted once before DoRelease is executed, and the logging function is intercepted once after DoRelease is executed. It is better to have an interceptor. When an Action exception occurs, it can intercept and handle it like the person who handled the bad beef above.) Isn't it done.

But how can we intercept an Action? Fortunately, this mechanism is built into the ASP. net mvc framework! Haha, let's do it now!

Implement interceptor

ASP. net mvc has three interceptors: Action interceptor, Result interceptor, and Exception interceptor. I want to use the first and third types. In fact, the so-called ASP. net mvc interceptor is nothing mysterious, just a common class. Only the FilterAttribute base class must be inherited. The Action interceptor must implement the IActionFilter interface, while the Exception interceptor must implement the IExceptionFilter interface.

Let's first look at the implementation: Let's create a new Filters directory under the Controllers directory, and then create two classes under Filters, one is LoggerFilter and the other is predictionfilter. The first is the LoggerFilter code.

LoggerFilter. cs:

Using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Web;
Using System. Web. Mvc;
Using System. Web. Mvc. Ajax;

Namespace MVCDemo. Controllers. Filters
{
Public class LoggerFilter: FilterAttribute, IActionFilter
{
Void IActionFilter. OnActionExecuting (ActionExecutingContext filterContext)
{
FilterContext. Controller. ViewData ["ExecutingLogger"] = "you are about to add an announcement. The announcement has been written to the log! Time: "+ DateTime. Now;
}
Void IActionFilter. OnActionExecuted (ActionExecutedContext filterContext)
{
FilterContext. Controller. ViewData ["ExecutedLogger"] = "The announcement has been added and logs have been written! Time: "+ DateTime. Now;
}
}
}

As you can see, this class inherits FilterAttribute and implements IActionFilter. The key is IActionFilter, which has two methods: OnActionExecuting is executed before the intercepted Action, and OnActionExecuted is executed after the intercepted Action. Both methods have a parameter, which has different types, but is actually a role: Context of the intercepted Action.

In this case, I have to explain that your interceptor intercepts the Action and will inevitably use the Action-related content during processing. For example, in our example, you need to add content to the ViewData of the Controller where the intercepted Action is located. Therefore, the interceptor method has a parameter that indicates that the context of the intercepted Action is a logical task.

Next, let's look at the ExceptionFilter interceptor, which plays a role when an Action exception occurs.

Predictionfilter. c:

  using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MVCDemo.Controllers.Filters
{
public class ExceptionFilter : FilterAttribute,IExceptionFilter
{
void IExceptionFilter.OnException(ExceptionContext filterContext)
{
filterContext.Controller.ViewData["ErrorMessage"] = filterContext.Exception.Message;
filterContext.Result = new ViewResult()
{
ViewName = "Error",
ViewData = filterContext.Controller.ViewData,
};
filterContext.ExceptionHandled = true;
}
}
}

The exception interceptor also needs to inherit FilterAttribute, but does not implement IActionFilter. Instead, it needs to implement the IExceptionFilter interface. This interface has only one method: OnException, which is called when an exception occurs. Let's take a look at what I made it do: first, the Exception information ExceptionContext is the same as the context, and its member Exception is an Exception type instance, that is, the thrown Exception) record it to the corresponding key value of ViewData, and then we will display the Error view.

Note! This is not a Controller, but another class, so you cannot call the View method to return the ViewResult instance. We had to create a new ViewResult instance and set its view name to Error. We passed the DataView in the context.

The last line of filterContext. effecitonhandled = true; is very important. This line tells the system that the exception has been handled and should not be processed again.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.