VERSION 2Лучшее место, чтобы заменить текст в ASP.NET MVC pipline
Я обновил исходный код, принимая во внимание тот факт, что метод записи потокового в HTML на странице в кусках.
Как указано «Поскольку у вас не гарантируется, что« THE_PLACEHOLDER »записывается в непрерывный блок байтов в записи. Вы можете получить «THE_PLACEH» в конце одного вызова для записи и «OLDER» в начале следующего.
Я исправил это, поставив полное содержимое потока в Stringbuilder и выполнив любое обновление, которое требуется для метода Close.
Сделав это, я задаю тот же вопрос снова ниже ....
Я работаю на CMS, которая просто заменяет заполнитель с текстом CMS.
У меня есть следующее, которое работает так, как должно.
Я переопределены в IHttpModule
public class CmsFilterHttpModule : IHttpModule {
// In the Init method, register HttpApplication events by adding event handlers.
public void Init(HttpApplication httpApplication) {
httpApplication.ReleaseRequestState += new EventHandler(this.HttpApplication_OnReleaseRequestState);
}
/// <summary>
/// HttpApplication_OnReleaseRequestState event handler.
///
/// Occurs after ASP.NET finishes executing all request event handlers.
/// This event causes state modules to save the current state data.
/// </summary>
private void HttpApplication_OnReleaseRequestState(Object sender, EventArgs e) {
HttpResponse httpResponse = HttpContext.Current.Response;
if (httpResponse.ContentType == "text/html") {
httpResponse.Filter = new CmsFilterStream(httpResponse.Filter);
}
}
public void Dispose() {
//Empty
}
}
и MemoryStream
public class CmsFilterStream : MemoryStream {
private Stream _responseStream;
private StringBuilder _responseHtml;
public CmsFilterStream(Stream inputStream) {
_responseStream = inputStream;
_responseHtml = new StringBuilder();
}
/// <summary>
/// Writes a block of bytes to the current stream using data read from a buffer.
/// </summary>
/// <param name="buffer">The buffer to write data from.</param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
/// <param name="count">The maximum number of bytes to write.</param>
public override void Write(Byte[] buffer, Int32 offset, Int32 count) {
if (buffer == null) { throw new ArgumentNullException("buffer", "ArgumentNull_Buffer"); }
if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "ArgumentOutOfRange_NeedNonNegNum"); }
if (count < 0) { throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_NeedNonNegNum"); }
if (buffer.Length - offset < count) { throw new ArgumentException("Argument_InvalidOffLen"); }
String bufferContent = UTF8Encoding.UTF8.GetString(buffer, offset, count);
_responseHtml.Append(bufferContent);
}
public override void Close() {
_responseHtml.Replace("THE_PLACEHOLDER", "SOME_HTML");
_responseStream.Write(UTF8Encoding.UTF8.GetBytes(_responseHtml.ToString()), 0, UTF8Encoding.UTF8.GetByteCount(_responseHtml.ToString()));
_responseStream.Dispose();
base.Close();
}
}
и следующее в Web.config
<system.webServer>
<modules>
<remove name="CmsFilterHttpModule" />
<add name="CmsFilterHttpModule" type="{MY_NAMESPACE}.CmsFilterHttpModule" />
</modules>
</system.webServer>
Это делает работу, как я требую.
Мой вопрос в самом деле - это лучшее место в трубопроводе, чтобы сделать это, прежде чем я начну работать назад.
Этот метод заменяет текст на завершенном выходе.
Я ищу самый быстрый способ заменить этот текст с точки зрения трубопровода.
На данный момент игнорируется скорость String.Replace/Stringbuilder и различные другие методы. Я вижу, что оптимизация немного дальше.
Я еще не отлаживал весь конвейер, но, хотя я предполагаю, что эта страница должна быть построена из разных частей, т. Е. Макетов, видов частичных и т. Д. И т. Д., Возможно, их быстрее заменить текст в этих частях.
Кроме того, в дополнение будут ли какие-либо проблемы с
String bufferContent = UTF8Encoding.UTF8.GetString(buffer);
при использовании других языков японский, китайский и т.д.
Я должен также добавить, что я пытаюсь сделать это как отдельный добавлен фрагмент кода, который затрагивает код сайта MVC для пользователей как можно меньше.
Вы изучали фильтр действий «OnActionExecuted»? – xandercoded
Я еще не смотрел в глаза другим. На самом деле это мой вопрос. Другие люди переживают, мнения, разные способы люди подошли к этому и т. Д. –
Также я должен добавить, что я пытаюсь сделать это как отдельный добавленный фрагмент кода, который как можно меньше затрагивает исходный код MVC. Так что это действительно исключает действие фильтра. –