2017-01-12 29 views
0

我想在我的控制器中建立一個請求的動作,它將接受表格的請求:Product/Create/[Category ID]URL的ID值不會持續獲取「產品/創建/ [類別ID]」的請求發佈請求

當用戶在Product/Index/[Category Id]頁面上時,他們可以看到特定於該類別ID的所有產品。

他們可以點擊「創建」按鈕,它應該處理Get請求:Product/Create/[Category ID]。我需要將以前的請求中的Category ID保留到此PostRequest中,以便爲特定的Category ID創建產品。

我的控制器的創建操作是這樣的:

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); 
     } 

您也可以在創建操作的的GetRequest,我試着堅持將ID爲模型的CategoryId屬性看。 Create Action的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,所以我總是從Product/Index/[Category ID]頁面點擊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

難道你需要將視圖模型轉換爲一個域對象,而不是'category.Products.Add(viewModel);'? –

+0

我有隱式轉換方法在ViewModel類中進行轉換。我已將它列入我更新的問題中。 – naz786

+1

你確定'CategoryId'正在你的'Index'控制器方法中被填充嗎? –

回答

1

似乎CategoryId是不是被填充無論出於何種原因我建議你修改視圖模型,你的索引頁明確定義的類別id作爲一個單獨的屬性:

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

明確設置您的索引操作方法的CategoryId值。

@model ProductIndexViewModel 

與創建跳轉鏈接:

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

與產品循環:

替換爲你的索引視圖的模型定義

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

謝謝你的幫助克里斯! :) – 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

啊我明白你現在正在嘗試做什麼,這個答案不會解決它。 –