问题
I feel like this is a pretty basic question. What I am trying to achieve is display a collection of objects as links. When I click on a link, I want to be taken to that specific object's details.
I can display a collection of item links on the index view, but when I click an item link, I can display the SingleProductView, but cannot display that specific item's variables there.
Is it possible to pass the specific item to the view through the html.actionlink? Or, is it possible to pass that specific item to another action that will display a view?
the model:
public class ProductModel
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
}
The home controller:
public class HomeController : Controller
{
List<ProductModel> inventory = new List<ProductModel>() {
new ProductModel { ProductName = "White T-Shirt", ProductDescription = "White T-Shirt", ListPrice = 10 },
new ProductModel { ProductName = "Black T-Shirt", ProductDescription = "Black T-Shirt", ListPrice = 10 },
};
public ActionResult Index()
{
return View(inventory);
}
[HttpGet]
public ActionResult SingleProductView()
{
return View();
}
}
The index view:
@if(Model != null)
{
<ul>
@foreach (ProductModel item in Model)
{
<li>
@Html.ActionLink(item.ProductName, "SingleProductView")
</li>
}
</ul>
}
回答1:
When you say return View();
, you aren't passing it a model. It's empty. So retrieve a model (usually from a database, but in your case just using an instance field) and pass that to the view.
[HttpGet]
public ActionResult SingleProductView(int id)
{
//From the inventory, retrieve the product that has an ID that matches the one from the URL (assuming default routing)
//We're using Linq extension methods to find the specific product from the list.
ProductModel product = inventory.Where(p => p.ProductId == id).Single();
//Send that product to the view.
return View(product);
}
Your view should accept a ProductModel
as the model type.
@* Declare the type of model for this view as a ProductModel *@
@model ProductModel
@* Display the product's name in a header. Model will be an instance of ProductModel since we declared it above. *@
<h2>@Model.ProductName</h2>
@* Display the product's description in a paragraph *@
<p>@Model.ProductDescription</p>
You don't pass the product from the index view to the other view, you pass the ID in the URL, which will turn into a parameter for the action method (assuming you've used default routing). Change your link to this in your index view:
@Html.ActionLink(item.ProductName, "SingleProductView", new {Id = item.ProductId})
Your ProductModel
says you have a ProductId
property, and no ListPrice
property. I think you need to add a public double ListPrice {get; set;}
and then when you create your inventory, assign ID's, for example:
List<ProductModel> inventory = new List<ProductModel>() {
new ProductModel { ProductId = 1, ProductName = "White T-Shirt", ProductDescription = "White T-Shirt", ListPrice = 10 },
new ProductModel { ProductId = 2, ProductName = "Black T-Shirt", ProductDescription = "Black T-Shirt", ListPrice = 10 },
};
The URL for accessing a product with an ID of 1 should be (assuming default routing) /Home/SingleProductView/1
.
By the way, you should rename ProductModel
to Product
. That makes it a little cleaner. And rename ProductName
to Name
. Look at the difference: ProductModel.ProductName
vs Product.Name
. Both are just as clear, but one is way more concise.
来源:https://stackoverflow.com/questions/28464343/passing-model-in-collection-to-actionlink