asp.net-core - 嵌套功能文件夹层次结构中按操作名称的方法

标签 asp.net-core asp.net-core-mvc

我在这里阅读了有关功能文件夹实现的信息: https://msdn.microsoft.com/en-us/magazine/mt763233.aspx

我真的很喜欢按功能而不是文件类型进行分隔的想法。我正在开发一种增强的解决方案,它允许构建无限级别的功能层次结构。

我为此创建了一个非常简单的文件夹/文件组织逻辑。例如:

[Feature]
  [Auth]
    [Entity]
      User.cs
      Role.cs
    [Route]
      [Login]
         [Forgot]
            Forgot.cs
            Forgot.cshtml
            ForgotModel.cs
         Login.cs
         Login.cshtml
         LoginModel.cs
      Index.cs
      Index.cshtml
    Auth.cs

正如您所看到的,所有内容都放置在顶级功能文件夹下。该文件夹内有特定的功能文件夹 (Auth)。在其下有一个 Route 子文件夹,其中包含所有 Controller / View 的层次结构。

对于上面的示例,我已经实现了一个自定义路由逻辑,它为我提供了这些路由:

/Auth
/Auth/Login
/Auth/Login/Forgot

它有效,但我不知道我做得好还是完全错误。为了实现自定义路由,我简单地这样做了:

public void Apply(ControllerModel controller)
{
   //From the article I linked before:
   controller.Properties.Add("feature", 
     GetFeatureName(controller.ControllerType));

   //My custom route value implementation:
   controller.Selectors.Clear();

   var routePath = GetRoutePath(controller.ControllerType); //"auth/login/forgot"
   var routeAttr = new RouteAttribute(routePath);
   var selector = new SelectorModel 
     { 
       AttributeRouteModel = new AttributeRouteModel(routeAttr) 
     };

   controller.Selectors.Add(selector);

}
  • controller.Selectors 是应用自定义路由路径的好地方吗?
  • 在添加新内容之前真的需要 .Clear() 吗?

我没有找到任何关于controller.Selectors的文章。

我还喜欢实现对操作名称到http方法转换的支持,其中所有标准http动词操作名称(get、post、put、patch、delete)自动绑定(bind)到适当的http方法过滤器。例如:

public class Login : Controller
{
   public IAcionResult Get()
   {
      return View();
   }

   public IAcionResult Post(LoginModel model)
   {
      return Ok()
   }
}

我不想在只有 get/post 操作的地方使用 [HttpGet] 和 [HttpPost] 属性。我认为官方有一个解决方案,但我找不到。

最佳答案

我找到了一个看起来效果很好的解决方案。但我不太确定我刚刚用这个做了什么:

    public class ActionModelConvention : IActionModelConvention
    {
        private static readonly List<String> httpVerbs;

        static ActionModelConvention()
        {
            httpVerbs = new List<String> { "GET", "POST", "PUT", "PATCH", "DELETE" };
        }

        private readonly ActionParserOptions options;

        public ActionModelConvention(ActionParserOptions options)
        {
            this.options = options;
        }

        public void Apply(ActionModel action)
        {
            var upper = action.ActionName.ToUpper();
            var found = httpVerbs.FirstOrDefault(
                     e => upper.Length >= e.Length &&
                     e == upper.Substring(0, e.Length));

            if (found != null)
            {
                //action.Selectors.Clear(); //no need to clear...I think...

                var constraint = new Microsoft.AspNetCore.Mvc.Internal //> Internal!
                    .HttpMethodActionConstraint(new String[] { found });

                var selector = new SelectorModel();
                    selector.ActionConstraints.Add(constraint);

                action.Selectors.Add(selector);
            }
        }

我认为使用 Microsoft.AspNetCore.Mvc.Internal 命名空间中的任何内容都不是一个好主意。但我还没有找到其他方法。

有什么想法吗?

关于asp.net-core - 嵌套功能文件夹层次结构中按操作名称的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41920541/

相关文章:

javascript - ASP.NET Core Angular Spa 项目 JavaScriptServices 中没有 Guard 的提供程序

c# - 带前缀的区域中的 razor 页面 url

c# - 多次调用 con.execute() 是否重要?

c# - 在 AuthorizeAttribute Mvc Core Web Api 中获取 Controller 实例

c# - 替换 ASP.net MVC 核心中的 DefaultModelBinder

asp.net - 如何为 ASP.NET Core 应用程序配置 IIS 身份验证以使用 SQL Server

asp.net-core - ASP.NET Core 2 - 如何删除脚手架路由?

ajax - Ajax 刷新的 ViewComponent 替代方案

c# - AppSettings.json 用于 ASP.NET Core 中的集成测试

asp.net-mvc - 小写网址和尾部斜杠