2

WebAPIコントローラでDTOを使用する方法がちょっと混乱しています。 Entity Frameworkのデータベースの最初のコンセプトを使用しています。以下のエンティティデータモデルが生成されました:WebAPIのコントローラでDTOを操作するには?

//Generated class by EDM: 
public partial class Address 
    { 
     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
     public Address() 
     { 
      this.Member = new HashSet<Member>(); 
     } 

     public int Id { get; set; } 
     public string Street { get; set; } 
     public Nullable<short> Street_Number { get; set; } 
     public Nullable<decimal> Zip { get; set; } 
     public string City { get; set; } 
     public string Country { get; set; } 

     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
     public virtual ICollection<Member> Member { get; set; } 
    } 

を私はEDMデータモデルを変更する必要があるたびに再生成され、データ注釈が失われているためAddressDTOを定義する必要があり、データ注釈を使用するには。

public class AddressDTO 
    { 
     public int Id { get; set; } 
     [Required] 
     [StringLength(100,ErrorMessage="The max. length of the street name is 100 characters.")] 
     public string Street { get; set; } 
     public Nullable<short> Street_Number { get; set; } 
     [Required] 
     public Nullable<decimal> Zip { get; set; } 
     [Required] 
     [RegularExpression(@"[a-z,A-Z]",ErrorMessage="Only characters are allowed.")] 
     public string City { get; set; } 
     [Required] 
     public string Country { get; set; } 
    } 

そして、コントローラは、以下のコードのようになります:

だから次、私はAddressDTOを定義した私は、ブラウザで結果を表示するためにRestAPIを始めているとき

[RoutePrefix("api/address")] 
    public class AddressController : ApiController 
    { 
     private PersonEntities db = new PersonEntities(); 

     // GET: api/Address 
     [HttpGet] 
     [ResponseType(typeof(AddressDTO))] 
     public async Task<IHttpActionResult> GetAll() 
     { 
      var addressList = await db.Address.ToListAsync(); 

      return Ok(addressList); 
     } 
    } 

[ 
    { 
     "Member": [ ], 
     "Id": 1, 
     "Street": "Example Street", 
     "Street_Number": 1, 
     "Zip": 12345.0, 
     "City": "New York", 
     "Country": "USA" 
    },... 
] 

しかし、私は次のような結果が必要です編集結果:

[ 
     { 
      "Street": "Example Street", 
      "Street_Number": 1, 
      "Zip": 12345.0, 
      "City": "New York", 
      "Country": "USA" 
     },... 
    ] 

私はそれをどのように解決できますか?

+0

APIに公開するプロパティのみを持つラッパークラスを作成 – Fabio

+0

いくつかのデータ注釈属性を使用するために別のモデルを作成する必要はありません。 [MetadataTypeAttribute](https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.metadatatype属性(v = vs.110).aspx) –

+0

@RezaAghaeiを使用して簡単に使用できますコード? – yuro

答えて

4

新しい編集は、AddressDTOモデルでIdMemberのプロパティが必要ないことを意味します。 List<Address>を返している間、結果はList<AddressDTO>になります。

だからAddressDTOから未使用のプロパティを削除してから新しいAddressDTOを選択し、プロパティを設定することで、結果を形作る:

var result = db.Address.Select(x=> new AddressDTO() 
            { 
             Street = x.Id, 
             Street_Number = x.Street_Number, 
             City = x.City, 
             Country = x.Country 
            }).ToListAsync(); 

あなたは、LINQを短くしたい場合は、AddressDTOに、このようなコンストラクタを追加することができます。

コントローラに続い
public AddressDTO(Address x) 
{ 
    Street = x.Id; 
    Street_Number = x.Street_Number; 
    City = x.City; 
    Country = x.Country; 
} 

var result = db.Address.Select(x=> new AddressDTO(x)).ToListAsync(); 

大規模なプロジェクトでも、答えに記載されているように、自動マッパーのようなオブジェクトマッパーに依存することができます。

+0

別の部分クラス 'Address'を作成する必要がありますか? – yuro

+0

あなたが答えについて質問がある場合、またはそれが役に立つとわかった場合は教えてください:) –

+0

ご協力いただきありがとうございます!私は後で試して、あなたにフィードバックを与えるでしょう:) – yuro

2

Automapperのようなライブラリを使用してニーズを処理します。

次に、あなただけの、たとえばこれに次の行を変更する必要があります

var addressList = await Mapper.Map<IList<AddressDto>>(db.Address.ToListAsync()); 

これは、あなたが変換されるかを制御することができますかそこらのためにメンバーを渡すことがないではないAddressDtoリストにあなたのアドレスリストを変換しますあなたの見解への例。 Automapperは、フィールド名が同じであれば、変換するものを自動的に認識します。

関連する問題