4

ASP.NET MVC アプリケーションで Linq to Sql と EF の両方を試しています。EF に切り替えた後、XML/JSON シリアライゼーションの出力に余分な問題があることに気付きました。

XML:

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <EntityKey>
    <EntitySetName>Persons</EntitySetName>
    <EntityContainerName>PersonEntities</EntityContainerName>
    <EntityKeyValues>
      <EntityKeyMember>
        <Key>Id</Key>
        <Value xsi:type="xsd:int">1</Value>
      </EntityKeyMember>
    </EntityKeyValues>
  </EntityKey>
  <Id>1</Id>
  <Name>John</Name>
</Test>

JSON:

{"Id":1,"Name":"John","EntityState":2,"EntityKey"{"EntitySetName":"Persons","EntityContainerName":"PersonEntities","EntityKeyValues":[{"Key":"Id","Value":1}],"IsTemporary":false}}

代わりに、出力を次のようにしたいだけです。

{"Id":1, "Name":"John"}

オブジェクトを取得するための私の EF クエリは次のとおりです。

Tests.First(t => t.Id == testId);
4

3 に答える 3

8

次のように、JSON の結果をコントローラーで整形できます。

public JsonResult Person(int id)
{
  var person = PersonRepository.FindByID(id);
  var result = new { Id = person.Id, Name = person.Name };
  return Json(result);
}

これにより、シリアル化された DTO が必要な値のみを含むように制限されます。

編集:コメントの質問に対する部分的な回答として。プロパティをマップできる、より単純な PersonViewModel クラス (DTO) を作成できます。John Saunders が回答で述べたように、Automapper は EF Person インスタンスからのプロパティ値のコピーを簡素化する優れた方法です。

変更された Action メソッドは次のようになります。

public JsonResult Person(int id)
{
  var person = PersonRepository.FindByID(id);
  var dto = Mapper.Map<Person, PersonViewModel>(person);
  return Json(dto);
}

私が考えることができる他の唯一のオプションは、リフレクションを使用して Person エンティティの DataMemberAttributes を変更し、EntityKey プロパティを抑制することです。

于 2009-04-04T09:04:01.790 に答える
1

これまでのところ、私が見つけた最良の手法はコード生成です。Service Factoryを使用していた 1 つのプロジェクトでこれを行いましたが、 T4 Text テンプレートを直接使用して「手動で」同じことを行うことができます。

また、AutoMapperにも注目してください。まだ新しい技術であると考えるほど新しいものですが、すぐに登場することを願っています!

于 2009-04-04T11:42:22.470 に答える