【问题标题】:C# - Model is always getting its default valuesC# - 模型总是得到它的默认值
【发布时间】:2020-11-17 12:43:16
【问题描述】:

我有一个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(子/派生类)

 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 请求负载Content-Type = application/json

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

当我通过 Postman 调用上述 API 并在 Movie ctor 上调试时,它总是会捕获 IsSpecial = false 的值和所有字段的默认值(例如字符串类型为 null)

谢谢!

【问题讨论】:

  • IsSpecial 在构造过程中始终为 false,您需要将其值传递给构造函数或更改属性的 setter 以构建集合。
  • 你发出的http请求是什么?
  • 显示你如何通过 Postman 调用它
  • 如果我是你,我不会费心创建模型类的层次结构,只需创建一个处理两种情况(标准和正常)的 Ticket 模型。
  • 与创建请求的方式无关,IsSpecial在执行if(IsSpecial)时还没有初始化

标签: c# asp.net-core-webapi asp.net-core-2.1 modelbinders


【解决方案1】:

您当前的实施中有两个问题。首先,您的请求 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"}
                            ]
            }
    

【讨论】:

    【解决方案2】:

    将“Isspecial”更改为“isSpecial”,与其他属性相同。

    另一个问题是你在构造函数中检查“IsSpecial”,此时它应该是假的。

    【讨论】:

      猜你喜欢
      • 2020-07-22
      • 1970-01-01
      • 2019-12-26
      • 2018-10-22
      • 2015-12-31
      • 2014-07-30
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多