我正在构建一个MVC 5应用程序,用于处理员工的日志记录时间等。我已经拥有一个完整的CRUD控制器,其中包含处理员工记录的视图,我有一个时间表控制器,用于为员工输入时间。
我想在Timesheets / Index视图中添加快捷方式,以便无需通过Admin / Index视图即可访问Employees模块。我还想直接从下级视图访问Employee Edit方法到Timesheets / Index。
本着DRY的精神,我可以重用Employee控制器逻辑并仍然可以回到我来自的地方,或者我是否需要复制Employee逻辑以使用不同的操作链接调用不同的视图? (我知道我可以通过使用部分模板来重用部分视图代码,但这还远远不够。)
好的回答我没有很好地解释我想做什么。以下是Employees控制器代码的一部分:
public partial class EmployeesController : Controller
{
//
// GET: /Employees/
public virtual ActionResult Index(int? page)
{
const int pageSize = 15;
var masterDataProxy = MasterDataChannelFactory.OpenChannel();
var employees = masterDataProxy.GetPagedEmployees((page ?? 0) * pageSize, pageSize);
masterDataProxy.CloseChannel();
ViewBag.HasPrevious = employees.HasPrevious;
ViewBag.HasMore = employees.HasNext;
ViewBag.CurrentPage = (page ?? 0);
return View(employees.Entities);
}
//
// GET: Employees/Edit/{id}
//[Authorize(Roles = "Admin")]
public virtual ActionResult Edit(int id)
{
var masterDataProxy = MasterDataChannelFactory.OpenChannel();
var employee = masterDataProxy.GetEmployee(id);
masterDataProxy.CloseChannel();
return View(employee);
}
//
// POST: Employees/Edit/{id}
[AcceptVerbs(HttpVerbs.Post), /*Authorize(Roles = "Admin")*/]
public virtual ActionResult Edit(int id, FormCollection formValues)
{
var masterDataProxy = MasterDataChannelFactory.OpenChannel();
var employee = masterDataProxy.GetEmployee(id);
masterDataProxy.CloseChannel();
if (null == employee)
{
return View(Views.NotFound);
}
try
{
UpdateModel(employee, formValues.ToValueProvider());
var adminProxy = AdminChannelFactory.OpenChannel();
adminProxy.AddUpdateEmployee(employee);
adminProxy.CloseChannel();
return RedirectToAction(Actions.Index());
}
catch (Exception ex)
{
ModelState.AddModelError("Employee", ex.Message);
return View(employee);
}
}
...
}
以下是管理员索引页面视图的一部分:
@{
ViewBag.Title = "Master Data Admin";
}
<h2>Master Data</h2>
<ul>
<li>@Html.ActionLink("Accounts", MVC.Account.Actions.Index())</li>
<li>@Html.ActionLink("Employees", MVC.Employees.Actions.Index())</li>
</ul>
然后我有一个时间表/索引视图,我想在其中添加另一个ActionLink给员工。我的问题是如何编写这个,以便我可以从任何一个视图(Admin / Index或Timesheets / Index)调用Employees Controller,更新服务上的Employees,然后返回到我的调用地点?
这似乎应该是一个已解决的问题,但我找不到任何接近我想做的事情。也许我需要重新解释一下这个问题?我想补充一点,我是MVC和网络编程的新手......
提前感谢您的任何帮助或指导。
戴夫
答案 0 :(得分:2)
如果我理解正确,您希望使用Employee
操作方法,而不必与Employee
视图绑定。
我会在您的应用程序中创建一个服务层(可能在一个单独的项目中)来处理Employee逻辑。然后,从您的Employee
控制器和Timesheets
控制器中调用此EmployeeService
服务。
这样,您的业务逻辑(EmployeeService
)就会与您的表示逻辑(Employee
和Timesheets
控制器及相关视图分开)。因此,您的控制器可以使用存储在EmployeeService
中的逻辑,并仍然使用自己的视图进行演示。
这实际上变成了一个双层设计。如果您的应用程序足够复杂,您甚至可以将数据访问逻辑分离到单独的层中 - 从而有效地使您的应用程序成为3层。
示例结构可能如下所示。
Presentation Layer Project (PL)
Controllers/
EmployeeController
TimesheetsController
Views/
Employee/
Timesheets/
...
Business Logic Layer Project (BLL)
ViewModels/
Services/
...
Data Access Layer Project (DAL)
Models/
Repositories/
...
(这里PL将引用BLL,BLL将引用DAL项目)。
这可能会提供更多信息:https://softwareengineering.stackexchange.com/questions/135724/separating-data-access-in-asp-net-mvc
答案 1 :(得分:0)
所有这些都很棒,但我认为我所要求的是如此简单,它只是假设我已经知道了。我绝对可以看到存储库和业务层的优势,并且会做出正确的事情。并将数据访问分离出控制器。但是,这并没有回答我的问题。
我需要做的是获取编辑屏幕的内容并创建局部视图。然后我需要为每个控制器调用创建一个单独的视图,其中包含使我回到我开始的位置的正确链接。
从管理员/员工/编辑调用的视图:
@model HawkTimeModel.Employee
@{
ViewBag.Title = "Edit Employee";
}
<h2>Edit</h2>
@{ Html.RenderPartial(MVC.Employees.Views._EmployeeForm); }
<p>
@Html.ActionLink("Back to List", MVC.Employees.Actions.Index())
</p>
从Timesheet / EditEmployee查看:
@model HawkTimeModel.Employee
@{
ViewBag.Title = "Edit Employee";
}
<h2>Edit</h2>
@{ Html.RenderPartial(MVC.Employees.Views._EmployeeForm); }
<p>
@Html.ActionLink("Back to Timesheet Overview", MVC.Timesheets.Actions.Index())
</p>
那就是&#34;缺失的链接&#34;。现在看,我不明白我是如何忽视这么简单的事情。
感谢您提供的意见,我的应用会因您的反馈而更好!
戴夫
答案 2 :(得分:0)
我的同事提出了另一种解决方案。修改模型,使其具有一个变量,用于定义调用视图的位置,并使用该变量确定页面底部的“返回链接”。然后主索引视图如下所示:
@using WebReporter.Models
@{ Html.RenderPartial(MVC.Employees.Views._IndexPartial); }
@if (Model.HomePage == HomePage.Timesheets)
{
<p>
@Html.ActionLink("Back to Timesheet Overview", MVC.TimeSheets.Index())
</p>
}
......并且这样称呼:
public virtual ActionResult Index(HomePage homePage, int? page)
{
return View(_masterDataService.GetPagedEmployees(homePage, page));
}
我最初构建了Employee视图和控制器的第二个副本,但它似乎违反了DRY原则,所以我正在尝试这个。
我无法相信这很难解释。我不可能是唯一一个想要从多个地方重用整个Controller + Views的人,所以我一定不好解释它......
感谢您的建议,我的代码将更适合您的输入!