5

ブラウザに送信されるすべての html を傍受し、そこにあるいくつかのタグを置き換える必要があります。これは、グローバルに、すべてのビューに対して行う必要があります。C#を使用してASP.NET MVC 3または4でこれを行う最良の方法は何ですか? 過去に、Global.asax (vb) の「response.filter」を使用して、ASP.net Webforms でこれを実行しました。

Private Sub Global_PreRequestHandlerExecute(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRequestHandlerExecute
    Response.Filter = New ReplaceTags(Response.Filter)
End Sub

これは、system.io.stream から継承し、すべてのタグを置き換えるために html をウォークスルーする、私が作成したクラスを呼び出します。C# を使用して ASP.NET MVC 4 でこれを行う方法がわかりません。お気づきかもしれませんが、私は MVC の世界ではまったくの初心者です。

4

2 に答える 2

10

ASP.NET MVC で引き続き応答フィルターを使用できます。

public class ReplaceTagsFilter : MemoryStream
{
    private readonly Stream _response;
    public ReplaceTagsFilter(Stream response)
    {
        _response = response;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        var html = Encoding.UTF8.GetString(buffer);
        html = ReplaceTags(html);
        buffer = Encoding.UTF8.GetBytes(html);
        _response.Write(buffer, offset, buffer.Length);
    }

    private string ReplaceTags(string html)
    {
        // TODO: go ahead and implement the filtering logic
        throw new NotImplementedException();
    }
}

次に、応答フィルターを登録するカスタム アクション フィルターを作成します。

public class ReplaceTagsAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var response = filterContext.HttpContext.Response;
        response.Filter = new ReplaceTagsFilter(response.Filter);
    }
}

あとは、このフィルターを適用するコントローラー/アクションを装飾するだけです。

[ReplaceTags]
public ActionResult Index()
{
    return View();
}

または、すべてのアクションに適用する場合は、Global.asax でグローバル アクション フィルターとして登録します。

于 2012-05-15T07:44:45.190 に答える
5

答えは正しいですが。しばらく使っていたらレスポンスがバラバラになってhtmlが間違っているケースに遭遇しました

Part 1: 
<html>.....<labe

Part 2: 
l/>...</html>

また、部分的なレンダリングでは、予期しないケースが発生する可能性があります。彼らのhtmlもメインストリームから外れています。したがって、私の解決策は、すべてのストリーミングが完了した後に Flush メソッドで行うことです。

    /// <summary>
    /// Insert messages and script to display on client when a partial view is returned
    /// </summary>
    private class ResponseFilter : MemoryStream
    {
        private readonly Stream _response;
        private readonly IList<object> _detachMessages;

        public override void Flush()
        {

            // add messages and remove
            // filter is called for a number of methods on one page (BeginForm, RenderPartial...)
            // so that we don't need to add it more than once

            var html = MessageAndScript(_detachMessages);
            var buffer = Encoding.UTF8.GetBytes(html);
            _detachMessages.Clear();
            _response.Write(buffer, 0, buffer.Length);

            base.Flush();
        }

        public ResponseFilter(Stream response, IList<object> detachMessages)
        {
            _response = response;
            _detachMessages = detachMessages;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _response.Write(buffer, offset, buffer.Length);    
        }

        private static string MessageAndScript(IList<object> detachMessages)
        {

            if (detachMessages.Count == 0)
                return null;

            var javascript = CustomJavaScriptSerializer.Instance.Serialize(detachMessages);

            return "$(function(){var messages = " + javascript + @";
// display messages
base.ajaxHelper.displayMessages(messages);
})";
        }
    }
于 2014-01-19T20:37:53.117 に答える