質問

Can I turn data contract attributes off and on dynamically? Essentially, I'd like two data contracts, one between the 3rd party and my app, and one between my app and my client - without having to manage two DTO classes. For example, consider MyDTO:

[DataContract]
public class MyDTO
{
    [DataMember(Name = "Lame/3rdParty/Inbound/Key")]
    public string MyCoolOutboundKey { get; set; }
}

I'd like to deserialize the DTO with ServiceStack.Text:

MyDTO dto = "{\"Lame/3rdParty/Inbound/Key\":\"CoolValue\"}".FromJson<MyDTO>();

But, I'd like to serialize it so that this Assertion would be true:

Assert.AreEqual("{\"MyCoolOutboundKey\":\"CoolValue\"}",dto.ToJson());

The actual object in question has over hundred properties, so I'm hoping to avoid having to create a second class just to allow for outbound serialization.

役に立ちましたか?

解決 2

OK - it's pretty well established that you cannot change attributes at runtime.

An alternative that would create an end-run around the entire issue, would be to pre-process the incoming json, replacing the keys according to a map, i.e.:

Dictionary<String,String> map = new Dictionary<String,String>();
map.Add("Lame/3rdParty/Inbound/Key","MyCoolOutboundKey");

JsonObject result = new JsonObject();
JsonObject obj = jsonObject.Parse("{\"Lame/3rdParty/Inbound/Key\":\"CoolValue\"}");

foreach (var entry in obj)
{
    entry.Key = map[entry.Key];
    result[entry.Key] = entry.Value;
}

Assert.AreEqual("{\"MyCoolOutboundKey\":\"CoolValue\"}",result.ToJson());

This way the only data contract I'd require would be the one between my app and my app's clients.

他のヒント

So, there is nothing wrong with your approach, but I think you are underestimating the power of JsonObject, it's kinda like LINQ to JSON.

I used it to get geo data from Google Maps and map it to a nice little DTO:

var jsonObj = jsonFromGoogleMaps.FromJson<JsonObject>();

return (
    from x in jsonObject.Get<JsonArrayObjects>("results")
    let geo = x.Get("geometry")
    let loc = geo.Get("location")
    return new Coords
    {
        Lat = x.Get<decimal>("lat"),
        Lng = x.Get<decimal>("lng"),
    }
).FirstOrDefault();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top