2013-02-13 3 views
2

Есть ли способ перехватить жизненный цикл страницы с контроллера MVC и ввести код где-нибудь на странице или DOM? Я хотел бы добавить HTML, CSS и JavaScript в верхний и нижний колонтитулы страницы, но не добавляя их в представление _Layout, которое где-то внедрено в сборку. Я бы хотел сделать это с контроллера Global.asax/Application_Start. Это возможно?Внедрить HTML или скрипты в жизненный цикл страницы MVC?

ответ

1

Я сделал что-то похожее на это.

Во-первых, вам нужно добавить заполнитель внутри файлов макета (где вы хотите, чтобы ввести код)

Во-вторых, вам нужно добавить глобальный ActionFilterAttribute в вашем global.asax. В FilterAttribute переопределить фильтр только с помощью OnActionExecuted и фильтровать только ViewResults.

В-третьих, вам необходимо изменить Response.Filter, с новым фильтром, который будет искать заполнители внутри html-кода и заменить его на свой собственный.

Я написал именно это, я добавил способ объявить стили & Скрипты в любом месте кода, и когда результат будет выполнен, ресурсы будут введены в главный тег.

public class DynamicHeaderHandler : ActionFilterAttribute 
{ 
    private static readonly byte[] _headClosingTagBuffer = Encoding.UTF8.GetBytes("</head>"); 
    private static readonly byte[] _placeholderBuffer = Encoding.UTF8.GetBytes(DynamicHeader.SectionPlaceholder); 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.Result is ViewResult) 
     { 
      filterContext.HttpContext.Response.Filter = new ResponseFilter(filterContext.HttpContext.Response.Filter); 
     } 

     base.OnActionExecuted(filterContext); 
    } 

    private class ResponseFilter : MemoryStream 
    { 
     private readonly Stream _outputStream; 

     public ResponseFilter(Stream aOutputStream) 
     { 
      _outputStream = aOutputStream; 
     } 

     public override void Close() 
     { 
      _outputStream.Flush(); 
      _outputStream.Close(); 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      var maxIndex = IndexOfSubArray(buffer, _headClosingTagBuffer); 
      var index = IndexOfSubArray(buffer, _placeholderBuffer, maxIndex); 

      if (index == -1) 
      { 
       _outputStream.Write(buffer, offset, count); 
      } 
      else 
      { 
       var html = DynamicHeader.GetHtml(); 
       var injectBytes = Encoding.UTF8.GetBytes(html); 
       var newBuffer = buffer.Take(index).Concat(injectBytes).Concat(buffer.Skip(index + _placeholderBuffer.Length)).ToArray(); 
       _outputStream.Write(newBuffer, 0, newBuffer.Length); 
      } 
     } 

     private static int IndexOfSubArray(byte[] aBuffer, byte[] aSubBuffer, int aMaxIndex = int.MaxValue) 
     { 
      if (aBuffer.Length < aSubBuffer.Length) 
      { 
       return -1; 
      } 

      for (var outerIndex = 0; outerIndex < aBuffer.Length && outerIndex < aMaxIndex; ++outerIndex) 
      { 
       var isEqual = true; 
       for (int subInnerIndex = 0, innerIndex = outerIndex; subInnerIndex < aSubBuffer.Length && innerIndex < aBuffer.Length; ++subInnerIndex, ++innerIndex) 
       { 
        if (aBuffer[innerIndex] != aSubBuffer[subInnerIndex]) 
        { 
         isEqual = false; 
         break; 
        } 
       } 

       if (isEqual) 
       { 
        return outerIndex; 
       } 
      } 

      return -1; 
     } 
    } 
} 

Я прикрепил ActionFilterAttribute, что, вероятно, относится к вам.

Если вы хотите увидеть весь код, вы можете посетить здесь: Add Styles & Scripts Dynamically

+0

Что делать, если есть несколько вызовов писать, первый пишущие до ' '? В этом случае ваш код не обнаружит конца головы. Обычно куски, переданные в Write, должны быть больше, чем общий HTML-заголовок, но все же. Вероятно, вы должны буферизировать все входные данные и сравнить буферный ввод с закрывающим тегом буфера. Разумеется, после окончания головы вы можете писать все непосредственно в поток завернутого потока. –

+0

Не думал об этом случае! Так или иначе, так как у меня никогда не было проблем, я думаю, мне повезло и не столкнулось с этим делом. Я исправлю это на моей стороне. Но это вам помогло? –

Смежные вопросы