.net 4.5 控制器:参数多态和自定义 Json 反序列化

.net 4.5 Controller : Parameters polymorphism and custom Json Deserialization

我有一个 API,其中有一个同步控制器。 这个控制器只有一个动作函数: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... )
}

我需要获取最终对象,而不仅仅是控制器中的基础对象,这样我才能将它传递给服务。

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

大家早上好。

我被这个问题启发了:

这就是我所做的。

  1. 创建自定义 Json 转换器 class

    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到return需要的对象类型

    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 中 Class Deglare the Custom JsonConvertor

        var config = GlobalConfiguration.Configuration;
        var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
        jsonSettings.Converters.Add(new BaseDtoJsonConvertor());
    

仅此而已。每当我收到 Actionrequest 对象类型时,它都会反序列化并抛出我的自定义 jsonConvertor。