我正在尝试限制用户条目,以便只有该特定用户才能看到他们的条目,而不是其他任何人。换句话说,毕竟我已经完成了,我的应用程序仍会显示所有输入的条目;任何用户都可以看到这些条目。
我通过使用Entity Framework中的Code First约定将我的Expenses表中的外键引用到我的AspNetUsers的主键创建了一对多的关系,但是,当我以不同的用户身份登录时,我我仍然可以看到其他用户输入的条目(费用)。
我不确定问题是出在我的视图,模型还是控制器中。
以下是我目前的代码:
IdentityModel :
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Expenses = new List<Expense>();
}
[Required]
public string Fullname { get; set; }
[Required]
public string Province { get; set; }
[Required]
public string Company { get; set; }
public virtual ICollection<Expense> Expenses { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("PacificPetEntities", throwIfV1Schema: false)
{
}
public IDbSet<Expense> Expenses { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
费用模型:
public class Expense : IValidatableObject
{
public Expense() { }
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
public string Category { get; set; }
public string Description { get; set; }
[Required]
[Display(Name = "Gross Amount")]
public double GrossAmount { get; set; }
[Required]
[Display(Name = "Tax Amount")]
public double TaxAmount { get; set; }
[Required]
[Display(Name = "Net Amount")]
public double NetAmount { get; set; }
public int Mileage { get; set; }
[Display(Name = "Mileage Rate")]
public double MileageRate { get; set; }
[Required]
[Display(Name = "Date Submitted")]
public DateTime? DateSubmitted { get; set; }
[Required]
[Display(Name = "Expense Date")]
public DateTime? ExpenseDate { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser ApplicationUser { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Category == "Auto - Mileage" && Mileage == 0)
{
yield return new ValidationResult("You must enter a mileage amount if the chosen category is mileage.");
}
}
}
控制器:
public class ExpensesController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Expenses
[Authorize]
public ActionResult Index()
{
var expenses = db.Expenses.Include(e => e.ApplicationUser);
return View(expenses.ToList());
}
// GET: Expenses/Details/5
[Authorize]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Expense expense = db.Expenses.Find(id);
if (expense == null)
{
return HttpNotFound();
}
return View(expense);
}
// GET: Expenses/Create
[Authorize]
public ActionResult Create()
{
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname");
return View();
}
// POST: Expenses/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]
[Authorize]
public ActionResult Create([Bind(Include = "ID,Category,Description,GrossAmount,TaxAmount,NetAmount,Mileage,MileageRate,DateSubmitted,ExpenseDate,UserId")] Expense expense)
{
if (ModelState.IsValid)
{
db.Expenses.Add(expense);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname", expense.UserId);
return View(expense);
}
// GET: Expenses/Edit/5
[Authorize]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Expense expense = db.Expenses.Find(id);
if (expense == null)
{
return HttpNotFound();
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname", expense.UserId);
return View(expense);
}
// POST: Expenses/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]
[Authorize]
public ActionResult Edit([Bind(Include = "ID,Category,Description,GrossAmount,TaxAmount,NetAmount,Mileage,MileageRate,DateSubmitted,ExpenseDate,UserId")] Expense expense)
{
if (ModelState.IsValid)
{
db.Entry(expense).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Fullname", expense.UserId);
return View(expense);
}
// GET: Expenses/Delete/5
[Authorize]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Expense expense = db.Expenses.Find(id);
if (expense == null)
{
return HttpNotFound();
}
return View(expense);
}
// POST: Expenses/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult DeleteConfirmed(int id)
{
Expense expense = db.Expenses.Find(id);
db.Expenses.Remove(expense);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
Index.cshtml :
@model IEnumerable<PacificPetExpenses.Models.Expense>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.ApplicationUser.Fullname)
</th>
<th>
@Html.DisplayNameFor(model => model.Category)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.GrossAmount)
</th>
<th>
@Html.DisplayNameFor(model => model.TaxAmount)
</th>
<th>
@Html.DisplayNameFor(model => model.NetAmount)
</th>
<th>
@Html.DisplayNameFor(model => model.Mileage)
</th>
<th>
@Html.DisplayNameFor(model => model.MileageRate)
</th>
<th>
@Html.DisplayNameFor(model => model.DateSubmitted)
</th>
<th>
@Html.DisplayNameFor(model => model.ExpenseDate)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.ApplicationUser.Fullname)
</td>
<td>
@Html.DisplayFor(modelItem => item.Category)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.GrossAmount)
</td>
<td>
@Html.DisplayFor(modelItem => item.TaxAmount)
</td>
<td>
@Html.DisplayFor(modelItem => item.NetAmount)
</td>
<td>
@Html.DisplayFor(modelItem => item.Mileage)
</td>
<td>
@Html.DisplayFor(modelItem => item.MileageRate)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateSubmitted)
</td>
<td>
@Html.DisplayFor(modelItem => item.ExpenseDate)
</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>
请帮忙。
谢谢。
答案 0 :(得分:1)
使用当前用户ID选择您的Expenses
。像这样。
// GET: Expenses
[Authorize]
public ActionResult Index()
{
var expenses = db.Expenses.Where(e => e.UserId == User.Identity.GetUserId());
return View(expenses.ToList());
}
答案 1 :(得分:0)
我找到了答案。 Padhraic非常接近,但他的回答帮助我解决了我的问题。
在我的控制器中,我有:
jq -r 'if .StatusInfos != null then
.StatusInfos[] as $info | {
RepStatus: $info.Status,
RepStatusType: $info.StatusType,
ReadReplicaSourceDBInstanceIdentifier,
DBInstanceIdentifier }
else . end'
相反,这应该是:
public ActionResult Index()
{
var expenses = db.Expenses.Include(e => e.ApplicationUser);
return View(expenses.ToList());
}
根据Stephen Muecke对我的问题的评论, db.Expenses.Include(e =&gt; e.ApplicationUser)正在返回我数据库中的所有行。相反,我需要将结果过滤到当前用户。