Asp. net Запрос веб-API Core 3.1 с массивом объектов без привязки - PullRequest
1 голос
/ 27 мая 2020

У меня есть проект ASP. net Core 3.1 web api. В одном из моих контроллеров у меня есть метод Post, который принимает объект запроса, содержащий массив объектов. Я проделал то же самое в ASP. Net с использованием. Net Framework и в ASP. Net Core 2.1 без проблем. Однако в версии 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# модели

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; }
    }

Пример запроса, используемый почтальоном для проверки {

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

}

Попытка отладить список ответов всегда пустой. Я безуспешно пытался использовать массив и тип списка вместо IEnumerable. Я знаю, что они изменили сериализатор в 3.1, но не уверен, почему массив не может сериализоваться? Кто-нибудь знает ответ? вот мой 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();

        });
    }
}

1 Ответ

0 голосов
/ 27 мая 2020

Я думаю, что вам нужно сделать поле QuestionaireAnswerRequestModel Answer для свойства, например. добавить {получить; устанавливать; } к нему:

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

Из MSDN:

Сложный тип должен иметь конструктор по умолчанию publi c и свойства publi c с возможностью записи для привязки. Когда происходит привязка модели, экземпляр класса создается с помощью конструктора по умолчанию publi c.

Surce: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...