这是理念。当管理员登录时,他们可以提取所有用户的列表。它会提供编辑,详细信息,删除等正常选项,但我已经添加了一个购买链接,如下所示:
@model IEnumerable<IdentitySample.Models.ApplicationUser>
@{
ViewBag.Title = "Index";
}
<div class="col-12 backgroundImg">
<div class="navbarSpace">
<div class="col-12 formBackground">
<h2 class="formHeader">List of Users</h2>
<h4 class="formText">
@Html.ActionLink("Create New ", "Create")
</h4>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th>
@Html.DisplayNameFor(model => model.UserName)
</th>
<th>
@Html.DisplayNameFor(model => model.FavStrain)
</th>
<th>
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FavStrain)
</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 }) |
@Html.ActionLink("Purchases", "PurchaseIndex", new {
id = item.Id})
</td>
</tr>
}
</table>
</div>
</div>
</div>enter code here
当您单击“购买”链接时,它会将您带到PurchaseIndex页面,如下所示: Purchase List
@model IEnumerable<IdentitySample.Models.Purchases>
@{
ViewBag.Title = "Index";
}
<div class="col-12 backgroundImg navbarSpace">
<div class="col-12 formBackground">
<h2 class="formHeader">Index</h2>
<hr />
<div class="formHeaderSmall">
Total Points <br />
@Model.Sum(i => i.Points) </div>
<p class="formText">
@Html.ActionLink("Create New", "CreatePurchase")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Points)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Points)
</td>
<td></td>
</tr>
}
</table>
<p class="formText">
@Html.ActionLink("Back to List", "Index")
</p>
</div>
</div>
它给出了一个购买列表,并给出了我没有包含详细信息页面的总分。除了购买不映射到特定用户之外,一切正常。如果我创建一个新用户并单击“购买”,则会显示所有购买的列表,而不仅仅是针对该用户的特定购买。如何将购买映射到特定用户?
我创建了一个如下所示的Purchases类:
public class Purchases
{
[Key]
public int PurchaseId { get; set; }
[Required]
[Display(Name = "Product Name")]
[DataType(DataType.Text)]
public string Name { get; set; }
[Required]
[Range(0,5)]
[Display(Name = "Points")]
[DataType(DataType.Text)]
public int Points { get; set; }
public string ApplicationUserId { get; set; }
public virtual ApplicationUser Users { get; set; }
}
我的ApplicationUser类看起来像这样:
public class ApplicationUser : IdentityUser
{
[Display(Name ="Favorite Strain")]
[DataType(DataType.Text)]
public string FavStrain { get; set; }
public virtual List<Purchases> Purchase { get; set; }
到目前为止,数据库正在按照预期的方式将Purchases类的外键注册到ApplicationUser类。
我可以创建一个新的购买并将它们显示在列表中,并且所有Crud操作都可以正常工作。 问题是,当我创建一个新的购买时,它不会在数据库中包含ApplicationUserId,它会返回Null。
我很确定问题出在我的控制器中。我已经尝试了所有的东西,所以我不想包括失败的尝试,所以这里是控制器,因为它们现在正在工作。
我不需要包含编辑或详细信息,因为我不会向用户提供访问权限。
public ActionResult CreatePurchase()
{
return View();
}
private ApplicationDbContext db = new ApplicationDbContext();
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreatePurchase([Bind(Include = "PurchaseId,Name,Points,Id")] Purchases purchases)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchases);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchases);
}
// GET: Purchases/Edit/5
public ActionResult PurchaseIndex()
{
var userDetails = db.Purchases.Include(u => u.Users);
return View(db.Purchases.ToList());
}
这是我关于Stack Overflow的第一个问题,如果有些事情不对,请原谅我。
********* ********更新****************************
这是我的PurchaseIndexController。现在,这仅返回与购买相关联的用户。但是它始终为0,因为没有UserID。如果我尝试使用int?型或Guid?它给出了一个错误。无法将int类型隐式转换为字符串。
public ActionResult PurchaseIndex(string ID)
{
//this gets all purchases for a certain individual
ApplicationDbContext db = new ApplicationDbContext();
var userDetails = db.Purchases.Where(x => x.ApplicationUserId ==
ID).ToList();
return View(userDetails);
}
这是CreatePurchase View
@model IdentitySample.Models.Purchases
@{
ViewBag.Title = "Create";
}
<div class="col-12 backgroundImg navbarSpace">
<div class="col-12 formBackground">
<h2 class="formHeader">Add a New Purchase</h2>
<hr />
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@*@Html.Hidden("id", (string)ViewBag.UserID)*@
@Html.HiddenFor(model => model.ApplicationUserId)
<div class="form-horizontal">
<div class="col-12">
@Html.LabelFor(model => model.Name, htmlAttributes: new {
@class = "formText col-12" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new {
htmlAttributes = new { @class = "col-12" } })
@Html.ValidationMessageFor(model => model.Name, "", new
{ @class = "text-danger" })
</div>
</div>
<div class="col-12">
@Html.LabelFor(model => model.Points, htmlAttributes: new {
@class = "formText col-12" })
<div class="col-md-10">
@Html.EditorFor(model => model.Points, new {
htmlAttributes = new { @class = "col-12" } })
@Html.ValidationMessageFor(model => model.Points, "",
new { @class = "text-danger" })
</div>
</div>
<div class="col-12">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-
default" />
</div>
</div>
</div>
}
<div class="formText">
@Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
我还在管理部分中有链接,供用户查看积分和购买但我不知道如何为此创建ActionLink以获取与用户相关的购买。 这是控制器
public ActionResult WeedPoints(string ID)
{
ApplicationDbContext db = new ApplicationDbContext();
var userDetails = db.Purchases.Where(x => x.ApplicationUserId ==
ID).ToList();
return View(userDetails);
}
现在是Action Link。
<div class="col-12 formHeaderSmall">@Html.ActionLink("My
Purchases/Points", "WeedPoints", "Manage")</div>
**********更新************* ***************************
以下是带有View Bag参考的控制器。创建购买视图具有ViewBag我刚刚取消注释它。
[Authorize(Roles =
"Admin,DispensaryManager,DispensaryEmployee,DispensaryEastEmployee")]
public ActionResult CreatePurchase(string Id)
{
ViewBag.UserID = Id;
//ApplicationDbContext db = new ApplicationDbContext();
//var userDetails = db.Purchases.Where(x => x.ApplicationUserId == Id;
return View();
}
private ApplicationDbContext db = new ApplicationDbContext();
//POST: Purchases/Create
[HttpPost]
[Authorize(Roles =
"Admin,DispensaryManager,DispensaryEmployee,DispensaryEastEmployee")]
[ValidateAntiForgeryToken]
public ActionResult CreatePurchase([Bind(Include =
"PurchaseId,Name,Points,ApplicationUserId")] Purchases
purchases,string id)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchases);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchases);
}
[Authorize(Roles =
"Admin,DispensaryManager,DispensaryEmployee,DispensaryEastEmployee")]
public ActionResult PurchaseIndex(string Id)
{
//this gets all purchases for a certain individual
ApplicationDbContext db = new ApplicationDbContext();
var userDetails = db.Purchases.Where(x => x.ApplicationUserId ==
Id).ToList();
ViewBag.UserID = Id;
return View(userDetails);
}
*************************** Total Refactor ****************** *************** 8
这是完整的新控制器。
public class PurchasesController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Purchases
public ActionResult Index()
{
var purchases = db.Purchases.Include(p => p.Users);
return View(purchases.ToList());
}
// GET: Purchases/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Purchases purchases = db.Purchases.Find(id);
if (purchases == null)
{
return HttpNotFound();
}
return View(purchases);
}
// GET: Purchases/Create
public ActionResult Create()
{
ViewBag.Users = new SelectList(db.Users, "Id", "UserName");
List<SelectListItem> selectListItems = new List<SelectListItem>();
foreach (ApplicationUser user in db.Users)
{
SelectListItem selectListItem = new SelectListItem
{
Text = user.UserName,
Value = user.Id.ToString()
};
selectListItems.Add(selectListItem);
}
//ViewBag.ApplicationUserId = new SelectList(db.Users, "Id",
"UserName");
return View();
}
// POST: Purchases/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 ActionResult Create([Bind(Include =
"PurchaseId,Name,Points,TotalPoints,ApplicationUserId")] Purchases
purchases)
{
if (ModelState.IsValid)
{
var totalPoints = db.Purchases.Sum(x => x.Points);
purchases.TotalPoints = totalPoints;
db.Purchases.Add(purchases);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ApplicationUserId = new SelectList(db.Users, "Id",
"UserName", purchases.ApplicationUserId);
return View(purchases);
}
// GET: Purchases/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Purchases purchases = db.Purchases.Find(id);
if (purchases == null)
{
return HttpNotFound();
}
ViewBag.ApplicationUserId = new SelectList(db.Users, "Id",
"UserName", purchases.ApplicationUserId);
return View(purchases);
}
// POST: Purchases/Edit/5
// 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 ActionResult Edit([Bind(Include =
"PurchaseId,Name,Points,TotalPoints,ApplicationUserId")] Purchases
purchases)
{
if (ModelState.IsValid)
{
db.Entry(purchases).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ApplicationUserId = new SelectList(db.Users, "Id",
"UserName", purchases.ApplicationUserId);
return View(purchases);
}
// GET: Purchases/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Purchases purchases = db.Purchases.Find(id);
if (purchases == null)
{
return HttpNotFound();
}
return View(purchases);
}
// POST: Purchases/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Purchases purchases = db.Purchases.Find(id);
db.Purchases.Remove(purchases);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
现在,您可以在创建新购买时从下拉列表中选择用户。这是创建视图。
<div class="col-12 backgroundImg navbarSpace scrollBar">
<div class="formBackground col-12">
<h2 class="formHeader">Edit Puchase</h2>
<hr />
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger"
})
@Html.HiddenFor(model => model.PurchaseId)
@Html.HiddenFor(model => model.TotalPoints)
<div class="col-12">
@Html.LabelFor(model => model.Name, htmlAttributes: new {
@class = "formText col-12" })
<div class="col-12">
@Html.EditorFor(model => model.Name, new {
htmlAttributes = new { @class = "col-12" } })
@Html.ValidationMessageFor(model => model.Name, "", new
{ @class = "text-danger" })
</div>
</div>
<div class="col-12">
@Html.LabelFor(model => model.Points, htmlAttributes: new {
@class = "formText col-12" })
<div class="col-12">
@Html.EditorFor(model => model.Points, new {
htmlAttributes = new { @class = "col-12" } })
@Html.ValidationMessageFor(model => model.Points, "",
new { @class = "text-danger" })
</div>
</div>
@*<div class="col-12">
@Html.LabelFor(model => model.TotalPoints,
htmlAttributes: new { @class = "formText col-12" })
<div class="col-12">
@Html.EditorFor(model => model.TotalPoints, new {
htmlAttributes = new { @class = "col-12" } })
@Html.ValidationMessageFor(model =>
model.TotalPoints, "", new { @class = "text-danger" })
</div>
</div>*@
<div class="col-12">@Html.LabelFor(model => model.ApplicationUserId,
"Users", htmlAttributes: new { @class = "formText col-12" })
<div class="col-12"> @Html.DropDownList("Users", null, htmlAttributes:
new { @class = "col-12" })
@Html.ValidationMessageFor(model => model.ApplicationUserId, "", new {
@class = "text-danger" })
</div>
</div>
<div class="col-12">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div class="formText"> @Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
这会创建一个显示其用户名的用户下拉列表。当我选择一个用户并点击保存时,我得到一个错误说 没有类型&#39; IEnumerable&#39;的ViewData项目。这有关键&#39; Id&#39;。
答案 0 :(得分:0)
传递给此方法的'Id'是否为null?
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreatePurchase([Bind(Include = "PurchaseId,Name,Points,Id")] Purchases purchases)
{
if (ModelState.IsValid)
{
db.Purchases.Add(purchases);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchases);
}
如果为null,则应在您发布的表单中包含userID(作为隐藏字段)。然后(一旦在数据库中填充了userID),您应该只能获得与userID相关联的购买,执行以下操作:
var userDetails = db.Purchases.Where(x=>x.ApplicationUserId == ID).ToList();
答案 1 :(得分:0)
您遇到的问题是“创建新购买”&#39; action没有传递用户ID,它当前是:
@Html.ActionLink("Create New", "CreatePurchase")
然而需要传递一个id:
@Html.ActionLink("Create New", "CreatePurchase", new {
id = Model.Id})
然而,这假设ID已经传递到该页面的模型中的购买索引视图,这可能不是这种情况,但我不能告诉我,因为我无法看到您的购买索引操作。为您传递它的最简单方法是通过一个视图包,但如果您打算认真使用它,我建议不要将它用于您的网站。在视图中处理数据的正确方法是使用viewmodels。有很多可用的教程,例如https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-3
使用CRUD实现,您可以使用弱类型的视图包将id传递给页面。您的购买索引操作应如下所示:
public ActionResult Index(string id)
{
//this checks to see if an id has been passed to the action
if (id != null){
//this gets all purchases for a certain individual
var purchases = db.purchases.Where(i => i.ApplicationUserId == id).ToList()
//this gets the user id passed to the action and sticks it in a viewbag you can retrieve later on the page
ViewBag.UserID == id;
//returns the view with the list above
return View(purchases);
}
else{
//no id was passed to the action so the list is for all purchases
var purchases = db.purchases.ToList();
return View(purchases);
}
}
现在,在您的视图中,您需要修改创建新的购买操作以包含viewbag项目:
@Html.ActionLink("Create New", "CreatePurchase", new {
id = ViewBag.UserID})
更改您的创建购买操作以接受您传递的用户ID:
public ActionResult CreatePurchase(string id)
{
//puts the id in a viewbag to again be used by the view
ViewBag.UserID == id;
return View();
}
然后在您的创建购买视图中,您需要将视图包项目传递到模型中,您可以通过在表单内的某个位置隐藏字段来执行此操作:
@Html.Hidden("id", (string)ViewBag.UserID)
我将viewbag转换为字符串,因为假设您正在使用ASP NET标识,用户ID是一个字符串而ViewBag是一个动态对象,因此需要先将其转换为字符串,然后才能将其放入model.id空间有效。然后,这会将用户ID传递给后期操作,并且将创建特定于id的购买。
请记住,这是一种可怕的方式,这是一种可靠的方式,默认的CRUD东西虽然方便,但对于生产来说并不是很好,因为你直接访问模型而你需要使用弱类型的ViewBags来传输数据。它容易出错并且不安全。