简体   繁体   中英

GraphQL Web Api using .NET Core and having null data values?

I'm writing a GraphQL API using .NET Core 3.1 and I am able to retrieve records if data exists in every field, but if one field contains a NULL value the entire record comes back NULL. Why is this? I've written GraphQL API's using python and it will return NULL for the field like how I expected. I'm new to .NET Core so is this something that just can't be done? Surely this answer is simple. Here is my code. Thanks in advance!

Here is the error. It is saying SDMGroup field contains a NULL, but why is this a problem? 在此处输入图像描述

Model

using System;
using System.ComponentModel.DataAnnotations;

namespace GraphQLDotNetCore.Entities
{
    public class ProcessTeam
    {
        [Key]
        public int ProcessTeamID { get; set; }
        public string ProcessTeamName { get; set; }

        [Required(ErrorMessage = "CreatedDate is required")]
        public DateTime CreatedDate { get; set; }
        public string CreatedBy { get; set; }

        [Required(ErrorMessage = "LastModifiedDate is required")]
        public DateTime LastModifiedDate { get; set; }
        public string LastModifiedBy { get; set; }

        [Required(ErrorMessage = "Active is required")]
        public Boolean Active { get; set; }
        public string SDMGroup { get; set; }
    }
}

Contract

using GraphQLDotNetCore.Entities;
using System.Collections.Generic;

namespace GraphQLDotNetCore.Contracts
{
    public interface IProcessTeamRepository
    {
        List<ProcessTeam> GetProcessTeams();
    }
}

Repository

using GraphQLDotNetCore.Contracts;
using GraphQLDotNetCore.Entities;
using System.Collections.Generic;
using System.Linq;

namespace GraphQLDotNetCore.Repository
{
    public class ProcessTeamRepository : IProcessTeamRepository
    {
        private readonly ApplicationContext _context;

        public ProcessTeamRepository(ApplicationContext context)
        {
            _context = context;
        }

        public List<ProcessTeam> GetProcessTeams() => _context.tb_ProcessTeam.ToList();
    }
}

GraphQL Query

using GraphQL.Types;
using GraphQLDotNetCore.Contracts;
using GraphQLDotNetCore.GraphQL.GraphQLTypes;
using GraphQLDotNetCore.Repository;

namespace GraphQLDotNetCore.GraphQL.GraphQLQueries
{
    public class AppQuery : ObjectGraphType
    {
        public AppQuery(IProcessTeamRepository processteam)
        {
            Field<ListGraphType<ProcessTeamType>>("processteams", resolve: context => processteam.GetProcessTeams());
        }
    }
}

GraphQL Schema

using GraphQL.Types;
using GraphQL.Utilities;
using GraphQLDotNetCore.GraphQL.GraphQLQueries;
using System;

namespace GraphQLDotNetCore.GraphQL.GraphQLSchema
{
    public class AppSchema : Schema
    {
        public AppSchema(IServiceProvider provider)
            :base(provider)
        {
            Query = provider.GetRequiredService<AppQuery>();
        }
    }
}

GraphQL Type

using GraphQL.Types;
using GraphQLDotNetCore.Entities;

namespace GraphQLDotNetCore.GraphQL.GraphQLTypes
{
    public class ProcessTeamType : ObjectGraphType<ProcessTeam>
    {
        public ProcessTeamType()
        {
            Field(x => x.ProcessTeamID, type: typeof(IdGraphType)).Description("Id property from the process team object.");
            Field(x => x.ProcessTeamName).Description("process team Name property from the process team object.");
            Field(x => x.CreatedDate).Description("Created Date property from the process team object");
            Field(x => x.CreatedBy).Description("Created By property from the process team object");
            Field(x => x.LastModifiedDate).Description("Last Modified Date property from the process team object");
            Field(x => x.LastModifiedBy).Description("Last Modified By property from the process team object");
            Field(x => x.Active).Description("Active field from the process team object");
            Field(x => x.SDMGroup).Description("Group field from the process team object");
        }
    }
}

Application Context

using GraphQLDotNetCore.Entities.Context;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GraphQLDotNetCore.Entities
{
    public class ApplicationContext : DbContext
    {
        public ApplicationContext(DbContextOptions options)
            :base(options)
        {
        }

        public DbSet<ProcessTeam> tb_ProcessTeam { get; set; }
    }
}

Startup

using GraphQL.Server;
using GraphQL.Server.Ui.Playground;
using GraphQLDotNetCore.Contracts;
using GraphQLDotNetCore.Entities;
using GraphQLDotNetCore.GraphQL.GraphQLSchema;
using GraphQLDotNetCore.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace GraphQLDotNetCore
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationContext>(opt =>
                opt.UseSqlServer(Configuration.GetConnectionString("sqlConString")));


            services.AddScoped<IProcessTeamRepository, ProcessTeamRepository>();
    

            services.AddScoped<AppSchema>();

            services.AddGraphQL()
                .AddSystemTextJson()
                .AddGraphTypes(typeof(AppSchema), ServiceLifetime.Scoped);

            services.AddControllers()
                .AddNewtonsoftJson(o => o.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

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

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseGraphQL<AppSchema>();
            app.UseGraphQLPlayground(options: new GraphQLPlaygroundOptions());

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

I resolved my issue by upgrading to .NET Core 5 and using the hot chocolate assemblies available in the nuget package store. Here is an awesome tutorial on getting it set up.

.Net 5 API with GraphQL

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM