C # - модель всегда получает свои значения по умолчанию - PullRequest
0 голосов
/ 14 октября 2019

У меня есть приложение ASP.Net Core 2.1.

Ниже приведены мои билеты DTO

public class Movie
{
  public int Id { get; set;}

  public bool IsSpecial {get; set;}

  public IEnumerable<Ticket> Tickets { get; set; }

    public Movie()
    {
        if(IsSpecial)
        {
            this.Tickets = new List<TicketSpecial>();
        }
        else
        {
            this.Tickets = new List<Ticket>();
        }
    }}}

(базовый класс)

 public class Ticket
 {
   public int Id { get; set;}

   public string Name { get; set;}

   public decimal price { get; set;}
 } 

TicketsSpecial (Child / Derived Class)

 public class TicketsSpecial : Ticket
 {
    public string SpecialProp1 { get; set;}

    public string SpecialProp2 { get; set;}

 }

Контроллер WebAPI

public class MovieController : ControllerBase
{

  public IActionResult Post([FromBody]Movie movie)
  {
  }
}

Почтальон (полезная нагрузка HTTPPost Req Content-Type = application/json)

{
"IsSpecial": true,
"SpecialProp1": "Mumbai Test",
}

Когда я вызываю вышеуказанный API через Почтальон& debug в Movie Ctor, он всегда ловит значение IsSpecial = false и значение по умолчанию для всех полей (например, для строкового типа null)

Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

В вашей текущей реализации есть две проблемы. Во-первых, ваш запрос json недействителен для вложенных свойств, и десериализатор json не сможет десериализовать вас с помощью TicketsSpecial.

Для обходного пути выполните следующие шаги:

  1. Movie

    public class Movie
    {
            public int Id { get; set; }
    
            public bool IsSpecial { get; set; }
    
            public IEnumerable<Ticket> Tickets { get; set; }
    
    }
    
  2. MyJsonInputFormatter

    public class MyJsonInputFormatter : JsonInputFormatter
    {
            public MyJsonInputFormatter(ILogger logger, JsonSerializerSettings serializerSettings, ArrayPool<char> charPool, ObjectPoolProvider objectPoolProvider, MvcOptions options, MvcJsonOptions jsonOptions) : base(logger, serializerSettings, charPool, objectPoolProvider, options, jsonOptions)
            {
    
            }
            public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
            {
            var result = await base.ReadRequestBodyAsync(context);
            if (result.Model is Movie movie && movie.IsSpecial)
            {
                    context.HttpContext.Request.Body.Position = 0;
                    string request = await new StreamReader(context.HttpContext.Request.Body).ReadToEndAsync();
                    var tickets = JObject.Parse(request)["Tickets"].ToObject<List<TicketSpecial>>();
                    movie.Tickets = tickets;
            }
            return result;
            }
    }
    
  3. Регистрация MyJsonInputFormatter

    services.AddMvc(o =>
    {
            var serviceProvider = services.BuildServiceProvider();
            var customJsonInputFormatter = new MyJsonInputFormatter(
                            serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<MyJsonInputFormatter>(),
                            serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value.SerializerSettings,
                            serviceProvider.GetRequiredService<ArrayPool<char>>(),
                            serviceProvider.GetRequiredService<ObjectPoolProvider>(),
                            o,
                            serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value
                    );
    
            o.InputFormatters.Insert(0, customJsonInputFormatter);
    })
    
  4. Запрос

            {
                    "IsSpecial": true,
                    "Tickets":  [
                                    {"SpecialProp1": "Mumbai Test"}
                            ]
            }
    
0 голосов
/ 14 октября 2019

Измените «Isspecial» на «isSpecial», то же самое с другим свойством.

Другая проблема заключается в том, что вы проверяете «IsSpecial» в конструкторе, и в настоящее время он все равно должен иметь значение false.

Ура,

...