5

JSON 形式の要求と応答を必要とする操作を行う WCF の Web サービスがあります。JSON で表現したいプロパティを持つ C# オブジェクトを記述できることはわかっていますが、JSON パラメーターが変更される可能性があるという問題があります。たとえば、私のメソッド コントラクトは次のとおりです。

    [WebInvoke(Method = "PUT", 
        UriTemplate = "users", 
        RequestFormat = WebMessageFormat.Json, 
        ResponseFormat = WebMessageFormat.Json)]
    [OperationContract]
    Response PutUserAccount(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 ドキュメントを表す可変数のプロパティを持つオブジェクトを作成する最善の方法は何ですか?

編集このクラスでは、WCF で a を使用できないため、柔軟な JSON 表現を使用できましたJObject(これを回答として投稿する必要がありますか?):

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

1

プロパティや子オブジェクトの値として他の JSON タイプを使用したい場合、私がよく使用するアプローチの 1 つは[DataContract]、受信オブジェクトのを定義することです。以下:UserDataMemberAttribute

[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 に答える