【问题标题】:how to deserialize json array in asp.net core api in post method?如何在 post 方法中反序列化 asp.net core api 中的 json 数组?
【发布时间】:2021-01-06 07:39:31
【问题描述】:

我该如何解决这个问题(序列化/反序列化 JSON 数组并从 sql server 存储和读取)? 谢谢

我创建了连接到 Angular 项目的 asp.net 核心 api,当我想要发布包含 json 数组(成分)的 json 时出现问题:

 { "RecepieName": "3222",
"Ingredient": [ { "ingredientName": "43243", "value": "33", "measure": "" },
{ "ingredientName": "565" , "value": "3", "measure": "" }],
"CookingTime": 3,
"Level": "advance", 
"ServingPerson": 3, 
"RecepieAbstration": "good food",
"RecepieText": "",
"CreateDate": "2021-01-04T12:37:51.948",
"ModifiedDate": "2021-01-04T12:37:51.948" }

当我使用邮递员进行测试时,我遇到了这个错误:

postman error

您可以在控制器中看到我的模型、dto 和操作帖子:

型号:

  public class Recepie
    {
    [Key]
    public int ID { get; set; }
    [Required]
    public string RecepieName { get; set; }
    [Required]
    public string Ingredient { get; set; }   // include ingredientName / value / measure array
    [Required]
    public int CookingTime { get; set; }
    [Required]
    public string Level { get; set; }
    [Required]
    public int ServingPerson { get; set; }
    [Required]
    public string RecepieAbstration { get; set; }
    [Required]
    public string RecepieText { get; set; }
    [Required]
    public string NutritionalInformation { get; set; }
    [Required]
    public string Tags { get; set; }
  
    public DateTime CreateDate { get; set; }

    public DateTime ModifiedDate { get; set; }
    }

DTO : RecepieCreateDto

    public class RecepieCreateDto
{

    public string RecepieName { get; set; }

    //public int MentorID { get; set; }

    public string Ingredient { get; set; }


    public int CookingTime { get; set; }

    public string Level { get; set; }

    public int ServingPerson { get; set; }

    public string RecepieAbstration { get; set; }

    public string RecepieText { get; set; }

    public string Tags { get; set; }

    public DateTime CreateDate { get; set; }

    public DateTime ModifiedDate { get; set; }
}

动作帖:

        //Post api/recepie
    [HttpPost]
    public ActionResult <RecepieReadDto> CreateRecepie(RecepieCreateDto recepieCreateDto)
    {
        var recepieModel = _mapper.Map<Recepie>(recepieCreateDto);
        _repository.CreateRecepieObject(recepieModel);
        _repository.SaveChange();
        var recepieReadDto = _mapper.Map<RecepieReadDto>(recepieModel);
        return CreatedAtRoute(nameof(GetRecepieByID), new { Id = recepieReadDto.ID }, recepieReadDto);
        // return Ok(recepieModel);
    }

