2014-10-19 149 views
0

我创建了一个基于我的表之一的脚手架。我现在试图找出如何让用户只能查看/编辑与他们的用户ID相同的数据。MVC5:允许用户只查看和编辑自己的信息

现在它显示来自该表的所有数据并允许编辑所有用户。我需要能够仅限于当前登录的用户。

请让我知道,如果我可以提供任何更多的细节。

控制器

public class ClientViewStaffController : Controller 
{ 
    private TpsEntities db = new TpsEntities(); 

    // GET: ClientViewStaff 
    public ActionResult Index() 
    { 
     return View(db.staffTables.ToList()); 
    } 

    // GET: ClientViewStaff/Details/5 
    public ActionResult Details(int? id) 
    { 
     if (id == null) 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
     staffTable staffTable = db.staffTables.Find(id); 
     if (staffTable == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(staffTable); 
    } 

    // GET: ClientViewStaff/Create 
    public ActionResult Create() 
    { 
     return View(); 
    } 

    // POST: ClientViewStaff/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 = "staffID,staffFirstName,staffLastName,staffTitle,staffAddress,staffCity,staffState,staffZip,staffExperience,staffEducation,desiredSalary,staffProfession,staffAvailibity,staffPhoto,staffEmail,staffPhoneNum,userID")] staffTable staffTable) 
    { 
     if (ModelState.IsValid) 
     { 
      db.staffTables.Add(staffTable); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     return View(staffTable); 
    } 

    // GET: ClientViewStaff/Edit/5 
    public ActionResult Edit(int? id) 
    { 
     if (id == null) 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
     staffTable staffTable = db.staffTables.Find(id); 
     if (staffTable == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(staffTable); 
    } 

    // POST: ClientViewStaff/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 = "staffID,staffFirstName,staffLastName,staffTitle,staffAddress,staffCity,staffState,staffZip,staffExperience,staffEducation,desiredSalary,staffProfession,staffAvailibity,staffPhoto,staffEmail,staffPhoneNum,userID")] staffTable staffTable) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Entry(staffTable).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(staffTable); 
    } 

    // GET: ClientViewStaff/Delete/5 
    public ActionResult Delete(int? id) 
    { 
     if (id == null) 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
     staffTable staffTable = db.staffTables.Find(id); 
     if (staffTable == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(staffTable); 
    } 

    // POST: ClientViewStaff/Delete/5 
    [HttpPost, ActionName("Delete")] 
    [ValidateAntiForgeryToken] 
    public ActionResult DeleteConfirmed(int id) 
    { 
     staffTable staffTable = db.staffTables.Find(id); 
     db.staffTables.Remove(staffTable); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      db.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 
} 
} 

视图(Index.cshtml)

<table class="table"> 
<tr> 
    <th> 
     First Name 
    </th> 
    <th> 
     Last Name 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.staffState) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.staffExperience) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.staffEducation) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.desiredSalary) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.staffProfession) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.staffAvailibity) 
    </th> 
    <th></th> 
</tr> 

@foreach (var item in Model) 
{ 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffFirstName) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffLastName) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffState) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffExperience) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffEducation) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.desiredSalary) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffProfession) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.staffAvailibity) 
     </td> 
     <td> 
      @Html.ActionLink("Details", "Details", new { id = item.staffID }) | 

     </td> 
    </tr> 
} 

视图(Details.cshtml)

<div> 
<h4>Staff View</h4> 
<hr /> 
<dl class="dl-horizontal"> 
    <dt> 
     First Name 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffFirstName) 
    </dd> 

    <dt> 
     Last Name 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffLastName) 
    </dd> 

    <dt> 
     Title 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffTitle) 
    </dd> 

    <dt> 
     Address 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffAddress) 
    </dd> 

    <dt> 
     City 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffCity) 
    </dd> 

    <dt> 
     State 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffState) 
    </dd> 

    <dt> 
     Zip Code 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffZip) 
    </dd> 

    <dt> 
     Experience 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffExperience) 
    </dd> 

    <dt> 
     Education 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffEducation) 
    </dd> 

    <dt> 
     Salary 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.desiredSalary) 
    </dd> 

    <dt> 
     Profession 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffProfession) 
    </dd> 

    <dt> 
     Availability 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffAvailibity) 
    </dd> 

    <dt> 
     Photo 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffPhoto) 
    </dd> 

    <dt> 
     Email 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffEmail) 
    </dd> 

    <dt> 
     Phone Number 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.staffPhoneNum) 
    </dd> 

    <dt> 
     User ID 
    </dt> 

    <dd> 
     @Html.DisplayFor(model => model.userID) 
    </dd> 

