ASP.NET核心服务器AllowSynchronousIO
设置为false
new WebHostBuilder()
.UseKestrel(options =>
{
options.AllowSynchronousIO = false;
})
在动作中,它输出一个JsonResult
public async Task<IActionResult> SanityCheck()
{
Dictionary<string, string> dic = await GetDic();
return this.Json(dic);
}
它以异常结束
System.InvalidOperationException:同步操作是 不允许。调用WriteAsync或将AllowSynchronousIO设置为true。
我不能用AllowSynchronousIO=false
返回JsonResult吗?
最好的问候
答案 0 :(得分:4)
我的单元测试中有这个问题。我必须将TestServer更新为AlloSynchronousIO
Server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
Server.AllowSynchronousIO = true;
答案 1 :(得分:2)
您可能遇到以下问题:https://github.com/aspnet/AspNetCore/issues/8302
您可以在此处找到更多信息:https://github.com/aspnet/AspNetCore/issues/7644
直到解决此问题的变通办法是允许syncIO。将其放在Startup.cs中。如果您使用的是IIS,则为IISServerOptions。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
}
答案 2 :(得分:1)
基于 Mark Lagendijk 的 answer,我以具有属性的声明方式应用了该逻辑:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class AllowSynchronousIOAttribute : ActionFilterAttribute
{
public AllowSynchronousIOAttribute()
{
}
public override void OnResultExecuting(ResultExecutingContext context)
{
var syncIOFeature = context.HttpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
syncIOFeature.AllowSynchronousIO = true;
}
}
}
只需在操作方法或整个控制器上使用它即可启用它:
[AllowSynchronousIO]
public IActionResult DownloadSynchronous()
{
return Something();
}
答案 3 :(得分:0)
我不确定您的要求是什么或GetDic()
做什么,但是在GetDic()
不执行任何同步IO的情况下,以下代码绝对可以正常工作:
public async Task<IActionResult> SanityCheck()
{
Dictionary<string, string> dic = await GetDic();
return this.Ok(dic);
}
如果您仍然想将dic
序列化为JSON,则应执行以下代码:
public async Task<IActionResult> SanityCheck()
{
Dictionary<string, string> dic = await GetDic();
string json = JsonConvert.SerializeObject(dic);
return this.Ok(json);
}
请注意,这最后一段代码以text/plain
而不是application/json
的形式返回结果。
我也在ASP.NET Core 2.2下进行了测试。
答案 4 :(得分:0)
这段代码对我有用,异步读取:
public override async void OnActionExecuting(ActionExecutingContext filterContext)
{
string content = "";
var request = filterContext.HttpContext.Request;
try
{
request.EnableBuffering();
request.Body.Position = 0;
using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8,true,1024,true))
{
content = await reader.ReadToEndAsync();
}
}
finally
{
request.Body.Position = 0;
}
}