在ActionFilter中读取响应,然后在DelegatingHandlers中读取

时间:2018-08-02 10:52:44

标签: c# asp.net asp.net-web-api

我们是否应该始终从<!DOCTYPE html> <html> <head> <style> body { font-size: 28px; } ul { list-style-type: none; margin: 0; padding: 0; overflow: visible; display: inline-block; width: 100%; background-color: #333; position: -webkit-sticky; /* Safari */ position: sticky; top: 0; } li { float: left; } li a, .dropbtn { display: block; color: white; text-align: center; padding: 14px 16px; text-decoration: none; } li a:hover, .dropdown:hover .dropbtn { background-color: #111; } .active { background-color: #4CAF50; } li.dropdown { display: block; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .dropdown-content a { color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .dropdown-content a:hover {background-color: #f1f1f1} .dropdown:hover .dropdown-content { display: block; } </style> </head> <body> <div class="header"> <h2>Scroll Down</h2> <p>Scroll down to see the sticky effect.</p> </div> <ul> <li><a class="active" href="#home">Home</a></li> <li><a href="#news">News</a></li> <li class="dropdown"> <a href="javascript:void(0)" class="dropbtn">Dropdown</a> <div class="dropdown-content"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </li> </ul> <h3>Sticky Navigation Bar Example</h3> <p>The navbar will <strong>stick</strong> to the top when you reach its scroll position.</p> <p><strong>Note:</strong> Internet Explorer, Edge 15 and earlier versions do not support sticky positioning. Safari requires a -webkit- prefix.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p> </body> </html> 读取流,然后重设?我们从响应中读取了两次,但没有效果[1]。

我们试图用HttpContent记录HTTP响应,然后在ActionFilterAttribute中更新响应。 DelegatingHandler中所做的更改丢失了:到达客户端的响应没有改变。

DelegatingHandler
public sealed class LoggingFilterAttribute : ActionFilterAttribute
{
    public override async void OnActionExecuted(HttpActionExecutedContext context)
    {
        string logMessage = null;
        context.Response?.Content?
            .ReadAsStringAsync()
            .ContinueWith(task => logMessage = task.Result);
        ...
    }
}

更改internal class AddVersionsHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var response = await base.SendAsync(request, cancellationToken); var responseContent = await response.Content .ReadAsAsync<IOurModels>(cancellationToken) .ConfigureAwait(false); responseContent.Versions = this.Versions; return response; } } 中的读取内容以从流中读取,然后重置位置即可。假设ActionFilterAttribute是必须在每次读取时重置的流。

HttpContent

我们是否需要确保读取public override async void OnActionExecuted(HttpActionExecutedContext context) { string logMessage = null; if (context.ActionContext?.Response?.Content != null) { var memoryStream = new MemoryStream(); await context.ActionContext.Response.Content.CopyToAsync(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); var sr = new StreamReader(memoryStream); logMessage = sr.ReadToEnd(); } ... } 任何地方,我们需要从流中读取然后重新设置?

将这些HttpContent绑定到每个更改响应的管道中就可以了。似乎DelegatingHandlers提供了对流中基础对象的访问,而无需更改读取位置。因此,如果您知道要读取的对象类型,则可以使用此选项。

1 个答案:

答案 0 :(得分:1)

如果您想阅读或更改响应的内容,并且知道对象的类型,则可以使用ReadAsAsync<T>。如果需要,可以将它们链接在管道中。

ReadAsAsync<T>()

如果要记录日志,则可以将以上响应序列化为XML或JSON。

如果要以字符串形式读取流,则只能使用var response = await context.ActionContext.Response.Content.ReadAsAsync<IOurModel>(); 来执行一次。管道中的后续更新将丢失。

ReadAsStringAsync()

如果您想读取流并稍后对其进行任何其他操作,则必须重置位置。

string logMessage = null;
context.Response?.Content?
    .ReadAsStringAsync()
    .ContinueWith(task => logMessage = task.Result);
相关问题