5

我在 WCF 中有一个 Web 服务,其操作需要 JSON 格式的请求和响应。我知道我可以只编写带有我想用 JSON 表示的属性的 C# 对象,但我的问题是 JSON 参数可能会改变。例如,我的方法合同如下:

    [WebInvoke(Method = "PUT", 
        UriTemplate = "users", 
        RequestFormat = WebMessageFormat.Json, 
        ResponseFormat = WebMessageFormat.Json)]
    [OperationContract]
    Response PutUserAccount(User user);

User 的参数可能包含任意数量的参数,因此 User 的实例有时可能是:

{
    "Name" : "John",
    "LastName" : "Doe",
    "Email" : "jdoe@gmail.com",
    "Username" : "jdoe",
    "Gender" : "M"
    "Phone" : "9999999"
}

甚至:

{
    "Name" : "John",
    "LastName" : "Doe",
    "Email" : "jdoe@gmail.com",
    "Username" : "jdoe",
    "FavoriteColor" : "Blue"
}

让一个具有可变数量属性的对象来表示 JSON 文档的最佳方法是什么?

编辑这个类允许我有一个灵活的 JSON 表示,因为我不能使用JObjectWCF (我应该把它作为答案发布吗?):

using System; 
using System.Collections.Generic; 
using System.Runtime.Serialization;

namespace MyNamespace {
    [Serializable]
    public class Data : ISerializable
    {
        internal Dictionary<string, object> Attributes { get; set; }

        public Data()
        {
            Attributes = new Dictionary<string, object>();
        }

        public Data(Dictionary<string, object> data)
        {
            Attributes = data;
        }

        protected Data(SerializationInfo info, StreamingContext context)
            : this()
        {
            SerializationInfoEnumerator e = info.GetEnumerator();
            while (e.MoveNext())
            {
                Attributes[e.Name] = e.Value;
            }
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            foreach (string key in Attributes.Keys)
            {
                info.AddValue(key, Attributes[key]);
            }
        }

        public void Add(string key, object value)
        {
            Attributes.Add(key, value);
        }

        public object this[string index]
        {
            set { Attributes[index] = value; }
            get
            {
                if (Attributes.ContainsKey(index))
                    return Attributes[index];
                else
                    return null;
            }
        }
    } 

}

4

2 回答 2

2

您可以使用Json.NETJObject中的类。您可以将 json 解析为属性并对其进行操作。不仅仅是一本字典。JObjectJObject

于 2013-09-17T21:13:07.770 回答
1

如果您想使用其他 JSON 类型作为属性的值,甚至是子对象,我经常使用的一种方法是[DataContract]为传入对象定义 a - 在您的情况下,User- 并将DataMemberAttributes 设置为类似于以下:

[DataContract]
public class User
{
    // IsRequired and EmitDefaultValue default to 'true',
    // if not set explicitly
    [DataMember]
    public string Name { get; set; }

    [DataMember(IsRequired=false,EmitDefaultValue=false)]
    public Foo MyFoo { get; set; }
    ...
}

这强制执行特定的User合同,但允许消费者选择要包含的可选字段。在这个片段中,两者

{ "name":"John" }

{ "name":"Earl", "myFoo":{ "bar":"baz" } }

是有效的请求实体。在前一种情况下,您的user参数将其MyFoo属性设置为null

这将不允许“不可预见的”属性,因此您必须决定拥有这样一个松散定义的 API 合同在您的情况下是否重要。

混合方法可能会定义一个可选Dictionary<string,string> ExtendedProperties属性,消费者可以使用任何用户定义的数据填充该属性,这些数据尚未在合同中定义。

于 2013-09-18T13:25:24.493 回答