MVC5:允许用户仅查看和编辑自己的信息

时间:2014-10-19 18:13:11

标签: c# asp.net-mvc-5 user-input user-defined-functions

我根据我的一张桌子创建了一个脚手架。我现在试图弄清楚如何允许用户仅查看/编辑与其用户ID相同的数据。

现在它显示该表中的所有数据,并允许编辑所有用户。我需要能够将其限制为仅当前登录的用户。

如果我能提供更多细节,请告诉我。

控制器

    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>

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

使用[授权]属性

装饰您的编辑操作
[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
{

}

然后,所有操作仅限于登录用户。这就是你要找的吗?

答案 2 :(得分:1)

我认为你遗漏了与Linq aka 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()。在每种方法中,您将检查用户是否有权执行操作或仅返回用户有权获取的数据。