0

今日の MVC4 で使用されている XML シリアライザーと Json シリアライザーの間には、かなり厄介な違いがあることがわかりました。

次のようなオブジェクトを返そうとしました:

public class Person
{
  public string FirstName {get;set;}
  public string LastName {get;set;}
  public string FullName{ get{ return FirstName + " " + LastName }}
}

クライアントが結果として json を要求すると、 が取得さFirstNameれ、期待される値が返されます。LastNameFullName

ただし、クライアントが XML データを要求すると、取得できるのはFirstNameとだけですLastName

これは、クライアントが要求する形式に応じて異なるデータを取得することを意味するため、私の意見では非常に悪いと思います。

Jsonシリアライザーのドキュメントには、デフォルトで読み取り専用プロパティが含まれ、Xmlシリアライザーではデフォルトで除外されていると記載されているため、これは意図的なものと思われます。

私の質問は次のとおりです。MVC4 で使用される Xml シリアライザーを変更して、デフォルトで読み取り専用を含めるにはどうすればよいでしょうか。DataContractクラスに属性を追加し、クラスの各プロパティに属性を追加すると、読み取り専用変数も返されるため、管理できることはわかっていますがDataMember、実際にはそうしたくありません。

4

2 に答える 2

0

まず、次の記事をお勧めします。

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_readonly

使用するシリアライザーを MVC に指示する方法を含む、WebAPI/MVC でのシリアライゼーションの優れた概要を提供するため (読み取り専用の問題を回避するために独自の実装を決定した場合)

ここで、既定のシリアライザー (DataContract または Xml) を使用する場合、残念ながら、読み取り専用プロパティを自動的にシリアル化するように指示することはできません。これは設計によるものです。考えてみると、ある種の意味があります。XMLシリアライゼーションの典型的なユースケースは

  • タイプ A をシリアライズする
  • ネットワーク経由で送信/ディスクに保存
  • 将来のある時点で読み返します
  • クラス A のインスタンスに逆シリアル化する

これは、伝統的に (このデータを HTTP 経由で弱い型付けのブラウザー ベースの言語に送信するという概念が生まれる前に)、読み取り専用プロパティをシリアル化する意味がほとんどまたはまったくないためだと想像できます。フィールドが読み取り専用であるため、元の型に逆シリアル化できませんでした!

もちろん、最近では、これらが必要になることは非常に理にかなっています。JSON シリアライザーの関係者は、JSON のデフォルトで読み取り専用プロパティを含めることを決定したときに、これを念頭に置いていたと確信しています。厳密に型指定されたインスタンスへのシリアル化ではなく、動的に型指定された Java スクリプト オブジェクトへのシリアル化です。

すなわち与えられた

 public class Foo
    {
        public int Bar { get; set; }
        public string BarName { get { return "This is Bar# " + Bar; } }
    }

デフォルトで、Xml または DataContract Serializer がこれを生成したとします。

   <Foo>
     <Bar>10</Bar>
     <BarName>This is Bar# 10</BarName>
   </Foo>

次のコードはどのように機能すると思いますか?

 var xs = new XmlSerializer(typeof(Foo));
 var y = xs.Deserialize(new StreamReader(@"C:\foo.xml")) as Foo;

BarName読み取り専用プロパティである例外をスローせずに?

設定不可能なプロパティの要点は、getter戻り値を構成する条件が呼び出し元には不明 (つまり、プライベート) であるため、シリアル化できないことです...

したがって、DataContractデフォルトDataMembersの動作をオーバーライドすることができます。

于 2013-10-01T13:41:37.163 に答える