.net 4.5 Controller:参数polymorphism和自定义Json反序列化

问题描述 投票:0回答:1

我有一个API,我有一个同步控制器。该Controller具有唯一的动作功能:ActionRequest

public IHttpActionResult ActionRequest([FromBody]ActionRequestDto model)
{
    //EXAMPLE OF PASSING AND ARTICLE IN OBJECT THREW POST METHOD
    ArticleDto article = null;
    if(model.ActionType == "Article"){
        article = (ArticleDto)model.Object; //Problem ==> model.Object looses all articles information and cannot be cast to article
    }
}

此功能应该像路由器一样工作。它读取操作请求并调用适当的存储库。

ActionRequest对象具有以下结构:

public class ActionRequestDto
{
    public string ActionType { get; set; }
    public string ObjectType { get; set; }
    public bool Transmited { get; set; } = false;
    public DateTime CreationDate { get; set; }
    public int RequestNumber { get; set; }
    public string Reference { get; set; }
    public BaseDto Object { get; set; }// this is where the data is passed.
                   //it can be any type extending from BaseDto (ArticleDto, CustomerDto... )
}

我需要获取最终对象不仅是控制器中的基础对象,所以我可以将它传递给服务。

如何更改反序列化行为但仅适用于此操作或至少为此控制器?

c# .net controller json.net json-deserialization
1个回答
0
投票

大家早上好。

我受到这个问题的启发:Automatically deserialize to string-like class in Web.API controller

所以我在这做了什么。

  1. 创建一个自定义Json转换器类 public class BaseDtoJsonConvertor : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var actionRequestDto = (ActionRequestDto)value; writer.WriteStartObject(); writer.WritePropertyName("ActionRequestDto"); serializer.Serialize(writer, actionRequestDto.ToString()); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // Variables to be set along with sensing variables ActionRequestDto actionRequestDto = new ActionRequestDto(); // Read the properties while (reader.Read()) { if (reader.TokenType != JsonToken.PropertyName) { break; } var propertyName = (string)reader.Value; if (!reader.Read()) { continue; } // Set the group if (propertyName.Equals("object", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.Object = JsonSerializerBaseObjectFactory.DeserializeObject(actionRequestDto.ObjectType, reader, serializer); } if (propertyName.Equals("ActionType", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.ActionType = serializer.Deserialize<string>(reader); } if (propertyName.Equals("ObjectType", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.ObjectType = serializer.Deserialize<string>(reader); } if (propertyName.Equals("Transmited", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.Transmited = serializer.Deserialize<bool>(reader); } if (propertyName.Equals("CreationDate", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.CreationDate = serializer.Deserialize<DateTime>(reader); } if (propertyName.Equals("RequestNumber", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.RequestNumber = serializer.Deserialize<int>(reader); } if (propertyName.Equals("Reference", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.Reference = serializer.Deserialize<string>(reader); } } return actionRequestDto; } public override bool CanConvert(Type objectType) { return objectType == typeof(ActionRequestDto); } }
  2. 创建工厂类以返回所需的对象类型 class JsonSerializerBaseObjectFactory { public enum Types { Article, Basket, Customer, WishList, User, Tarif, Store, Stock, ShippingTaxe, Seller, SalesDocument, Promotion, Payment, InventoryTransaction, Inventory, Family, Etablissement, Dimension, Depot, CreditCard, Country, Commande, Category, Cashier, AvailableQuantity, ArticleRequest }; public static BaseDto DeserializeObject(string type, JsonReader reader, JsonSerializer serializer) { Types typeRes; if (Enum.TryParse(type, out typeRes)) { switch (typeRes) { case Types.Article: return serializer.Deserialize<ArticleDto>(reader); case Types.Basket: return serializer.Deserialize<BasketDto>(reader); case Types.Customer: return serializer.Deserialize<CustomerDto>(reader); default: return serializer.Deserialize<BaseDto>(reader); } } return serializer.Deserialize<BaseDto>(reader); } }
  3. 最后在StartUp类中声明Custom JsonConverter qazxsw poi

就这样。任何时候我收到一个Actionrequest对象类型,它被反序列化抛出我的自定义jsonConvertor。

© www.soinside.com 2019 - 2024. All rights reserved.