5 Tips for improving the ASP. NET MVC code base

Source: Internet
Author: User
Tags httpcontext knowledge base

MVC, recommendations

Just finished checking some of the code in the support ticket, I want to write some suggestions for the improvement of ASP. This content is still in the author's mind, is willing to share with you together. If you've been using MVC for a while, the following may not be new. This article is more suitable for readers who do not use MVC often or are not fully aware of MVC.

Consider the following scenario: you want to figure out why a Web application consumes 2GB of memory in a production environment, so you deploy the version of the application running in your production environment to run locally for analysis and debugging.

After looking at the code carefully, you can analyze it carefully, and maybe shake your head at times and finally figure out the nature of the problem, so you should give feedback.

This is the author's experience today, summed up 5 suggestions, hoping to make the reader in the use of ASP. NET MVC code is more handy.

1, understand the problem in the scope of inquiries

The root cause of the support ticket I receive is that a large amount of data is extracted from the database, resulting in excessive memory consumption.

This is a very common problem. If you set up a regular blog that contains articles and a variety of media (Pictures, videos, attachments). You put a Media array into the Post Field object, which stores all the picture data in a byte array. Because you are using ORM, you need to design a domain model in some way; we've all been through this.

public class Blogpost {public icollection<blogmedia> Media {get; set;}}  public class Blogmedia {public byte[] Data {get; set;} public string Name {get; set;}}


There is no big problem with this design, and you have built the domain model very accurately. The problem is that when you start a query with the most common ORM, all the data associated with the blog post is loaded.

Public ilist<blogpost> getnewestposts (int take) {return _db. Blogposts.orderbydescending (p = p.postdate). Take (take). ToList ();}

This line looks fine (unless you've been bothered by it, so it's not harmless to know about it), but it can have very serious consequences if you don't cancel lazy loading or let ORM ignore the large "data" attribute on the log media.

It is important to understand how an ORM is querying and mapping objects, and to ensure that the content being queried is what is needed (such as using projection).

Public ilist<postsummary> getnewestposts (int take) {return _db. Blogposts.orderbydescending (p = p.postdate). Take (take). Select (p = = new Postsummary () {Title = P.title, Id = p.id}). ToList ();}

This ensures that only the amount of data that the task really needs is captured. If all you have to do is create a link on the homepage using the title and ID, then it's enough to get these two attributes .

You can prepare more than 5 methods in the knowledge base to make the user interface more complete and not too careful.

2. Do not invoke the knowledge base from the view

This one is more difficult to note. Imagine the following code in the MVC view:

@foreach (Var post in model.relatedposts) {...}

It doesn't seem to be a problem, but if you look closely at what's implied in this model attribute?

public class Myviewmodel {public ilist<blogpost> relatedposts {get {return new Blogrepository (). Getrelatedposts (this. Tags); }  }}

Yes! The view model contains business logic, and a data access method is also called directly. As a result, data access code is introduced into unfamiliar areas and hidden in attributes. Moving this code to the controller makes it easy to discuss and intentionally add content to the view model.

Here's a good indication that proper unit testing can help identify such problems, and because it's certainly not possible to intercept calls to such a method, you might suddenly realize that you shouldn't inject the knowledge base into the view model.

3. Make full use of local modules and sub-actions

If you want to execute business logic in a view, you should reconsider the view model and logic. It is not recommended to perform such operations in the MVC Razor view.

@{var blogcontroller = new BlogController ();} <ul> @foreach (var tag in blogcontroller.gettagsforpost (p.id)) {<li> @tag. Name</li>}</ul>

Never use business logic in a view, but in addition, you can create a controller ! Move the business logic into an action method and use the view model for its intended purpose. You can also move the business logic into a separate action method, which is called only within the view, so that it can be cached separately if necessary.

In the Controller:[childactiononly][outputcache (duration=2000)]public actionresult tagsforpost (int postId) {return View ();} In the View:@{html.renderaction ("Tagsforpost", new {PostID = p.id});}

Note the "childactiononly" property. As mentioned in MSDN:

