简体   繁体   English

Asp.net Core 3.1 Web api 对象数组请求未绑定

[英]Asp.net Core 3.1 Web api request with array of objects not binding

I have an ASP.net Core 3.1 web api project.我有一个 ASP.net Core 3.1 web api 项目。 In one of my controllers, I have a Post method that accepts a request object that contains an array of objects.在我的一个控制器中,我有一个 Post 方法,它接受包含对象数组的请求 object。 I have done this same thing in ASP.Net using.Net Framework and in ASP.Net Core 2.1 with no problem.我在 ASP.Net using.Net Framework 和 ASP.Net Core 2.1 中做过同样的事情,没有问题。 However, in 3.1 The array is not getting bound when calling the api method.但是,在 3.1 中调用 api 方法时,数组并未绑定。

 [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# models 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 {示例请求在 postman 中用于测试 {

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

} }

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.尝试调试,答案列表始终为 null。我尝试使用数组和列表类型而不是 IEnumerable,但没有成功。 I know they changed the serializer in 3.1 but not sure why an array is not able to serialize?我知道他们在 3.1 中更改了序列化程序,但不确定为什么数组无法序列化? Does Anyone know the answer?有人知道答案吗? here is my startup.cs这是我的 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();

        });
    }
}

I think that you need to make QuestionaireAnswerRequestModel field Answers a property eg.我认为您需要将 QuestionaireAnswerRequestModel 字段 Answers 设为一个属性,例如。 add { get;添加{得到; set;放; } to it: } 对它:

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

From MSDN:来自 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.当 model 发生绑定时,使用公共默认构造函数实例化 class。

Surce: https://learn.microsoft.com/en-us/as.net/core/mvc/models/model-binding?view=as.netcore-3.1来源: https://learn.microsoft.com/en-us/as.net/core/mvc/models/model-binding?view=as.netcore-3.1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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