This article will introduce the usage of the official ASP. net mvc 2 Framework, including caching and static content placement. I hope this article will help you.
1st day of this month in the use of ASP. net mvc 2 http://www.86e0.com/t this site, when using aps.net MVC2 RC2, And now ASP. net mvc 2 official version has been released. I have some experiences in using MVC. The following is a summary. I hope it will be useful to you and you are welcome to discuss it.
1. About Cache
The cache on the data layer is required.
Another important thing is view fragment caching.
I have read three articles about fragment caching written by Lao Zhao:
Suitable for ASP. net mvc view fragment caching ):
Suitable for ASP. net mvc view fragment caching): more practical API
Suitable for ASP. net mvc view fragment caching): Page Output Principle
I wanted to use Lao Zhao, But I found ASP. net mvc 2 has a new function: Html. partial can return the generated HTML. The returned type is MvcHtmlString. although you need to use Partial View to generate Html fragments, I think this is enough for me to use, so I made such a Helper, it mainly caches the generated HTML fragments into Memcached. The Code is as follows:
- public static class MvcHtmlHelper
- {
- public static MvcHtmlString MemcacheHtmlPartial(this HtmlHelper htmlHelper,int duration, string partialViewName, object model, ViewDataDictionary viewData)
- {
- object obaear = htmlHelper.ViewContext.RouteData.DataTokens["area"];
- string area=string.Empty;
- if (obaear != null) area = obaear.ToString();
- string key = string.Format("MemcacheHtmlPartial_{0}{1}", area, partialViewName);
- object ob = DistCache.Get(key);
- if (ob == null)
- {
- MvcHtmlString mstr = htmlHelper.Partial(partialViewName, model, viewData);
- DistCache.Add(key, mstr.ToString(), TimeSpan.FromSeconds(duration));
- return mstr;
- }
- else
- {
- return MvcHtmlString.Create((string)ob);
- }
- }
- }
Then, I think, in this way, we still need to extract the data in the Controller each request and then upload it to the Partial View. Now that the data has been cached, you do not need to retrieve the data in the Controller for every request! Although the data layer has a cache.
So can I save the consumption of Controller data? The following code caches the HTML generated by Action into Memcached.
- public static MvcHtmlString MemcacheHtmlRenderAction(this HtmlHelper htmlHelper,
- int duration, string actionName,string controllerName, RouteValueDictionary routeValues)
- {
- object obaear = htmlHelper.ViewContext.RouteData.DataTokens["area"];
- string area = string.Empty;
- if (obaear != null) area = obaear.ToString();
- string key = string.Format("MemcacheHtmlRenderAction_{0}{1}{2}", area, controllerName,actionName);
- object ob = DistCache.Get(key);
- if (ob == null)
- {
- // htmlHelper.RenderAction(actionName, controllerName, routeValues);
- StringWriter writer = new StringWriter(CultureInfo.CurrentCulture);
- ActionHelper(htmlHelper, actionName, controllerName, routeValues, writer);
- string wStr = writer.ToString();
- DistCache.Add(key, wStr,TimeSpan.FromSeconds(duration));
- MvcHtmlString mstr = MvcHtmlString.Create(wStr);
- return mstr;
- }
- else { return MvcHtmlString.Create((string)ob); }
- }
The Actionhelper method is extracted from the original MVC code. Because the Html. RenderAction method in MVC2 does not return the overloaded version of MvcHtmlString. Is there a better way?
In fact, the Action in MVC has an output cache, so using Html. RenderAction in View can solve many problems. You can use programs to manage the cache.
2. Placement of static content
Traditionally, static content is stored in the directory where the mvc program is located, such as js, css, and uploaded images. In this case, all static requests must be processed by aspnet_isapi, which is very uneconomical. Therefore, static content is usually stored in another subdomain. The http://www.86e0.com/t is placed on cdn.86e0.com.
3. About strong ViewModel
I basically read Lao Zhao's best practices of Asp.net MVC. One of them is that we strongly recommend using a strong ViewModel. I tried some pages and found that using a strong ViewModel does not apply to me at this stage. Because I use NbearLite, most of the data captured from the database is DataTable. I think DataTable + NbearLite is quite convenient. Although there is no Dynamic Language for data access, it can save a lot of code than Entity, ViewModel, DTO, and so on. Then, the most important thing is that because I often modify such sites, it is quite frequent to change the database, add fields, and subtract fields. However, it is very convenient to use NbearLite + DataSet and DataTable.
So I think Asp.net MVC can be used if you don't use DDD or DDT. Because of DDD, it is still important to learn about DDT.
4. URL generation
Old Zhao wrote a series of articles about URL generation:
Performance Comparison of various URL generation methods
Performance Comparison and Analysis of various URL generation methods)
Generate a Fluent Interface for the URL)
URL generation method performance optimization results
Select directly
Raw method, the fastest speed, is suitable for me. Oh. Rather than the strong type, it is suitable for me.
Finally, share a useful Asp.net MVC pagination Helper.
This Helper cited from the classic boss's blog: http://www.cnblogs.com/chsword/. I made a few changes before, now has been used on the http://www.86e0.com/t.
The effect is as follows:
Please note that the generated URL is used? Parameter = page number. The Code is as follows:
- /// <Summary>
- /// Pager display
- /// </Summary>
- /// <Param name = "html"> </param>
- /// <Param name = "currentPageStr"> QueryStringKey that identifies the current page number </param>
- /// <Param name = "pageSize"> display on each page </param>
- /// <Param name = "totalCount"> total data volume </param>
- /// <Returns> </returns>
- Public static string Pager (this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)
- {
- Var queryString = html. ViewContext. HttpContext. Request. QueryString;
- Int currentPage = 1; // current page
- If (! Int. TryParse (queryString [currentPageStr], out currentPage) currentPage = 1; // bind with the corresponding QueryString
- Var totalPages = Math. Max (totalCount + pageSize-1)/pageSize, 1); // total number of pages
- Var dict = new RouteValueDictionary (html. ViewContext. RouteData. Values );
- Var output = new StringBuilder ();
- Foreach (string key in queryString. Keys)
- If (queryString [key]! = Null &&! String. IsNullOrEmpty (key ))
- Dict [key] = queryString [key];
- If (totalPages> 1)
- {
- If (currentPage! = 1)
- {// Process the homepage connection
- Dict [currentPageStr] = 1;
- Output. AppendFormat ("<span class = \" p_home \ "> {0} </span>", html. RouteLink ("Homepage", dict ));
- }
- If (currentPage> 1)
- {// Process the connection of the previous page
- Dict [currentPageStr] = currentPage-1;
- Output. AppendFormat ("<span class = \" p_up \ "> {0} </span>", html. RouteLink ("Previous Page", dict ));
- }
- Else
- {
- Output. AppendFormat ("<span class = \" p_disable \ "> {0} </span>", "Previous Page ");
- }
- Int currint = 5;
- For (int I = 0; I <= 10; I ++)
- {// A total of 10 page numbers can be displayed, including the first 5 and the last 5
- If (currentPage + I-currint)> = 1 & (currentPage + I-currint) <= totalPages)
- If (currint = I)
- {// Process the current page
- Output. Append (string. Format ("<span class = \" p_current \ ">{0} </span>", currentPage ));
- }
- Else
- {// General page processing
- Dict [currentPageStr] = currentPage + I-currint;
- Output. appendFormat ("<span class = \" p_num \ "> {0} </span>", html. routeLink (currentPage + I-currint ). toString (), dict ));
- }
- }
- If (currentPage <totalPages)
- {// Process the next page
- Dict [currentPageStr] = currentPage + 1;
- Output. AppendFormat ("<span class = \" p_down \ "> {0} </span>", html. RouteLink ("next page", dict ));
- }
- Else
- {
- Output. AppendFormat ("<span class = \" p_disable \ "> {0} </span>", "Next page ");
- }
- If (currentPage! = TotalPages)
- {
- Dict [currentPageStr] = totalPages;
- Output. AppendFormat ("<span class = \" p_last \ "> {0} </span>", html. RouteLink ("last page", dict ));
- }
- }
- Output. appendFormat ("<span class = \" p_count \ "> page {0}/total {1} </span>", currentPage, totalPages ); // This statistics can be added without adding
- Return output. ToString ();
- }
ASP. net mvc extension reading
ASP. net mvc is a framework for compiling ASP. NET Web applications in the MVC mode officially provided by Microsoft.
It comes from Castle's MonoRail. It has already gone through several versions. MVC in ASP. net mvc originally exists in the Desktop program, M is the exponential data model, V is the user interface, and C is the controller. The purpose of using MVC is to separate the implementation code of M and V, so that the same program can use different expressions. For example, you can use a column chart or pie chart to represent a batch of statistical data. The purpose of C is to ensure synchronization between M and V. Once M changes, V should be updated synchronously.
The ASP. net mvc framework is another development method after ASP. NET WebForms. It provides a series of excellent features that enable ASP. NET developers to have another choice. ASP. net mvc Framework Options are very clean and easy to use. It will allow you to easily keep focus on separation in applications and help with clean testing and TDD.
Original article title: Asp.net MVC2 experience and performance optimization suggestions
Link: http://www.cnblogs.com/OtisBlog/archive/2010/03/22/1691676.html