1

MCV4 の理解と知識を深めようとしています。

Product オブジェクトのプロパティ CategoryType を HttpPost のコントローラーに戻す最良の方法は何ですか。

すべてのプロパティを手で書き出す必要がないように、アプローチを探しています。現在、リフレクションを使用して Category タイプのプロパティを反復処理し、@Html.Hidden メソッドを使用して非表示の入力変数として追加しています。これは機能しますが、正しい方法で実行しているかどうかを知りたいです (ベストプラクティス)。

  1. @Html.HiddenFor メソッドを使用して、以下で行ったことを達成する方法を知りたいです。リフレクションからのプロパティ情報を使用してラムダ式を記述する方法がわかりません。
  2. Category オブジェクトをコントローラーに渡すことを処理するより良い方法はありますか? 私の見解は強く型付けされています。投稿で Product オブジェクトを返すことを知っている必要があります。

私は次のような複合型を持っています。

    public class Product
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string ProductName { get; set; }

    public Category CategoryType { get; set; }
}


public class Category
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string CategoryName { get; set; }
}

次のようにコントローラを使用

 public class ProductController : Controller
{
    //
    // GET: /Product/

    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Add()
    {
        //Add a new product to the cheese category.
        var product = new Product();
        var category = new Category { Id = 1, CategoryName = "Cheese" };
        product.CategoryType = category;

        return View(product);
    }

    [HttpPost]
    public ActionResult Add(Product product)
    {
        if (ModelState.IsValid)
        {
            //Add to repository code goes here

            //Redirect to Index Page
            return RedirectToAction("Index");
        }
        return View(product);
    }
}

そして、追加ビューで

    @model BootstrapPrototype.Models.Product

@{
    ViewBag.Title = "Add";
}

<h2>Add</h2>


@using (Html.BeginForm())
{

    @Html.DisplayFor(m => m.ProductName);
    @Html.EditorFor(m => m.ProductName);

    foreach(var property in Model.CategoryType.GetType().GetProperties())
    {

        //I know how to use the Hidden but would also know how to use the HiddenFor with reflections.
        @Html.Hidden("CategoryType." + property.Name, property.GetValue(Model.CategoryType));
    }

    <button type="submit">Add</button>

}

ありがとう。

4

2 に答える 2

4

なぜ隠されたのですか?

カテゴリ フィールドを非表示フィールドに配置する理由は、ユーザーに更新してほしくないためだと思いますが、それらの値をProductオブジェクトの一部として戻す必要があるためです。そうしないと、製品オブジェクトがカテゴリなしで保存されます。 (null値付き)。ViewModelこれこそが、 s が非常に重要である理由です。必要な値のみの入力を受け入れるビューモデルを作成します。したがって、名前のみが必要な製品を作成する必要があり、事前に選択された編集不可能なカテゴリを使用する場合は、ビューモデルを使用できます。

public class ProductModel {
    public int Id {get;set;}
    public strnig Name{get;set;}
    public int CategoryId {get;set;}
}

とビュー

@model ProductModel 
@Html.HiddenFor(m=>m.Id)
@Html.HiddenFor(m=>m.CategoryId)
@Html.TextboxFor(m=>m.Name)

コントローラーメソッドから取得できる

public ActionResult Add() {
    var product = new ProductModel {
        CategoryId = getIdFromDb("cheese");
    };
    return View();
}

コントローラーメソッドで受け取ることができる

[HttpPost]
public ActionResult Add(ProductMOdel input) {
    // map input to an entity
    var productENtity = mapModelToEntity(input);
    // save entity to your repo
}

ProductおよびCategoryクラスに 100 のフィールドがある場合、このアプローチの利点はさらに大きくなります。また、これらのフィールドの一部のみが編集されるユース ケースがあること。

足場

しかし、もちろん、あなたはまだあなたのやり方でそれを行うことができます. しかし、オーバーヘッドを与えるリフレクションを行う代わりに、それを取り除いてスキャフォールディングを行うべきです。このように、クラスのすべてのフィールドを手作業でコーディングする必要はありません。以下に、Scaffolding を開始するための 2 つの適切なリンクを示します。

リフレクションの使用

しかし、リフレクションの使用を主張する場合は、完全に可能です (ほとんどコードに含まれていました)。

@foreach(var property in Model.CategoryType.GetType().GetProperties())
{
    @Html.Hidden("Product." + property.Name, 
        property.GetValue(Model.CategoryType));
}

そのコードの鍵は"Product."、モデル バインダーがその仕事を行えるようにすることです。隠しフィールドの値は、POST コントローラー メソッドに戻されます。ただし、CategoryTypeが null の場合、そのコードは機能しません。

于 2013-04-24T02:02:54.677 に答える