Home > database >  Is it possible to set custom contract resolver for automatic json serialization in c#?
Is it possible to set custom contract resolver for automatic json serialization in c#?

Time:07-27

I Have an Azure function, which is triggered by http requests. In the function I get data from soap web service in xml format, which has different property names compared to the class that I created for storing that data. Because of that I specified JsonProperty Names for class properties, however I want my class to be serialized with class property names and not json property names. For that I created Custom Contract Resolver, but I don't know how to specify that contract resolver for automatic serializations (by this I mean when data is automatically serialized for http response).

my class:

public class WaybillHeader
{
    [JsonProperty(PropertyName = "ID")]
    public int Id { get; set; }

    [JsonProperty(PropertyName = "TYPE")]
    public int Type { get; set; }

    [JsonProperty(PropertyName = "CREATE_DATE")]
    public DateTime CreateDateTime { get; set; }

    [JsonProperty(PropertyName = "BUYER_TIN")]
    public string BuyerTin { get; set; } = default!;

    [JsonProperty(PropertyName = "BUYER_NAME")]
    public string BuyerName { get; set; } = default!;

    [JsonProperty(PropertyName = "START_ADDRESS")]
    public string StartAddress { get; set; } = default!;

    [JsonProperty(PropertyName = "END_ADDRESS")]
    public string EndAddress { get; set; } = default!;

    [JsonProperty(PropertyName = "DRIVER_TIN")]
    public string DriverTin { get; set; } = default!;

    [JsonProperty(PropertyName = "DRIVER_NAME")]
    public string DriverName { get; set; } = default!;

    [JsonProperty(PropertyName = "TRANSPORT_COAST")]
    public decimal TransportationCost { get; set; }

    [JsonProperty(PropertyName = "DELIVERY_DATE")]
    public DateTime DeliveryDateTime { get; set; }

    [JsonProperty(PropertyName = "STATUS")]
    public int Status { get; set; }

    [JsonProperty(PropertyName = "ACTIVATE_DATE")]
    public DateTime ActivationDateTime { get; set; }

    [JsonProperty(PropertyName = "FULL_AMOUNT")]
    public decimal FullAmount { get; set; }

    [JsonProperty(PropertyName = "CAR_NUMBER")]
    public string CarNumber { get; set; } = default!;

    [JsonProperty(PropertyName = "WAYBILL_NUMBER")]
    public string WaybillNumber { get; set; } = default!;

    [JsonProperty(PropertyName = "CLOSE_DATE")]
    public DateTime CloseDateTime { get; set; }

    [JsonProperty(PropertyName = "S_USER_ID")]
    public string ServiceUserId { get; set; }

    [JsonProperty(PropertyName = "BEGIN_DATE")]
    public DateTime BeginDateTime { get; set; }

    [JsonProperty(PropertyName = "IS_CONFIRMED")]
    [JsonConverter(typeof(StrToBoolConverter))]
    public bool IsConfirmed { get; set; }

    [JsonProperty(PropertyName = "INVOICE_ID")]
    public int InvoiceId { get; set; }

    [JsonProperty(PropertyName = "IS_CORRECTED")]
    [JsonConverter(typeof(StrToBoolConverter))]
    public bool IsCorrected { get; set; }

    [JsonProperty(PropertyName = "BUYER_ST")]
    public int BuyerStatus { get; set; }
}

Custom Contract Resolver:

public class CustomContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, 
    MemberSerialization memberSerialization)
    {
        var property = 
        base.CreateProperty(member,memberSerialization);

        property.PropertyName = member.Name;
    
        return property;
    }
}

Edit:

I have custom converter to turn "0" and "1" to bool values and what I tried (and it worked but I don't think it's a proper solution) is that I supplied CustomContractResolver to serializer in WriteJson like this:

public class StrToBoolConverter : JsonConverter<bool>
{
    public override void WriteJson(JsonWriter writer, bool value, 
    JsonSerializer serializer)
    {
        serializer.ContractResolver = new CustomContractResolver();
        writer.WriteValue(value);
    }

    public override bool ReadJson(JsonReader reader, Type objectType,             
    bool existingValue, bool hasExistingValue, JsonSerializer 
    serializer)
    {
        if (reader.Value == null)
            return false;

        if (reader.ValueType != typeof(string))
            return false;

        return reader.Value.ToString() switch
        {
            "0" => false,
            "1" => true,
            _ => false
        };
    }
}

this solution worked for every serialized WaybillHeader value except the first one

CodePudding user response:

I don´t know if I understand your request but i think yuo want to serialize to your class a response from a Azure application.


yourClass dats = new yourClass()

WebResponse response = "your call to azure APP"

...

using (Stream stream = response.GetResponseStream())
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(yourClass));
             dats = (yourClass)ser.ReadObject(stream);

        }
...

Regards

CodePudding user response:

I would remove all JsonProperty attributes from the c# properties and create a constructor for deserialization

public class WaybillHeader
{
    public int Id { get; set; }

    public int Type { get; set; }

    [JsonProperty(PropertyName = "CreateDateTime")] // You can remove it,
                                               // or give the name for serialization 
                                              // if you need a different one
    public DateTime CreateDateTime { get; set; }

    .....

     [Newtonsoft.Json.JsonConstructor]
    public class WaybillHeader(int ID, int TYPE, DateTime CREATE_DATE, ...)
   {
        Id=ID;
        Type=TYPE;
        CreateDateTime=CREATE_DATE;
        .....
    }
 
}
  • Related