(MVC) MVC (2015 год)

Кешування вхідної сторінки сайту за допомогою System.Web.Mvc.ViewEngines.



На багатьох ресурсах вхідна сторінка занадто важка, формування підсумкового HTML, який видається в браузер потребує 30 секунд і більше. Зрозуміло, что чекати такий довгий час ніхто не буде і користувач просто закриє сайт. Цей ефект ще більше, якщо сайт досить нагружений. Наприклад http://www.votpusk.ru/ мав до падіння оборотів в туристичної індустрії до 33 мільонів відвідувачів на місяць - Rating.mail.ru зрозуміло, що кожного разу формувати тисячі разів на секунду одну і ту ж сторінку ніяк неможливо з точки зору можливостей серверів, та й не має ніякого сенсу, бо вхідна сторінка змінюється досить рідко.

Тому на цієї сторінці я опишу досить хитру технологію кешування вхідної сторінки сайту на ASP.NET.MVC. Могутні класи System.Web.Mvc.ViewEngines.Engines не досить часто використовують починаючі програмісти, тому, сподіваюсь, ця сторінка буде дуже цікавою для них.

По-перше, для напруженого сайту з важкої вхідної сторінкою потрібно зробити окремий вхід, через який буде робитися кеш. Я назвав його CreateCache. Тобто я зробив маркер у каталозі View і далі весь цей код буде викликатися зовні як /Home/CreateCache





Підсумок виклику /Home/CreateCache буде подвійний - по-перше сторінка головна вхідна сторінка сайту з ім'ям Cache.html, яка буде сформована у каталозі сайту, а подруге ця ж сторінка, яка звичайно видається як результат виклику /Home/Index буде видана як результат виклику /Home/CreateCache.

Далі повне налаштування цього метода кешування потребує ще дві речі:

Все вищесказане стосується лише зовнішнього оточення беспосередьньо коду кешування. А тепер подивимося безпосередньо на код кешування. У коді контролеру я розмістив лише звернення до оточення головного классу System.Web.Mvc.ViewEngines.Engines, який безпосередньо поєднує VIEW и DATA, щоб зробити підсумковий HTML:





А ось, нарешті і сам сам механізм вштовхування даних у View (зверніть увагу, що цей класс зроблений на Дженеріках, тобто тип класа Model при компіляції невідомий). Вштовхування робиться у 51-й стрічці, все інше лише підготовка до цього. Результат заштовхування - у 53-й стрічці.



   1:  Public Class MVC_Engine
   2:   
   3:   
   4:      'Dim MVC As New MVC_Engine
   5:      'Dim ResultHTML1 As String = Mvc.GetHTML("Home", "Index", "M1", New With {.model = Nothing}, Me, HttpContext)
   6:      'Response.ContentType = "text/html"
   7:      'Response.Write(ResultHTML1)
   8:   
   9:   
  10:      Function GetHTML(Of T)(ControllerName As String, ActionName As String, MasterPageName As String, Model As T, ControllerClass As System.Web.Mvc.ControllerBase, HttpContext As System.Web.HttpContextBase) As String
  11:          'System.Web.Mvc.ControllerContext - контекст исполнения контроллера
  12:          Dim Controller_Context As New System.Web.Mvc.ControllerContext()
  13:          Controller_Context.Controller = ControllerClass
  14:          Controller_Context.HttpContext = HttpContext
  15:          Controller_Context.RouteData = New RouteData()
  16:          Controller_Context.RouteData.Values.Add("controller", ControllerName)
  17:          Controller_Context.RouteData.Values.Add("action", ActionName)
  18:          Dim ViewEngineResult As System.Web.Mvc.ViewEngineResult
  19:          Dim ViewEngineError As String = ""
  20:          Try
  21:   
  22:              'ViewEngines.Engines - движок поиска нужной вьюхи
  23:              'ViewEngineResult.SearchedLocations - Gets or sets the searched locations.
  24:              'ViewEngineResult.View - Gets or sets the view.
  25:              'ViewEngineResult.ViewEngine - Gets or sets the view engine.
  26:              'https://msdn.microsoft.com/en-US/library/system.web.mvc.viewengines%28v=vs.118%29.aspx
  27:              '
  28:              ViewEngineResult = System.Web.Mvc.ViewEngines.Engines.FindView(Controller_Context, ActionName, MasterPageName)
  29:          Catch ex As Exception
  30:              ViewEngineError = ex.Message
  31:          End Try
  32:          Dim ResultPath As String = ""
  33:          Dim ResultHTML As String = ""
  34:          If ViewEngineError = "" Then
  35:              If ViewEngineResult.View IsNot Nothing Then
  36:                  'єто итоговый путь найденной движком ViewEngines.Engines вьюхи
  37:                  ResultPath = DirectCast(ViewEngineResult.View, System.Web.Mvc.WebFormView).ViewPath
  38:                  '
  39:                  'System.Web.Mvc.ViewContext - контект исполнения вьюхи
  40:                  'ControllerContext - Encapsulates information about the HTTP request.
  41:                  'View - The view to render.
  42:                  'ViewData - The dictionary that contains the data that is required in order to render the view.
  43:                  'TempData - The dictionary that contains temporary data for the view.
  44:                  'Writer -  The text writer object that is used to write HTML output.
  45:                  'https://msdn.microsoft.com/en-us/library/system.web.mvc.viewcontext%28v=vs.118%29.aspx
  46:                  '
  47:                  Try
  48:                      Dim HomeView = New WebFormView(Controller_Context, ResultPath)
  49:                      Dim NoModel = New ViewDataDictionary(Model)
  50:                      Dim Writer = New IO.StringWriter()
  51:                      Dim ViewContext As New System.Web.Mvc.ViewContext(Controller_Context, HomeView, NoModel, New TempDataDictionary(), Writer)
  52:                      'наконец
  53:                      ViewEngineResult.View.Render(ViewContext, Writer)
  54:                      ResultHTML = Writer.ToString
  55:                      Return ResultHTML
  56:                  Catch ex As Exception
  57:                      Return ex.Message
  58:                  End Try
  59:              End If
  60:          Else
  61:              Return ViewEngineError
  62:          End If
  63:      End Function


Цей клас дуже важливий. Late binding та відокремлення даних від їх відображення у ідеології MVC приводить до цікавого ефекту - проект добре компілюється, але падає у будь якому місці на етапі роботи. Тобто ви намагаєтесь відображати дані типу MODEL.DATA а з контролеру передаете для відображення MODEL.DATE - і хоч компіляція пройшла добре, сайт може впасти у будь який момент, коли процесс його виконання дійде до цього місця. Цих глюков не було в звичайної технології ASP.NET (без літер MVC) - там, якщо сайт компілюється, то він і виконуватися буде. Я описував цю проблему багато разів, останній раз тут - Моя CMS для ASP.NET MVC. як Мікрософт відмовилась розвивати ASP.NET і загубила всі свої передові технологічні наработки, повернувшись до простого ASP (який існував до 2002-го року), лише доповнив його трошки не досить вдалої технологією URL-реврайтінгу. Мабуть половина програмістів на ASP.NET після цього кульбіту назавжди прокляла Мікрософт і назавжди лишила цю платформу. Але я залишився і став шукати, чи можливо хоч якось вдосконалити цю не дуже вдалу задумку, що дуже поширилась зараз у web-програмінгі і називається MVC. І знайшов я ось це рішення у вигляді цього класу.

А ще дуже схожа техніка описана у мене тут - AJAX завантаження Partial View



Comments ( )
Link to this page: //www.vb-net.com/CacheEnterPage/index.htm
< THANKS ME>