(编辑)的 我有一个产品(产品)表,它在名为ProductCatalog的视图中显示,用户可以在其中找到产品表中的所有产品。我正在使用标准(索引)视图。
我现在想要实现的是可以选择(单击)目录中的单个产品并显示产品的详细视图的场景(类似于CRUD中的标准编辑/详细信息方法)。 但是,在此详细信息视图(ProductDetails)中,我需要增强模型,因为用户将确定变量,例如应该过帐到新表(LineItems)的订单数量以及产品中的属性( ProductID,主要是为了最终创建订单。
我一直未能实现这一目标。不确定我是否需要使用mutliple视图模型或做一些我不了解的其他奇特的东西。
总而言之,问题是如何从Index转到Details和Details以将不同的viewmodel发布到某个DB。所有这一切都与EF。
型号:
da.attrs['long_name'] = 'new_long_name'
查看
public class Products
{
public int ID { get; set; }
public int CategoryID { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public string ProductPicturePath { get; set; }
public string UnitCost { get; set; }
public string UnitPrice { get; set; }
public string LowestUnitPrice { get; set; }
public string SubscriptionPrice { get; set; }
public string UnitMargin { get; set; }
public string UnitProfit { get; set; }
public bool InCatalog { get; set; }
}
public class ProductViewModel
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public string ProductPicturePath { get; set; }
[RegularExpression(@"^\((\d{3}?)\)$", ErrorMessage = "Du brauchst die Anzahl nicht ausschreiben - verwende Ziffern.")]
[Display(Name = "Bestellmenge")]
public string SubscriptionQuantity { get; set; }
[Display(Name = "Lieferrhytmus")]
public string SubscriptionCadenceCategory { get; set; }
public string SubscriptionCadenceValue { get; set; }
[Display(Name = "Preis im Abonnement")]
public string SubscriptionPrice { get; set; }
public bool IsSingleOrder { get; set; }
[RegularExpression(@"^\((\d{3}?)\)$", ErrorMessage = "Du brauchst die Anzahl nicht ausschreiben - verwende Ziffern.")]
[Display(Name = "Bestellmenge")]
public string Quantity { get; set; }
[Display(Name = "Preis pro Einheit")]
public string UnitPrice { get; set; }
public DateTime ActivityDateTime { get; set; }
public string ActivityLatitude { get; set; }
public string ActivityLongitude { get; set; }
public string ActivityLocation { get; set; }
}
ProductDetails(查看)
@using freshNclean.Models
@model IEnumerable<freshNclean.Models.Products>
@{
ViewBag.Title = "Sortiment";
}
<div id="productCatalogContainer" class="container">
<div id="productCatalogHeaderSection" class="headerSection">
<h1 id="productCatalogHeaderTitle" class="headerTitle">
@ViewBag.Title
</h1>
<i id="productCatalogHeaderIcon" class="headerIcon fas fa-gem" aria-hidden="true"></i>
</div>
<!-- table section -->
<section id="productCatalogListPartialSection" class="table">
<div id="productCatalogSeparatorSection" class="separatorSection">
<hr id="productCatalogSeparator" class="separator" />
</div>
<div id="productCatalog" class="productTableSection row">
@foreach (var item in Model)
{
if (item.InCatalog == true)
{
<a id="productCatalogProductArea" class="tableArea col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-3 col-lg-offset-2 col-lg-3" href="@Url.Action("ProductDetails", "freshNclean", new { id = item.ID })">
@Html.HiddenFor(modelItem => item.ID, new { @class = "tableField col-xs-12 col-sm-12 col-md-12 col-lg-12" })
<img id="productCatalogProductImage" class="tableImage col-xs-12 col-sm-12 col-md-12 col-lg-12" src="@Url.Content(item.ProductPicturePath)" alt="Produktbild" />
<div id="productCatalogProductNameField" class="tableField col-xs-12 col-sm-12 col-md-12 col-lg-12">
@Html.DisplayFor(modelItem => item.ProductName)
</div>
<div id="productCatalogProductDescriptionField" class="tableField col-xs-12 col-sm-12 col-md-12 col-lg-12">
@Html.DisplayFor(modelItem => item.ProductDescription)
</div>
<div id="productCatalogLowestUnitPriceField" class="tableField col-xs-12 col-sm-12 col-md-12 col-lg-12">
ab @Html.DisplayFor(modelItem => item.LowestUnitPrice)
</div>
</a>
}
}
</div>
<div id="productCatalogListPartialMenuSeparatorSection" class="separatorSection">
<hr id="productCatalogListPartialMenuSeparator" class="separator" />
</div>
@Html.ActionLink("zum Warenkorb", "ShowShoppingCart", "", htmlAttributes: new { @class = "formButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-3 col-md-6 col-lg-offset-3 col-lg-6" })
</section>
</div>
<!-- link back to menu -->
<div id="productCatalogReturnToMenuSection" class="linkSection">
@Html.ActionLink("zurück zum Menü", "Profile", "", htmlAttributes: new { @id = "productCatalogReturnToMenuButton", @class = "link" })
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<!-- Google Places -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBYK8aBCsb1dFrzXqIgUq07ZwO3w3_fGCs&libraries=places&callback=initAutocomplete" async defer></script>
}
控制器
@model freshNclean.Models.Products
@{
ViewBag.Title = "Sortiment";
}
<div id="productCatalogContainer" class="container">
<div id="productCatalogHeaderSection" class="headerSection">
<h1 id="productCatalogHeaderTitle" class="headerTitle">
@ViewBag.Title
</h1>
<i id="productCatalogHeaderIcon" class="headerIcon fas fa-gem" aria-hidden="true"></i>
</div>
<!-- form -->
<section id="productDetailsForm" class="form">
@using (Html.BeginForm("ShowProduct", "freshNclean", FormMethod.Post, new { @id = "productDetailsFormContainer", @class = "form-horizontal", @role = "form" }))
{
@Html.AntiForgeryToken()
<!-- user activities (hidden) -->
@Html.HiddenFor(m => m.ActivityLatitude, new { @id = "productDetailsActivityLatitudeField", @class = "userActivityField" })
@Html.HiddenFor(m => m.ActivityLongitude, new { @id = "productDetailsActivityLongitudeField", @class = "userActivityField" })
@Html.HiddenFor(m => m.ActivityLocation, new { @id = "productDetailsActivityLocationField", @class = "userActivityField" })
<!-- autopopulate user activity fields with location -->
<script>
$(document).ready(function defaultValue() {
if (!navigator.geolocation) return;
navigator.geolocation.getCurrentPosition(function (userCoordinates) {
geocoder = new google.maps.Geocoder();
userLatLng = new google.maps.LatLng(userCoordinates.coords.latitude, userCoordinates.coords.longitude);
document.getElementById('productDetailsActivityLatitudeField').value = userCoordinates.coords.latitude;
document.getElementById('productDetailsActivityLongitudeField').value = userCoordinates.coords.longitude;
geocoder.geocode({ 'latLng': userLatLng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var result = results[0];
locationPlaceholder = "";
for (var i = 0, len = result.address_components.length; i < len; i++) {
var addressComponent = result.address_components[i];
if (addressComponent.types.indexOf("locality") >= 0) locationPlaceholder = addressComponent.long_name;
}
if (locationPlaceholder != '') {
document.getElementById('productDetailsActivityLocationField').value = locationPlaceholder;
}
}
});
});
});
</script>
<!-- form: product display -->
<div id="productDetailsProductDisplaySeparatorSection" class="separatorSection">
<hr id="productDetailsProductDisplaySeparator" class="separator" />
</div>
<div id="productDetailsProductDisplaySection" class="formSection row">
@Html.HiddenFor(m => m.ProductID, new { @id = "productDetailsProductIDField", @class = "tableField col-xs-12 col-sm-12 col-md-12 col-lg-12" })
<img id="productDetailsProductImage" class="tableImage col-xs-12 col-sm-12 col-md-12 col-lg-12" src="@Model.ProductPicturePath" alt="Produktbild" />
<div id="productDetailsProductName" class="tableField col-xs-12 col-sm-12 col-md-12 col-lg-12">
@Html.DisplayFor(m => m.ProductName)
</div>
<div id="productDetailsProductDescriptionField" class="tableField col-xs-12 col-sm-12 col-md-12 col-lg-12">
@Html.DisplayFor(m => m.ProductDescription)
</div>
<!-- define subscription quantity -->
<a id="productDetailsSubscriptionMinusButton" class="tableButton col-xs-offset-2 col-xs-2 col-sm-offset-2 col-sm-2 col-md-offset-3 col-md-2 col-lg-offset-3 col-lg-2">
-
</a>
@Html.TextBoxFor(m => m.SubscriptionQuantity, new { @id = "productDetailsSubscriptionQuantityField", @class = "tableField col-xs-offset-1 col-xs-2 col-sm-offset-1 col-sm-2 col-md-offset-0 col-md-2 col-lg-offset-0 col-lg-2" placeholder = "0" })
<a id="productDetailsSubscriptionPlusButton" class="tableButton col-xs-offset-1 col-xs-2 col-sm-offset-1 col-sm-2 col-md-offset-0 col-md-2 col-lg-offset-0 col-lg-2">
+
</a>
@Html.LabelFor(m => m.SubscriptionCadenceCategory, new { @id = "productDetailsSubscriptionCadenceCategoryLabel", @class = "tableLabel" })
@Html.TextBoxFor(m => m.SubscriptionCadenceCategory, new { @id = "productDetailsSubscriptionCadenceCategoryField", @class= "tableField" })
@Html.LabelFor(m => m.SubscriptionCadenceValue, new { @id = "productDetailsSubscriptionCadenceValueLabel", @class = "tableLabel" })
@Html.TextBoxFor(m => m.SubscriptionCadenceValue, new { @id = "productDetailsSubscriptionCadenceValueField", @class= "tableField" })
</div>
<div id="productCatalogListPartialMenuSeparatorSection" class="separatorSection">
<hr id="productCatalogListPartialMenuSeparator" class="separator" />
</div>
@Html.ActionLink("zum Warenkorb", "ShowShoppingCart", "", htmlAttributes: new { @class = "formButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-3 col-md-6 col-lg-offset-3 col-lg-6" })
</section>
</div>
<!-- link back to menu -->
<div id="productCatalogReturnToMenuSection" class="linkSection">
@Html.ActionLink("zurück zum Menü", "Profile", "", htmlAttributes: new { @id = "productCatalogReturnToMenuButton", @class = "link" })
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<!-- Google Places -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBYK8aBCsb1dFrzXqIgUq07ZwO3w3_fGCs&libraries=places&callback=initAutocomplete" async defer></script>
}
答案 0 :(得分:1)
注意:由于技术原因,我无法运行此代码。因此,它可能包含未捕获的错误。让我知道这些事情。
因此,这是一个过于完整的示例。 想法如下:
PersonEntity
的列表来完成此操作)Details
链接时,我们将被发送到DetailRow
操作。 person.Id
作为GET参数传递。DetailRow
视图中,我们查询数据库,但仅请求与作为参数传递的PersonEntity
匹配的Id
。 Detail
方法包括.Include
属性。 PersonEntity
。 Person
视图中显示返回的DetailRow
我认为粗体字直接回答了您的问题。
在此示例中,我假设您使用的是Entity Framework,否则,您需要将对Context
类的调用“转换”为某种DAO,或者如果您是一个肮脏的人,则直接插入SQL。 -)
控制器和数据层的代码(理想情况下,每个类都放在自己的文件中)
public class KenFExample : Controller
{
// GET
public IActionResult Index()
{
using (Context context = new Context())
{
// Get the whole list of basic entries
IEnumerable<SimplePersonViewModel> rows = context.Persons.Select(r => new SimplePersonViewModel(r));
// Construct a new view model with these entries
BaseListingViewModel model = new BaseListingViewModel(rows);
return View(model);
}
}
public IActionResult DetailRow(int id)
{
using (Context context = new Context())
{
// Get only the entry that we are interrested in
PersonEntity row = context.Persons.Include(p => p.Detail).Single(r => r.Id == id);
// Construct a new view model with this entry
PersonViewModel model = new PersonViewModel(row);
return View(model);
}
}
}
public class Context : DbContext
{
public virtual DbSet<PersonEntity> Persons { get; set; }
public virtual DbSet<DetailEntity> Details { get; set; }
}
public class PersonViewModel
{
public PersonViewModel(PersonEntity entity)
{
Id = entity.Id;
FirstName = entity.FirstName;
LastName = entity.LastName;
IsHandsome = entity.Detail.IsHandsome;
Address = entity.Detail.Address;
Email = entity.Detail.Email;
Phone = entity.Detail.Phone;
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsHandsome { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
public class PersonEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual DetailEntity Detail { get; set; }
}
public class DetailEntity
{
public bool IsHandsome { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public virtual PersonEntity Person { get; set; }
}
public class SimplePersonViewModel
{
public SimplePersonViewModel(PersonEntity entity)
{
Id = entity.Id;
FirstName = entity.FirstName;
LastName = entity.LastName;
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class BaseListingViewModel
{
public BaseListingViewModel(IEnumerable<SimplePersonViewModel> list)
{
Rows = list;
}
public IEnumerable<SimplePersonViewModel> Rows { get; set; }
}
这是Index.cshtml
视图
@model BaseListingViewModel
<table>
<thead>
<tr>
<td>
Id
</td>
<td>
First name
</td>
<td>
Last name
</td>
<td>
Is handsome
</td>
<td>
Go to details
</td>
</tr></thead>
@foreach (SimplePersonViewModel person in Model.Rows)
{
<tr>
<td>
@person.Id
</td>
<td>
@person.FirstName
</td>
<td>
@person.LastName
</td>
<td>
<a href="@Url.Action("DetailRow", new {id = person.Id})">Details</a>
</td>
</tr>
}
</table>
这是DetailRow.cshtml
视图
@model RelaxationPortal.Controllers.PersonViewModel
Details for @Model.FirstName @Model.LastName (id: @Model.Id)
<br />
Address is @Model.Address and can be contacted using @Model.Phone
@if (Model.IsHandsome)
{
<span>He <b>IS</b> handsome</span>
}
else
{
<span>He isn't so handsome</span>
}