Any method marked with "childactiononlyattribute" can only be called with the "action" or "renderaction"html extension method.

This means that no one can access your child actions by manipulating the URL (if you take the default path).

In the MVC library, local modules and sub-actions are useful tools, so make the most of them!

4. Cache Important Things

With the above code to pave the way, if you only cache the view model, what will be the effect?

Public ActionResult Index () {var Homepageviewmodel = httpcontext.current.cache["Homepagemodel"] as Homepageviewmodel;      if (Homepageviewmodel = = null) {Homepageviewmodel = new Homepageviewmodel ();      Homepageviewmodel.recentposts = _blogrepository.getnewestposts (5);  HTTPCONTEXT.CURRENT.CACHE.ADD ("Homepagemodel", Homepageviewmodel, ...); } return View (Homepageviewmodel);}

What effect does not have! It is not possible to improve performance by entering the data layer through the controller variables in the view and the properties in the view model ... Caching the view model is not useful.

Try caching the output of the MVC action:

[OutputCache (duration=2000)]public ActionResult Index () {var homepageviewmodel = new Homepageviewmodel ();  Homepageviewmodel.recentposts = _blogrepository.getnewestposts (5); Return View (Homepageviewmodel);}

Please note that the "outputcache" property is very useful. MVC supports ASP. NET output caching, so make the most of this feature, where appropriate. To cache the model, the model should basically be POCO with automatic (and read-only) attributes, and cannot invoke other knowledge base methods.

Also, I'd like to introduce a good way that I haven't tried, that is, to use a different output cache vendor to cache in AppFabric, NoSQL, or wherever else is needed. MVC has a very strong extensibility.

5. Use ORM boldly

If you don't take advantage of the ORM feature set, it's a huge loss. I have used NHibernate in the code base that I checked, but I didn't really use it well. The NHibernate advanced projective functionality that could be used to solve some of the memory problems is completely ignored. This problem is sometimes caused by the use of rigid thinking created by the "library model" and sometimes by the lack of necessary knowledge.

The functionality of the knowledge base can be significantly increased by leveraging EF or NHibernate features compared to using only basic class methods. They can form and return the data you really want in the controller, greatly enhancing the logic of the controller. Read the ORM file and learn about the features it can offer, which will benefit you a lot.

The author believes that the use of the Knowledge base model, like the elimination of fog and haze, so that the bright sunlight from the ORM window to shine in. When I first contacted RavenDB, I discarded the Knowledge Base layer (which is actually the whole data Project ), used the Raven query completely in the Application service layer, and used a little extension method to reuse the query logic. The author finds that many logic is obviously dependent on the specific context, and it is of great benefit to cast, form and process the query in batches using the extended characteristics of Raven.

It's just your opinion ...

If you think you can abstract the ORM, I strongly suggest you think in a different way. ORM is really an abstract concept, and if you think that because the ORM is "abstract", it is easy to replace the existing ORM with another ORM, then the facts will surprise you. That's what I thought before, until I learned that converting to Raven simply changed my entire codebase, which I didn't expect at all. ORM not only affects data access, it also affects domain and business logic, and even affects the user interface. By removing the Knowledge base abstraction, you can effectively reduce the overall complexity of the data access code .

"Common sense is not known."

My father used to remind me of this sentence. Sometimes, by looking at the code carefully, you will find the truth that you think everyone knows, and that is not true; You may have learned this from practical experience, or read it on Google, and mistakenly assume that this is a fact that is known to all.

I hope this article can help the people who need it!

OneAPM helps you easily lock in. NET application performance bottlenecks, with powerful Trace records to layer through analysis until the line-level problem code is locked. Displays the system response speed at the user's point of view, and counts user usage in geographic and browser dimensions. To read more technical articles, please visit the OneAPM official blog.

This article was transferred from OneAPM official blog

Original address: http://kamranicus.com/blog/2014/01/29/5-tips-to-improve-your-mvc-site/


5 Tips for improving the ASP. NET MVC code base

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.