How to serialize class type but not the namespace to a Json string using DataContractJsonSerializer

后端 未结 6 1579
太阳男子
太阳男子 2021-02-05 21:17

I\'m trying to serialize a class hierarchy to a Json string using DataContractJsonSerializer, in a WCF service. the default behaviour for serializing a derived clas

6条回答
  •  佛祖请我去吃肉
    2021-02-05 21:36

    @Cheeso wrote:

    To avoid this, you'd maybe need to return a string from the WCF method, perform the serialization yourself, and post-process the emitted JSON.

    Here's how I implemented that post-processing. I thought I'd post it here JIC it might help someone else.

    First some boilerplate to show how I generate my JSON string:

    // Instantiate & populate the object to be serialized to JSON
    SomeClass xyz = new SomeClass();
    ... populate it ...
    
    // Now serialize it
    DataContractJsonSerializer ser = new DataContractJsonSerializer(xyz.GetType()); // Note xyz.GetType()
    ... serialize the object to json, many steps omitted here for brevity ...
    string json = sr.ReadToEnd();
    

    (Serialization is based on examples from https://msdn.microsoft.com/en-us/library/bb412179%28v=vs.110%29.aspx )

    Note that the [DataContract] on SomeClass does not include the (name="") syntax that I've seen suggested elsewhere. That only removes the namespace from the __type at the cost of needing to adorn ALL your DataContract attrs, which clutters your code. Instead, my post-processor handles the assembly name in the __type field.

    And now the string json contains the JSON text, but unfortunately includes all that "__type" junk that you don't want but can't suppress.

    So here's my post-processing code that removes it:

    // This strips out that unsuppressable __type clutter generated by the KnownType attributes
    Attribute[] attrs = Attribute.GetCustomAttributes(xyz.GetType());
    foreach (Attribute attr in attrs)
    {
        if (attr is KnownTypeAttribute)
        {
            KnownTypeAttribute a = (KnownTypeAttribute)attr;
            string find = "\"__type\":\"" + a.Type.ReflectedType.Name + "." + a.Type.Name + ":#" + a.Type.Namespace + "\",";
            json = json.Replace(find, "");
        }
    }
    

    This makes a few assumptions, most notably that the __type field ends with a comma, which assumes that another field follows it, though (a) my objects always have at least 1 field and (b) I've found that the __type field is always 1st in the serialized object's output.

    As always, you may have to adjust something to your situation, but I find it works well for mine.

提交回复
热议问题