2

初めての ASP.NET MVC4 Web API を作成しています。20 ほどのエンティティが既に作成され、Azure でホストされているデータベースがあり、Entity Framework を使用してデータベースを POCO クラスにリバース エンジニアリングしました。

彼らは最終的に次のようになりました。

public class Activity
{
    public Activity()
    {
        this.ActivityCategories = new List<ActivityCategory>();
        this.ActivityImages = new List<ActivityImage>();
        this.PerformedActivities = new List<PerformedActivity>();
        this.UserActivities = new List<UserActivity>();
    }

    public int ActivityID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public Nullable<int> Thumbnail { get; set; }
    public virtual Image Image { get; set; }
    public virtual ICollection<ActivityCategory> ActivityCategories { get; set; }
    public virtual ICollection<ActivityImage> ActivityImages { get; set; }
    public virtual ICollection<PerformedActivity> PerformedActivities { get; set; }
    public virtual ICollection<UserActivity> UserActivities { get; set; }
}

次に、次のようなアクションで ApiController 拡張クラスを作成しました。

    public IEnumerable<Activity> All()
    {
        return db.Activities.ToArray();
    }

そして、予想通り、非常に長い JSON 応答が返されました。JSON 応答には、Activity クラスで定義されたすべてが含まれていました。しかし、すべてを含めたくない場合はどうすればよいでしょうか? たとえば、UserActivities、PerformedActivities などを返したくありません。

基本的に、JSON は次のようになります。

[
    {
        "id":"32",
        "name":"this activity name",
        "description":"blah blah",
        "thumbnail":"http://mydomain.com/images/32/thumbnail.png",
        "images": [
            {
                "name":"this image",
                "url":"http://mydomain.com/images/32/1.png",
            },
            {
                "name":"cool image",
                "url":"http://mydomain.com/images/32/2.png",
            },
        ],
    },
    ...
]

(JSON の書式設定エラーは無視して、例をすばやく入力してください)

必ずしも同じプロパティ名を使用したくないことに注意してください。データを必要な形式に変換する効率的な方法はありますか?

最初に考えたのは、必要なプロパティのみを含む構造体の配列に各アクティビティをコピーすることです。よりエレガントなソリューションはありますか?

4

2 に答える 2

4

この場合、DTO オブジェクトが助けになります。DTO は消費者に十分なデータを提供するため、Web API を介して転送する必要があるデータを使用して DTO を定義します。場合によっては、EF からモデルを使用できますが、次のようになります。

  1. 通常、EF は内部で動的プロキシを生成して、遅延読み込みと変更の追跡をサポートします。Web API は POCO オブジェクトではなくプロキシをシリアル化するため、シリアル化の問題が発生する可能性があります。

  2. 不必要なデータを消費者に転送しすぎると、HTTP リクエストが重くなり、データ漏洩が明らかになります。

  3. 関心の分離に違反します。EF モデルがドメイン エンティティである場合、それらはデータ転送オブジェクトとして責任を負いません。

ActivityDtoサンプルでは、​​前述のように不要なプロパティを定義して削除できます。

public class ActivityDto
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Nullable<int> Thumbnail { get; set; }
    public virtual Image Image { get; set; }
}

public IEnumerable<Activity> All()
{
    return db.Activities.Select(a => new ActivityDto(){
        Name = a.Name,
        Description = a.Description,
        Thumbnail = a.Thumbnail
        // More properties if you need

    }).ToArray();
}

DTO を EF モデルに自動的にマップするツールを探したい場合は、AutoMapperがここにあります。

于 2012-09-19T07:25:37.240 に答える
1

MVC では、データベース エンティティをモデルとして使用することは実際にはベスト プラクティスではありません。代わりに、ViewModel として POCO (またはさらに複雑なオブジェクト) を作成し、ビューに必要なデータのみを含むものを返すことができます (またはこの場合は API ユーザー)。返されたデータを操作したいだけの場合、その方法はわかりませんが、WebAPI は newtonsoft の JSON.NET ライブラリを使用して JSON を出力することを知っているので、それを操作する方法を調べてください。

于 2012-09-18T17:18:42.757 に答える