【问题讨论】:

    标签: c# arrays json


    【解决方案1】:
    you can implement solution like below code ;
    1 : Create View model For input Api;
    
      
    
     public class RecepieCreateViewModel
            {
        
                public string RecepieName { get; set; }
        
                public List<Ingredient> Ingredient { get; set; }
        
                public int CookingTime { get; set; }
        
                public string Level { get; set; }
        
                public int ServingPerson { get; set; }
        
                public string RecepieAbstration { get; set; }
        
                public string RecepieText { get; set; }
        
                public string NutritionalInformation { get; set; }
        
                public string Tags { get; set; }
        
                public DateTime CreateDate { get; set; }
        
                public DateTime ModifiedDate { get; set; }
            }
    
       
    
     public class Ingredient
        {
            public string ingredientName { get; set; }
            public string value { get; set; }
            public string measure { get; set; }
        }
    
    
    2 : Create Dto Model
    
    public class RecepieCreateDto
    {
    
        public string RecepieName { get; set; }
    
        public string Ingredient { get; set; }
    
        public int CookingTime { get; set; }
    
        public string Level { get; set; }
    
        public int ServingPerson { get; set; }
    
        public string RecepieAbstration { get; set; }
    
        public string RecepieText { get; set; }
    
        public string NutritionalInformation { get; set; }
    
        public string Tags { get; set; }
    
        public DateTime CreateDate { get; set; }
    
        public DateTime ModifiedDate { get; set; }
    
    }
    
    3 : Cast Ingredient Model ToJson Object In Api And Create New RecepieCreateDto Like Below Code
    
      var result=Newtonsoft.Json.JsonConvert.SerializeObject(recepieCreateDto.Ingredient);
            
    
       RecepieCreateDto readDto = new RecepieCreateDto
        {
            CookingTime = recepieCreateDto.CookingTime,
            Level = recepieCreateDto.Level ,
            ModifiedDate = recepieCreateDto.ModifiedDate ,
            NutritionalInformation = recepieCreateDto.NutritionalInformation ,
            RecepieAbstration = recepieCreateDto.RecepieAbstration ,
            RecepieName = recepieCreateDto.RecepieName ,
            RecepieText = recepieCreateDto.RecepieText ,
            ServingPerson = recepieCreateDto.ServingPerson ,
            CreateDate = recepieCreateDto.CreateDate ,
            Tags = recepieCreateDto.Tags ,
            Ingredient=result,
    
        };
    

    【讨论】:

      【解决方案2】:

      在 RecepieCreateDto 类成分是一个字符串,但在您的请求 json 成分是一个数组。 所以将 RecepieCreateD 更改为类或请求 json。

      "[{\"ingredientName\": \"43243\", \"value\": \"33\", \"measure\": \"\" },{ \"ingredientName\": \"565\" , \"value\": \"3\", \"measure\": \"\" }]"
      

          public IList<Ingredient> Ingredient { get; set; }
      

      【讨论】:

      • 我做了你的建议,但我发生了这个错误:System.InvalidOperationException:'实体类型'Ingredient'需要定义一个主键。如果您打算使用无密钥实体类型,请在“OnModelCreating”中调用“HasNoKey”。
      • 在您的 DbContext 类的 OnModelCreating 方法中,您执行以下操作:modelBuilder .Entity(builder => { builder.HasNoKey(); });
      • 对不起,我做到了,并得到了新的错误:? '无法确定'List'类型的导航'Recepie.Ingredient'所代表的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。
      【解决方案3】:

      您需要为成分属性创建一个类。

      public class Ingredient {
          public string IngredientName { get; set; }
          public string Value { get; set; } // This might be an int, you can change this on your purpose.
          public string Measure { get; set; } // This might be an int, you can change this on your purpose.
      }
      

      看起来您发布的成分是一个集合类型,所以制作成分列表或任何其他集合类型都可以做到。

      public class RecepieCreateDto
      {
      
          public string RecepieName { get; set; }
      
          //public int MentorID { get; set; }
      
          public List<Ingredient> Ingredient { get; set; }
      
      
          public int CookingTime { get; set; }
      
          public string Level { get; set; }
      
          public int ServingPerson { get; set; }
      
          public string RecepieAbstration { get; set; }
      
          public string RecepieText { get; set; }
      
          public string Tags { get; set; }
      
          public DateTime CreateDate { get; set; }
      
          public DateTime ModifiedDate { get; set; }
      }
      

      在这些更改之后,您可能需要对您的 Recepie 模型进行类似的更改。

      【讨论】:

      • 我做了你的建议,但我发生了这个错误:System.InvalidOperationException:'实体类型'Ingredient'需要定义一个主键。如果您打算使用无密钥实体类型,请在“OnModelCreating”中调用“HasNoKey”。
      【解决方案4】:

      您正在为成分传递 array,但期望 string。请将成分更改为List&lt;Ingredient&gt;,其中成分是您的新对象,具有名称、值和范围。例如:

       public class Ingredient
      {
       [Key]
       int Id {get; set; }
       string IngredientName { get; set; }
       string Value { get; set; }
       string Measure { get; set; }
      }

      UPDATE:请分别更新DTO模型并在RecepieCreateDto

      中使用
       public class IngredientDTO
       {
       string IngredientName { get; set; }
       string Value { get; set; }
       string Measure { get; set; }
       }
      

      【讨论】:

      • 请查看微软文档link
      • 我做了你的建议,但我发生了这个错误:System.InvalidOperationException:'实体类型'Ingredient'需要定义一个主键。如果您打算使用无密钥实体类型,请在“OnModelCreating”中调用“HasNoKey”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-27
      • 2020-07-11
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      相关资源
      最近更新 更多