【发布时间】:2017-03-09 10:53:42
【问题描述】:
我正在创建一个将在我们公司的 Intranet 上使用的工作流工具。用户使用 Windows 身份验证进行身份验证,我设置了一个自定义 RoleProvider,将每个用户映射到一对角色。
一个角色表示他们的资历(访客、用户、高级用户、经理等),另一个角色表示他们的角色/部门(分析、开发、测试等)。 Analytics 中的用户能够创建一个请求,然后沿着链向上流动到开发等:
模型
public class Request
{
public int ID { get; set; }
...
public virtual ICollection<History> History { get; set; }
...
}
public class History
{
public int ID { get; set; }
...
public virtual Request Request { get; set; }
public Status Status { get; set; }
...
}
在控制器中,我有一个 Create() 方法,它将创建 Request 标头记录和第一个 History 项:
请求控制器
public class RequestController : BaseController
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create (RequestViewModel rvm)
{
Request request = rvm.Request
if(ModelState.IsValid)
{
...
History history = new History { Request = request, Status = Status.RequestCreated, ... };
db.RequestHistories.Add(history);
db.Requests.Add(request);
...
}
}
}
请求的每个进一步阶段都需要由链中的不同用户处理。该过程的一小部分是:
- 用户创建请求 [分析,用户]
- 经理授权请求 [分析,经理]
- 开发人员处理请求 [开发,用户]
目前我有一个 CreateHistory() 方法来处理流程的每个阶段。从视图中拉出新历史项目的状态:
// GET: Requests/CreateHistory
public ActionResult CreateHistory(Status status)
{
History history = new History();
history.Status = status;
return View(history);
}
// POST: Requests/CreateHistory
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateHistory(int id, History history)
{
if(ModelState.IsValid)
{
history.Request = db.Requests.Find(id);
...
db.RequestHistories.Add(history);
}
}
CreateHistory 视图本身将根据状态呈现不同的部分表单。我的意图是我可以为流程中的每个阶段使用一个通用的 CreateHistory 方法,使用 Status 作为参考来确定要渲染哪个部分视图。
现在,问题在于呈现和限制视图中的可用操作。我的 CreateHistory 视图变得臃肿,If 语句根据请求的当前状态确定操作的可用性:
@* Available user actions *@
<ul class="dropdown-menu" role="menu">
@* Analyst has option to withdraw a request *@
<li>@Html.ActionLink("Withdraw", "CreateHistory", new { id = Model.Change.ID, status = Status.Withdrawn }, null)</li>
@* Request manager approval if not already received *@
<li>...</li>
@* If user is in Development and the Request is authorised by Analytics Manager *@
<li>...</li>
...
</ul>
在正确的时间出现正确的操作是一件容易的事,但感觉是一种笨拙的方法,我不确定如何以这种方式管理权限。所以我的问题是:
我是否应该在 RequestController 中为流程的每个阶段创建一个单独的方法,即使这会导致很多非常相似的方法?
一个例子是:
public ActionResult RequestApproval(int id)
{
...
}
[MyAuthoriseAttribute(Roles = "Analytics, User")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RequestApproval(int id, History history)
{
...
}
public ActionResult Approve (int id)
{
...
}
[MyAuthoriseAttribute(Roles = "Analytics, Manager")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Approve (int id, History history)
{
...
}
如果是这样,我该如何处理在视图中呈现适当的按钮?我只希望一组有效的操作显示为控件。
抱歉发了这么长的帖子,任何帮助将不胜感激。
【问题讨论】:
-
使用具有
bool CanWithdraw等属性的视图模型(这些属性的值是根据当前用户设置的,并且状态会让您查看更清晰/更具可读性,尽管您仍然需要if状态)
标签: c# asp.net-mvc razor windows-authentication