У меня есть действие контроллера, подобное
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Put)]
[InsertScript(Order = 1)]
[Compress(Order = 2)]
public ViewResult Service(Page page) { //omitted }
Атрибут InsertScript применил Response.Filter
response.Filter = new RegexResponseFilter(response.Filter, scriptInsertRegex, replacementString);
Фильтр ответов регулярных выражений основан на сообщении в блоге здесь.Примечание. Я не пытаюсь удалить пробел, я пытаюсь вставить тег сценария, но это не имеет значения.
Метод записи RegexResponseFilter такой же.Остальное такое же, как в блоге.
public override void Write(byte[] buffer, int offset, int count)
{
// capture the data and convert to string
var data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
// filter the string
var s = Encoding.Default.GetString(buffer);
s = regex.Replace(s, replacement);
// write the data to stream
var outdata = Encoding.Default.GetBytes(s);
response.Write(outdata, 0, outdata.GetLength(0));
}
Это прекрасно работает в изоляции.Но когда я применил атрибут сжатия (довольно стандартный, который можно увидеть в любом количестве мест в интернете), это сломалось, когда FF4 выдал сообщение об ошибке.
Страница, которую вы пытаетесь просмотреть, не может бытьпоказано, потому что он использует недопустимую или неподдерживаемую форму сжатия.
Я почувствовал запах красной сельди и удалил атрибут InsertScript, и он работает.Таким образом, эти два противоречат в некотором роде.Вот атрибут сжатия для полноты.
public class CompressAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//get request and response
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response;
//get encoding
var encoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrWhiteSpace(encoding))
return;
encoding = encoding.ToUpperInvariant();
if (encoding.Contains("DEFLATE") || encoding == "*")
{
response.AppendHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
else if (encoding.Contains("GZIP"))
{
response.AppendHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
base.OnActionExecuting(filterContext);
}
}
Возможно, это что-то очевидное, но похоже, что оно должно работать.Вставка должна быть применена до сжатия.
Большое спасибо