简体   繁体   中英

C# - Model is always getting its default values

I have an ASP.Net Core 2.1 application.

Below is my 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>();
        }
    }}}

Tickets (Base Class)

 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 Controller

public class MovieController : ControllerBase
{

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

Postman (HTTPPost Req payload Content-Type = application/json )

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

When I call the above API via Postman & debug at Movie ctor, it always catches the value of IsSpecial = false & all fields default value (ex. for string type null)

Thanks!

Change "Isspecial" to "isSpecial", same with the other property.

Another problem is that you're checking "IsSpecial" in the constructor and at this time it should be false anyway.

There are two issues in your current implementation. First, your request json is invalid for nested properties and json deserializer would not deserialize for you with TicketsSpecial .

Follow steps below for a workaround:

  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. Register 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. Request

     { "IsSpecial": true, "Tickets": [ {"SpecialProp1": "Mumbai Test"} ] }

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