Asp.net Core 3.1 Web API请求与未绑定的对象数组 [英] Asp.net Core 3.1 Web api request with array of objects not binding

查看:70
本文介绍了Asp.net Core 3.1 Web API请求与未绑定的对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.net Core 3.1 Web API项目.在我的一个控制器中,我有一个Post方法,该方法接受包含对象数组的请求对象.我在使用.Net Framework的ASP.Net和在ASP.Net Core 2.1中都没有问题,也做了同样的事情.但是,在3.1版中,调用api方法时未绑定数组.

I have an ASP.net Core 3.1 web api project. In one of my controllers, I have a Post method that accepts a request object that contains an array of objects. I have done this same thing in ASP.Net using .Net Framework and in ASP.Net Core 2.1 with no problem. However, in 3.1 The array is not getting bound when calling the api method.

 [HttpPost(), Route("{id}/Answers")]
    [ProducesResponseType(typeof(QuestionaireAnswerModel), StatusCodes.Status201Created)]
    public async Task<IActionResult> PostAnswers(int id, QuestionaireAnswerRequestModel request) {
        try
        {
            if (ModelState.IsValid)
            {
                if (request.Answers == null || request.Answers.Count < 1) 
                    return BadRequest("Answers are required.");
                var result = await _service.CreateQuestionaireAnswersAsync(id, request);
                return Created($"https://blah/api/{result.Id}", result);
            }
            else { return BadRequest(ModelState); }
        }
        catch (Exception ex)
        {
            var message = $"An error occurred posting answers for Questionnaire. Questionnaire Id: {id}, UserName: {request.UserName}";
            _logger.LogError(ex, message);
            return StatusCode(StatusCodes.Status500InternalServerError, message);
        }
    }

c#个模型

public class QuestionaireAnswerRequestModel
    {
        public string UserName { get; set; }
        public IEnumerable<QuestionAnswerRequestModel> Answers;
    }

public class QuestionAnswerRequestModel
    {
        public int QuestionId { get; set; }
        public bool Answer { get; set; }
    }

邮递员用于测试的样本请求{

Sample request used in postman to test {

"userName": "testuser",
"answers": [{
    "questionId": 1,
    "answer": "false"
}]

}

尝试调试,答案列表始终为空.我试过使用数组和列表类型而不是IEnumerable,但是没有运气.我知道他们在3.1中更改了序列化器,但不确定为什么数组无法序列化?有人知道答案吗?这是我的startup.cs

Trying to debug and the answers list is always null. I have tried using an array and List type instead of IEnumerable with no luck. I know they changed the serializer in 3.1 but not sure why an array is not able to serialize? Does Anyone know the answer? here is my startup.cs

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)
    {            
        var connection = Configuration.GetConnectionString("HealthScreeningConnection");
        services.AddEntityFrameworkSqlServer()
            .AddEntityFrameworkProxies()
            .AddDbContextPool<HealthScreeningContext>((serviceProvider, options) => {
                options.UseSqlServer(connection).UseInternalServiceProvider(serviceProvider);
                options.UseLazyLoadingProxies();
            });
        services.AddScoped<IQuestionareService, QuestionaireService>();
        services.AddScoped<IAccountService, AccountService>();
        services.AddControllers();
        services.AddCors(opts => {
            opts.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader());
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        var nlogFilePath = "nlog.config";
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            nlogFilePath = $"nlog.{env.EnvironmentName}.config";
        }
        NLog.LogManager.LoadConfiguration(nlogFilePath);

        app.UseHttpsRedirection();

        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();
        app.UseCors("CorsPolicy");

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

        });
    }
}

推荐答案

我认为您需要将QuestionaireAnswerRequestModel字段设置为Answers属性,例如.添加{get;放;}:

I think that you need to make QuestionaireAnswerRequestModel field Answers a property eg. add { get; set; } to it:

public class QuestionaireAnswerRequestModel
{
    public string UserName { get; set; }
    public IEnumerable<QuestionAnswerRequestModel> Answers { get; set; }
}

从MSDN:

复杂类型必须具有公共默认构造函数和公共可写属性才能绑定.发生模型绑定时,将使用公共默认构造函数实例化该类.

A complex type must have a public default constructor and public writable properties to bind. When model binding occurs, the class is instantiated using the public default constructor.

来源: https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/model-binding?view = aspnetcore-3.1

这篇关于Asp.net Core 3.1 Web API请求与未绑定的对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