2012-12-22 16 views
7

カスタムモデルバインディングなしでこれを処理する方法はありますか?ASP.NET MVC 4 ViewModel with Child Interface

public class MyViewModel { 
    public string UserId { get; set; } 
    public IJob Job { get; set; } 
} 

public interface IJob { 
    public long Id { get; set; } 
    public string CompanyName { get; set; } 
} 

public class FullTimeJob : IJob { 
    // omitted for brevity 
} 

public class Internship : IJob { 
    // omitted for brevity 
} 

私がいる問題は、それがインスタンス化するIJobのどの実装を理解していないので、私は、デフォルトのモデルバインダーにエラーが発生しますです。 MyViewModelを作成したら、FullTimeJobのインスタンスをJobプロパティに設定しました。 ASP.NETは実装タイプを保持できないと思いますか?

このためのベストプラクティスソリューションは何ですか?

答えて

1

ビューはUIとコントローラ間のデータキャリアです。したがって、IdプロパティとCompanyNameプロパティをビューに単純に追加できます。あなたがしたいのは、IDと会社の値をUIから取得することだけです。 UIからデータを取得している間に、インターンシップかフルタイムのジョブかどうかは重要ではないかもしれません。 UIから取得したデータを処理する際には重要ですが、Viewの責任ではありません。

+0

私はオブジェクト階層を維持できるようにしたいので、仕事関連のフィールドを直接ビューモデルに置くことを避けたいと思います。私がそれをしているなら、ViewModelは私に何も買っていない。 –

+0

そうですね、私はカスタムモデルのバインダーでそれを行いましたが、それほどカスタムレスではないと思っていました。 –

+0

ViewModelを 'class MyViewModel T:IJob、new()'のようなものにすることができます。コンストラクタでカスタムジョブタイプ 'Job = new T();'をインスタンス化できます。 –

0

1つのオプションは、特にエレガントされていないが、以下のことができます任意のクラス固有のプロパティへのアクセスを維持しながら

public class MyViewModel { 
    public string UserId { get; set; } 
    public FulltimeJob FulltimeJob { get; set; } 
    public InternJob InternJob { get; set; } 

    public IJob Job { get { return FulltimeJob ?? InternJob; } } 
} 

これは、ジョブのプロパティを介して、あなたの共有プロパティに簡単にアクセスできます。

次に、POSTコントローラメソッドでどのプロパティが設定されているかを確認し、それに応じて動作させることができます。

+0

それは解決のためのきちんとした考えです、そして、あなたがそこに行くところを私は見ています。 IJobの新しいインプリメンテーション(すでに6つあります)を修正する必要があります。あなたが追加した2つの余分なフィールドがマップやコレクションにあったとしても、それはひどいことではありませんが、それでもまだちょっと気味が悪いです。 –

+0

私は同意します。私はそれがそれらのクラスがどれほど似ているか、実際にそれらのビューとコントローラのメソッドを共有する必要があるかどうかということになります。もう1つの方法(類似していますが)は、ビューモデルを平坦化し、JobTypeだけでなくフィールドだけを含むだけでなく、どのフィールドにポピュレートすることができるかをコントローラに知らせることです。 AutoMapperまたはFasterflectを使用してプロパティのマッピングを簡略化/自動化し、これを少し簡単にします。 –