[英]Cannot read raw data as actionContext.Request.Content always empty in Action attribute in Web API
我需要通過屬性讀取通過 post/put 發送到我的 Web API 的內容以執行一些額外的驗證,但內容值始終為空,即使我可以看到context-size
設置了一個值,即 2067 和content-type
設置為application/json
我嘗試了不同的方法,但似乎都沒有奏效:
我的最后一次嘗試如下所示:
public async override void OnActionExecuting(HttpActionContext actionContext)
{
using (MemoryStream ms = new MemoryStream())
{
await actionContext.Request.Content.CopyToAsync(ms)
.ConfigureAwait(false);
var str = System.Text.UTF8Encoding.
UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);
}
}
我嘗試使用 CopyTo 的原因是我注意到,當我調用上述一些函數時,即使它們返回一個空字符串,我也可以在谷歌搜索后進行一次調用,我相信這是設計使然。
底線是我需要訪問我的請求的正文/內容,以便我可以檢查發送的 json。
謝謝。
這里的問題是執行 controller 操作的中間件讀取請求正文並因此在過程中消耗它,從而剝奪了任何后續中間件訪問它的機會。 這就是為什么您在嘗試解析 stream 時得到一個空字符串的原因,因為您正在有效地讀取長度為零的 stream 。
看起來 Action Filter 中間件是在 controller 中間件之后運行的,這在管道過程中已經太遲了。 一種解決方案是設置一個在 controller 中間件之前執行的自定義中間件,並僅在當前操作端點使用給定屬性注釋時解析請求正文 stream。
此處提供的解決方案是為 ASP.NET Core 3.0 編寫的,因此您可能需要進行一些調整才能使其在您的特定項目中工作。
在Startup.cs中:
public void Configure(IApplicationBuilder app)
{
app.UseRouting(); // Routes middleware
// Request body-reading middleware must be put after UseRouting()
app.Use(async (ctx, next) =>
{
var endpoint = ctx.GetEndpoint();
if (endpoint != null)
{
var attribute = endpoint.Metadata.GetMetadata<ThierryAttribute>();
if (attribute != null)
{
ctx.Request.EnableBuffering();
using (var sr = new StreamReader(ctx.Request.Body, Encoding.UTF8, false, 1024, true))
{
var str = await sr.ReadToEndAsync(); // Store request body JSON string
}
ctx.Request.Body.Position = 0;
}
}
await next();
});
app.UseEndpoints(erb => erb.MapControllers()); // Controller middleware
}
並將您的屬性設置為空標記屬性:
[AttributeUsage(AttributeTargets.Method)]
public class ThierryAttribute : Attribute { }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.