2014-10-19 150 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()。在每種方法中,您都會檢查用戶是否有權執行操作,或僅返回用戶有權獲取的數據。