3

最初から良い習慣を身につけたいので、この質問と問題があります。

私は働いている次のことをしてきました、そして私はこの投稿を読みました

ここ

私がやっていることのこの例:

コントローラ

public ActionResult OneDollar130(Int32 number)
{
    MyEDM db = new MyEDM();
    MyDBModel model = db.MyTable.Where(t => t.Current == 1 && t.No == number).First();
    return View(model);
}

見る

@model MyProject.MyDBModel
<table>
  <tr>
    @if (Model.fldNo1 == "")
    {
        <td class="numberTD">
            @Html.ActionLink("1", "Number1", "Number", new { model = Model, number = 1 }, null)
        </td>
    }
    else
    {
        <td class="numberTD2">
            @Html.ActionLink("1", "Number2", "Number", new { model = Model, number = 1 })
        </td>
     }
  </tr>
</table>

EDM のモデルを使用してビューに渡しています。

上記の投稿で、これは悪い習慣であるため、データベース モデルをビューに渡すべきではないことを読みました。私はそれを正しくやりたいと思っているので、これはやや心配です。

したがって、上記の投稿に基づいて、コードを変更して実験し、思わぬ障害に遭遇しました。

コントローラ

public ActionResult OneDollar112(Int32 TableNo)
{
    return View(new getOneDollar112Game(TableNo));
}

モデル

public class getMyModel
{
    MyEDM db = new MyEDM();
    public MyDBModel MyModel { get; set; }

    public getMyModel() { }
    public getMyModel(Int32 number)
    {
        MyModel = db.MyTable
            .Where(t => t.Current == 1 && t.No == numbner).First();
    }
}

見る

@model MyProject.Models.getMyModel
<table>
  <tr>
    @if (Model.fldNo1 == "")
    {
        <td class="numberTD">
            @Html.ActionLink("1", "Number1", "Number", new { model = Model, number = 1 }, null)
        </td>
    }
    else
    {
        <td class="numberTD2">
            @Html.ActionLink("1", "Number2", "Number", new { model = Model, number = 1 })
        </td>
    }
  </tr>
</table>

さて、私の2つの質問は次のとおりです。

  1. ベスト プラクティスはどれですか ... DB モデルをビューに渡さないというルールを破る前に行っていたことはありますか?

  2. 2 番目の方法が正しい場合 (私が想定している)、fldNo1 が存在しないというエラーが継続的に発生するのはなぜですか?

例: CS1061: 'MyProject.Models.getMyModel' には 'fldNo1' の定義が含まれておらず、タイプ 'MyProject.Models.getMyModel' の最初の引数を受け入れる拡張メソッド 'fldNo1' が見つかりませんでした (using ディレクティブがありませんか?またはアセンブリ参照?)

4

3 に答える 3

1

少なくとも 2 つの理由から、Model と ViewModel を分離する必要があります。

1. セキュリティ

MVC のデフォルトのモデル バインダーは、一致する投稿データ フィールドをモデル プロパティにバインドします。これにより、更新することを意図していないがモデル内にあるプロパティがある場合に悪用される可能性のあるセキュリティ全体が提供されます (たとえば、通常は表示されないプロパティ名でポスト バックを偽造する)。

ViewModel を使用し、必要な各プロパティを ViewModel から実際のモデルに明示的に渡すことで、この攻撃ベクトルから防御します

2.複雑さ

ほとんどの合理的なアプリケーションでは、ビューごとに多数のモデルとモデル コレクションが必要になります。

たとえば、基本的な CRM 顧客ビューには、顧客の詳細 (スコアは除く)、名前と電話番号のリスト、最近の取引の概要リスト、登録された製品のリストなどがあります。これらは、名前と電話番号を含むオブジェクトの複雑なコレクションに存在する場合があります。異なるモデルでは、最近のトランザクションは、注文番号、注文明細の総数、および最初の 3 つの SKU コードのみなどです。

ViewModel を使用すると、モデルと静的データ キャッシュから、表示に必要な部分と要約のみを構築できます。その結果、ビューを構築するためのワークフローが簡素化され、よりテストしやすくなります。

通常、単純なViewModelから実際に使用される最終的な複雑なViewModelへの継承のパスがあります

于 2013-02-02T09:58:46.763 に答える
0

1) あなたのコードを編集しました。

アクション:

public ActionResult OneDollar112(Int32 tableNo)
{
    return View(new OneDollar112ViewModel(tableNo));
}

モデル:

public class OneDollar112ViewModel
{
    private static MyEDM db = new MyEDM();
    private MyDBModel myModel;

    public string fldNo1 
    {
        get 
        { 
            return myModel == null
                ? myModel.fldNo1
                : null;
        }

        set 
        {
            // Your set logic here 
        }
    }    

    public OneDollar112ViewModel(Int32 number)
    {
        myModel = db.MyTable
            .Where(t => t.Current == 1 && t.No == numbner).SingleOrDefault();
    }
}    

意見:

@model MyProject.Models.OneDollar112ViewModel
<table>
    <tr>
    @if (Model.fldNo1 == "")
    {
        <td class="numberTD">
            @Html.ActionLink("1", "Number1", "Number", new { model = Model, number = 1 }, null)
        </td>
    }
    else
    {
        <td class="numberTD2">
            @Html.ActionLink("1", "Number2", "Number", new { model = Model, number = 1 })
        </td>
    }
    </tr>
</table>

2) ビュー モデルを使用して、サービスにカプセル化できるデータ層からビジネス ロジックを分離し、将来的に依存性注入を利用する必要があります。

于 2013-02-02T09:43:47.467 に答える