C# 用于常见操作的最佳实践ASP.NET控制器
我有一个简短的问题 在许多示例中,我看到不返回任何视图或Partialview的控制器操作也添加在同一个控制器中-现在在我的情况下,我有多个控制器,需要运行相同的操作,例如C# 用于常见操作的最佳实践ASP.NET控制器,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个简短的问题 在许多示例中,我看到不返回任何视图或Partialview的控制器操作也添加在同一个控制器中-现在在我的情况下,我有多个控制器,需要运行相同的操作,例如 控制器A将运行操作A 控制器B将运行操作A 在控制器A和B中添加操作A看起来不正确 由于我正在使用AJAX调用动作A,因此,我希望它位于一个控制器中,以便于后期访问,尽管我不希望在两个控制器中添加相同的动作 我可以在控制器A中添加动作A,让控制器B访问从控制器A请求的相同动作,而不是我所想的 **如果我创建一个名为 通用
- 控制器A将运行操作A
- 控制器B将运行操作A
一个示例应用程序,其中包含个人和国家,因此个人模型对于所有国家都是相同的,但是每个国家都有不同的控制器,因此,如果管理员希望使用从true到false的字段来更新个人模型,那么他们将转到例如{USA}/索引控制器并将true切换为false。现在,对于{AUS}/Index和{China}/Index,这是相同的,所以在所有控制器中,更改为true/false的操作是相同的。为了实现这一点,我不想在所有国家/地区控制器中都添加Action Isemply-(想不出更好的例子)-您应该在两个控制器中都编写Action
a
。否则就会违反法律。最佳实践是将实现代码从控制器移动到服务层。例如,如果要为产品和子类别加载产品类别,则代码如下:
public interface ICategoryService
{
List<Category> LoadCategory();
}
public class CategoryService : ICategoryService
{
public List<Category> LoadCategory()
{
//code here
}
}
public class ProductController : Controller
{
private readonly ICategoryService _categoryService;
public ProductController()
{
_categoryService = <inject dependency here>;
}
public ActionResult GetCategory()
{
var category = _categoryService.LoadCategory();
}
}
public class SubCategoryController : Controller
{
private readonly ICategoryService _categoryService;
public SubCategoryController()
{
_categoryService = <inject dependency here>;
}
public ActionResult GetCategory()
{
var category = _categoryService.LoadCategory();
}
}
公共接口ICategoryService
{
列出LoadCategory();
}
公共类CategoryService:ICategoryService
{
公共列表LoadCategory()
{
//代码在这里
}
}
公共类ProductController:控制器
{
专用readonly ICategoryService(U类别服务);
公共产品控制员()
{
_类别服务=;
}
公共操作结果GetCategory()
{
var category=_categoryService.LoadCategory();
}
}
公共类子类别控制器:控制器
{
专用readonly ICategoryService(U类别服务);
公共子类别控制器()
{
_类别服务=;
}
公共操作结果GetCategory()
{
var category=_categoryService.LoadCategory();
}
}
这里的指导原则应该是关注点分离 如果ControllerA和ControllerB具有特定的业务逻辑,并且添加一个CommonActions控制器可以为共享数据提供一个良好的隔离家庭,那么这是一个很好的实践 没有更好的说明你的需求,虽然很难回答 一个稍微好一点的示例可能是order应用程序: 库存管理员 雇员控制员 您可能不希望CommomController具有以下方法:
GetStoreClosingHours(int storeNumber);
GetTotalSales(int employeeId);
GetEmployeeComps(int employeeId);
GetLastLogonTime(thisEmployee);
IoC和依赖注入可能也会得到回报,这取决于操作。任何控制器都可以调用以下方法:
GetStoreClosingHours(int storeNumber);
GetTotalSales(int employeeId);
GetEmployeeComps(int employeeId);
GetLastLogonTime(thisEmployee);
毕竟,这实际上是一套设计应用程序的原则,而最佳实践并不总是包装得非常整齐。我想说最重要的是,选择一些灵活、可扩展的东西,然后坚持下去。动作a实际做什么?但问题仍然存在:如果你从
ControllerA
或ControllerB
调用CommonAction
,你会回到哪里?我的意思是,您如何确定调用此CommonAction
的操作?我觉得这实际上是一个REST API和路由设计问题。你可以提供更多关于你的路线和你正在谈论的行动性质的信息将其提取到服务无法解决哪个特定问题?我阅读该示例的方式是,您无缘无故地复制控制器。根据你提供的信息,我会重新设计路线。这意味着,我将有一个带有route“{:country}/index”
,从route读取country
参数的控制器,然后从那里开始。首先,我不认为每个国家都需要控制器。同样,我非常肯定您可能会想重新考虑RESTAPI/路由设计,这是第一件事。更不用说,如果所有的“控制器”都是一样的(如果它们应该是分开的),那么它本身就是控制器的候选者,那么你不应该切换/复制视图而不是控制器吗?我将不得不在8个不同的控制器中重复我的3个操作-这不是额外的代码行吗-可能有更好的方法来处理这个问题?在8个不同的控制器上重复相同的操作听起来是不对的。您的想法是什么创建一个额外的服务层。我想我没有很好地解释它-对不起,我确实有一个服务层,但问题是我仍然必须从我的操作调用该服务层,例如在下面的代码中[HttpPost]public ActionResult GetAccess(string accessCode){var userToken=User.Identity.GetUserToken();string errorMessage;if(!\u userService.claimerccesscode(accessCode,userToken,out errorMessage))做点什么}
所以我仍然需要在每个控制器上添加操作A来访问服务层代码优化并不总是好的。优化后,您可能会理解您的代码。但是其他人必须面对理解代码的困难。好的,谢谢,是的,我所有的代码都在控制器之外,我只是从控制器操作调用它。这是一个有个人和国家的示例应用程序,所以除了我们之外,所有国家的人模型都是相同的