2017-01-12 6 views
0

私のコントローラで、要求のアクションを作成しようとしています:Product/Create/[Category ID]の要求を受け入れます。URLのID値が "Product/Create/[Category ID]"要求を依頼し続けることがありません

ユーザーがProduct/Index/[Category Id]ページにいる場合、そのカテゴリIDに固有のすべての製品が表示されます。

リクエスト:Product/Create/[Category ID]を処理する[作成]ボタンをクリックできます。特定のCategory IDの製品を作成するには、前のリクエストのCategory IDをこのPostRequestに保存する必要があります。

私のコントローラの作成アクションのようになります。また、あなたは、アクション作成者のGetRequestで見ることができます

public ActionResult Create(int? id) 
     { 
      if (id == null) 
      { 
       return HttpNotFound(); 
      } 

      return View(new ProductViewModel{CategoryId = id.Value}); 
     } 

     // POST: Product/Create 
     // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
     // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> Create([Bind(Include = "Id,Name,Image,Price,CategoryId")] ProductViewModel viewModel) 
     { 

      if (ModelState.IsValid && viewModel.Image != null) 
      { 
       var category = await db.Categories.FindAsync(viewModel.CategoryId); 

       if (category == null) 
       { 
        return HttpNotFound(); 
       } 

       category.Products.Add(viewModel); 

       await db.SaveChangesAsync(); 
       return RedirectToAction("Index/" + viewModel.CategoryId); 
      } 

      return View(viewModel); 
     } 

、私はモデルのCategoryIdプロパティにIDを持続してみてください。アクション作成のPostRequestのモデルは、GetRequestから取得したCategoryIdという値を含むはずです。 Product/Index/[Category ID]から

ビューのモデル一覧です:同じビューで

@model List<ValueVille.Models.ProductViewModel> 
@using MvcApplication8.Models 

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 

<p class="btn btn-default"> 
    @Html.ActionLink("Create New", "Create", new { id = Model[0].CategoryId}) 
</p> 

<table class="panel panel-default table"> 
    <tr> 
     <th> 
      @Html.DisplayNameFor(model => model[0].Name) 

     </th> 
     <th> 
      @Html.DisplayNameFor(model => model[0].Image) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model[0].Price) 
     </th> 
     <th></th> 
    </tr> 

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.Name) 
     </td> 
     <td> 
      @Html.Image(item.ByteImage, "Product_Image", "100") 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Price) 
     </td> 
     <td> 
      @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | 
      @Html.ActionLink("Details", "Details", new { id=item.Id }) | 
      @Html.ActionLink("Delete", "Delete", new { id=item.Id }) 
     </td> 
    </tr> 
} 

</table> 

<div> 
    @Html.ActionLink("Back to List", "Index", new { Controller = "Category" }, new { id = Model[0].Id}) 
</div> 

Create ActionLinkのは、次のようになります。ブラウザで

<p class="btn btn-default"> 
    @Html.ActionLink("Create New", "Create", new { id = Model[0].CategoryId}) 
</p> 

idは常に提供します値は0ですから、ページからCreateをクリックすると、私はいつもProduct/Create/0に連れて行きます。変換方法と

ProductViewModelクラス:

public class ProductViewModel 
    { 
     public int Id { get; set; } 
     [Required, Display(Name="Product Name")] 
     public string Name { get; set; } 
     [DataType(DataType.Upload)] 
     public HttpPostedFileBase Image { get; set; } 
     public string OutputImage { get; set; } 
     public Byte[] ByteImage { get; set; } 
     [Required] 
     public Decimal Price { get; set; } 
     public int CategoryId { get; set; } 

     public static byte[] ConvertToByte(ProductViewModel model) 
     { 
      if (model.Image != null) 
      { 
       byte[] imageByte = null; 
       BinaryReader rdr = new BinaryReader(model.Image.InputStream); 
       imageByte = rdr.ReadBytes((int)model.Image.ContentLength); 

       return imageByte; 
      } 

      return null; 
     } 

     // ViewModel => Model | Implicit type Operator 
     public static implicit operator Product(ProductViewModel viewModel) 
     { 
      var model = new Product 
      { 
       Id = viewModel.Id, 
       Name = viewModel.Name, 
       Image = ConvertToByte(viewModel), 
       Price = viewModel.Price 
      }; 

      return model; 
     } 

     // Model => ViewModel | Implicit type Operator 
     public static implicit operator ProductViewModel(Product model) 
     { 
      var viewModel = new ProductViewModel 
      { 
       Id = model.Id, 
       Name = model.Name, 
       OutputImage = string.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(model.Image)), 
       ByteImage = model.Image, 
       Price = model.Price, 
       CategoryId = model.Id 
      }; 

      return viewModel; 
     } 

    } 
+0

:で

<p class="btn btn-default"> @Html.ActionLink("Create New", "Create", new { id = Model.CategoryId }) </p> 

と製品のループ:でアクション・リンクを作成します

@model ProductIndexViewModel 

ビューモデルを 'category.Products.Add(viewModel);ではなくドメインオブジェクトに変換します;'? –

+0

私は、変換を行うViewModelクラスの内部に暗黙の変換メソッドを持っています。私は更新された質問にそれを含めました。 – naz786

+1

あなたの 'Index'コントローラメソッドに' CategoryId'が設定されていることは確かですか? –

答えて

1

CategoryIdが移入されていないようです:あなたはループのいくつかのフォームにインデックスページ上のすべての製品のリストを表示していると仮定すると、モデルのインデックスではなく、ローカル製品の参照を使用してみてくださいどんな理由であれ。私はあなたが明示的に別のプロパティとしてカテゴリIDを定義するために、あなたのインデックスページのビューモデルを修正する提案:

public class ProductIndexViewModel 
{ 
    public IList<ValueVille.Models.ProductViewModel> Products; 
    public int? CategoryId 
} 

明示的にあなたのindexアクションメソッドでCategoryId値を設定します。

を使用して、インデックスビューのモデル定義を置き換えます。あなたがする必要はありません

@foreach (var item in Model.Products) { 
+0

Chrisさん、ありがとうございます! :) – naz786

1

問題のIndex.cshtmlのビューコードの残りの部分を含めてください。

問題がnew { id = Model[0].CategoryId }であると思われます。

@foreach (var p in Model) 
{ 
    ... 
    <p class="btn btn-default"> 
     @Html.ActionLink("Create New", "Create", new { id = p.CategoryId }) 
    </p> 
    ... 
} 
+0

質問を更新し、インデックスページコードを含めました – naz786

+0

ああ、私はあなたが今何をしようとしているのか見ていますが、この答えは解決しません。 –

関連する問題