</dl> 
</div> 
<p> 
    @Html.ActionLink("Edit", "Edit", new { id = Model.staffID }) | 
    @Html.ActionLink("Back to List", "Index") 
</p> 
+0

Couldyou提供您的域模型的一些细节? – 2014-10-19 18:18:10

+0

我从来没有解释过,所以请裸露在我身边。我设置视图,查看模型,控制器。我使用MS的MVC 5模板创建项目,并放弃了我不需要的东西。我使用个人身份验证,因为我已连接到我的SQL服务器(不是本地)。 Model.edmx在那里...让我知道你特别要求什么,稍微有点新鲜。 – slider1578 2014-10-19 18:24:57

+0

您是否使用asp.net身份框架进行身份验证?如果你很乐意为你的编辑按钮使用显示/隐藏选项,那么我可以给你简单的解决方案。 – DSR 2014-10-19 18:29:56

回答

1

您可以在Edit, Details GET操作中实现类似这样的操作。

var loggedInUser = GetUserId(HttpContext.Current.User.Identity.Name); 
if (id != loggedInUser) 
{ 
    return new HttpStatusCodeResult(HttpStatusCode.Forbidden); 
} 

您也可以将此从控制器中抽象出来并放入Action Filter中。 ASP.NET MVC中的动作过滤器是C#属性,用于区分诸如安全性等特定问题。

1

装饰用[授权] [编辑action属性

[Authorize] 
public ActionResult Edit(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 
    staffTable staffTable = db.staffTables.Find(id); 
    if (staffTable == null) 
    { 
     return HttpNotFound(); 
    } 
    return View(staffTable); 
} 

然后隐藏你的编辑操作在用户未记录。

首先将@using Microsoft.AspNet.Identity添加到您的视图的顶部,然后使用下面的代码进行查看。

@if (Request.IsAuthenticated) 
{ 
    @Html.ActionLink("Edit", "Edit", new { id = Model.staffID }) 
} 

编辑的评论

正如你知道你需要什么,限制未经身份验证的用户(非登录),你有我提到的使用[授权]属性。

你没有提到你在你的问题中完全限制访问。

如果要限制将所有内容访问到非身份验证用户,请按如下所示向您的控制器添加[授权]属性。

[Authorize] 
public class ClientViewStaffController : Controller 
{ 

} 

然后所有限制仅限登录用户的操作。那是你在找什么?

+0

有没有办法将结果限制为只有员工staffID。目前,我加载它从数据库中拉出所有人并给出编辑选项。我想限制结果仅限于登录人员。 有一个index.cshtml可以提取所有内容 – slider1578 2014-10-19 19:20:14

+0

已执行但未运行 – slider1578 2014-10-19 19:25:05

+0

检查已编辑的答案。 – DSR 2014-10-19 20:08:59

1

我认为你错过了一些关于实体框架与Linq又名Linq-to-entities的组合。

您可以使用Linq针对您的ef模型编写查询。详情请参阅MSDN

你基本上做的是在c#中编写一个查询,而实体框架将把这个查询转换成一个sql select语句,并对你的数据库运行这个查询。

使用这种方法你的问题变得非常简单。只需编写一个适合您需求的查询。像这样的东西可以工作

public IEnumerable<> FetchData(string userId) 
{ 
    return (
     from item in this.db.staffTables 
     where item.UserId == userId 
     select item 
     ).ToArray(); 
} 

一个更好的方法是隐藏你的实体框架模型从你的控制器和使用之间的存储库。该存储库通常会实现四个功能:GetData()', 'Create()', 'Update()Delete()。在每种方法中,您都会检查用户是否有权执行操作,或仅返回用户有权获取的数据。