在 .NET POST API 请求的正文中接收两个不同的可能类型对象

Receiving two different possible type objects in the body of a .NET POST API request

提问人:Nono-Man 提问时间:9/3/2023 最后编辑:Brian Tompsett - 汤莱恩Nono-Man 更新时间:10/8/2023 访问量:42

问:

我有这两类:

public class FieldStructure
    {
        public FieldStructure(string name, string type)
        {
                Name = name;
                Type = type;
                NameAsProperty = name.ToLower().Replace(" ", "_");
            
        }

        public FieldStructure() { }

        public string Name { get; set; } = string.Empty;
        public string NameAsProperty { get; set; } = string.Empty;
        public string Type { get; set; } = string.Empty;

    }

    public class FieldStructureRelation : FieldStructure
    {
        public FieldStructureRelation(FieldStructure fieldStructure, string appRelationId, string appRelationName) 
            : base(fieldStructure.Name, fieldStructure.Type)
        {
            this.AppRelationName = appRelationName;
            this.AppRelationId = appRelationId;
        }

        public FieldStructureRelation() { }

        public string AppRelationId { get; set; } = string.Empty;
        public string AppRelationName { get; set; } = string.Empty;
    }

而这个控制器:

[HttpPost("{workspaceId}/add")]
        public async Task<IActionResult> CreateApp([FromBody] AppDTOCreate request, string workspaceId)
        {
            if (request == null) { return BadRequest(); }
             
            //App app = new App() { AppName = request.AppName, Fields = request.Fields};
            //await _appServices.InsertApp(app, workspaceId);
            return Created("Created", true);
        }

这是我应该收到的对象:

public class AppDTOCreate
    {
        public string AppName { get; set; } = string.Empty;
        public List<FieldStructure> Fields { get; set; } = new List<FieldStructure>();
    }

所以,基本上,我想要的只是能够接收一个 JSON 请求,其中包含一个 和 的列表。我以为这就像做我已经做过的事情一样容易,但是每当我收到请求时,我所看到的代码都是,每当我到达 时,它都会擦除 和 字段,因此它仍然是 .AppDTOCreateFieldStructuresFieldStructureRelationsFieldStructuresFieldStructureRelationAppRelationNameAppRelationIdFieldStructure

这是我用作示例的 JSON:

{
    "AppName":"Prueba",
    "Fields": [
        {
            "Name": "Name",
            "Type": "text"
        },
        {
            "Name": "Active",
            "Type": "boolean"
        },
        {
            "Name": "Total Sales",
            "Type": "decimal"
        },
        {
            "Name": "Cliente",
            "Type": "itemRelation",
            "AppRelationId": "appIdxxxxxx",
            "AppRelationName": "AppNameABC"
        }
    ]
}

如果有人能帮我弄清楚这里出了什么问题,我将不胜感激!

C# asp.net JSON .NET

评论

0赞 jdweng 9/3/2023
请参阅以下和上面的段落:learn.microsoft.com/en-us/aspnet/core/web-api/...正文为 IActionResult,类型为 IResult。
0赞 vernou 9/3/2023
这是 asp.net 核心?
0赞 Nono-Man 9/3/2023
@vernou是的
0赞 darrenleeyx 9/7/2023
为什么不将您的属性定义为 as 而不是 ?FieldsAppDtoCreateList<FieldStructureRelation>List<FieldStructure>

答:

1赞 Serge 9/4/2023 #1

您可以使用此转换器

    AppDTOCreate data = JsonConvert.DeserializeObject<AppDTOCreate>(json);
    
   //test
    data.Fields[2].GetType().ToString(); // "FieldStructure"
    data.Fields[3].GetType().ToString(); // "FieldStructureRelation"

public class DataPropertyConverter : JsonConverter<List<FieldStructure>>
{
    public override List<FieldStructure> ReadJson(JsonReader reader, Type objectType, List<FieldStructure> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jArray = JArray.Load(reader);
        
        return jArray.Select(jObj=> (FieldStructure) jObj.ToObject(
                              Type.GetType((string)jObj["Type"] == "itemRelation"
                              ? nameof(FieldStructureRelation)
                              : nameof(FieldStructure))))
                              .ToList();
    }

    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, List<FieldStructure> value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

修复类

public class AppDTOCreate
{
    public string AppName { get; set; }

    [JsonConverter(typeof(DataPropertyConverter))]
    public List<FieldStructure> Fields { get; set; }
}