.NetCore 3.1 WebApi中的GraphQL给出“不允许执行同步操作”错误

时间:2020-07-31 15:55:00

标签: .net-core graphql asp.net-core-webapi

我正在学习多个站点课程“使用ASP.NET Core构建GraphQL API”,但似乎还没有完成。运行“游乐场”时,浏览器将加载:

  • 消息“无法访问服务器”
  • 架构无法加载
  • 以及浏览器右侧窗格中的以下文本:

{“错误”:“ JSON在位置0处出现意外令牌S”}

如果我将其作为应用程序(而不是IISExpress)运行,则在控制台窗口中会看到以下故障:

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware [1] 执行请求时发生未处理的异常。 System.InvalidOperationException:同步操作是 不允许。

我发现一些帖子说添加了AllowSynchronousIO选项,但是我没有用。我也尝试在IISExpress中运行...没什么区别。

以下是我的设置的一些详细信息:

.Net Core 我创建了一个ASP.NET Core 3.1(3.1.6)Web API项目。

NuGet程序包

  • GraphQL(2.4.0)
  • GraphQL.Server.Transports.AspNetCore(3.4.0)
  • GraphQL.Server.Ui.Playground(3.4.0)

github site上有一个免责声明,即最新的稳定版本具有“许多已知问题”,这些问题可能已在预览版本中修复,但是我尝试了这些问题,甚至无法对其进行编译。 ..

Startup.cs

使用语句

using global::GraphQL;
using global::GraphQL.Server;
using global::GraphQL.Server.Ui.Playground;
using global::GraphQL.Types;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApiGQL.GraphQL.Schema;
using WebApiGQL.Repository;

ConfigureServices

services.AddCors();

services.AddScoped<IProductRepository, ProductRepository>();
services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService));
services.AddScoped<ProductSchema>();
services
    .AddGraphQL(o => { o.ExposeExceptions = true; })
    .AddGraphTypes(ServiceLifetime.Scoped);
services.Configure<IISServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});

配置

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseCors(o => o.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseGraphQL<ISchema>();
app.UseGraphQLPlayground(new GraphQLPlaygroundOptions());

[注意:app.UseCors(...)最终将进入if (env.IsDevelopment())块。]

我倾向于不使用IISExpress开发Core应用程序,因为我认为您会从弹出的命令窗口中获得更好的诊断。

GraphQL看起来非常强大,我很想启动它并运行....但是看不到我所缺少的东西。


编辑8月3日:回复于永清

因此,这是一个真正的“ Hello World”应用程序,不使用实体框架。最终的应用程序(如果我们采用这种方式)将从一系列端点(例如SQL,其他API, etc etc )中提取数据,并将这些数据合并在一起然后返回合并的详细信息。

ProductSchema.cs

public class ProductSchema : Schema
{
    public ProductSchema(IDependencyResolver resolver) :
        base(resolver)
    {
        Query = resolver.Resolve<ProductQuery>();
    }
}

IProductRepository

public interface IProductRepository
{
    List<Product> GetAll();

    //List<Product> GetList(List<string> skus);

    //Product Get(string sku);
}

我的意图是只注释掉两个方法,但是我回到基础知识,只是尝试了一个“ GetAll”方法来解决这个问题。

产品存储库

public class ProductRepository : IProductRepository
{
    public List<Product> GetAll()
    {
        return this.AllProducts;
    }

    //public List<Product> GetList(List<string> skus)
    //{
    //    return this.AllProducts.Where(p => skus.Contains(p.Sku)).ToList();
    //}

    //public Product Get(string sku)
    //{
    //    return this.AllProducts.FirstOrDefault(p => p.Sku.Equals(sku));
    //}

    private readonly List<Product> AllProducts = new List<Product>
        {
            new Product
            {
                Sku = "ABC12345"
            },

            new Product
            {
                Sku = "ABC12345"
            }
        }
    }

ProductType.cs

public class ProductType : ObjectGraphType<Product>
{
    public ProductType()
    {
        Field(p => p.Sku);
    }
}

Product.cs 我从一个复杂的野兽开始,其中包括以下属性:

  • 列表
  • 枚举
  • 字符串,整数,布尔值和小数

但是,为简化起见,我将其简化为:

public class Product
{
    public string Sku { get; set; }
}

1 个答案:

答案 0 :(得分:0)

最后....解决了这个问题。

我有:

services.Configure<IISServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});

但需要:

services.Configure<KestrelServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});