在ASP.NET MVC中设置备用控制器文件夹位置

13
我们可以创建一个使用默认文件夹约定的MVC应用程序,但我们想设置备用的“Services”文件夹,并且仅用于返回xml或json的Web服务的控制器。
因此,“/Services/Tasks/List”路由到“/Services/TaskService.cs”,而“/Tasks/List”则路由到标准的“/Controllers/TaskController.cs”。
我们希望将服务控制器与视图控制器分开。我们认为区域或使用另一个项目都不适用。应该如何最好地解决这个问题?
4个回答

14

你可以使用Routing并将控制器放在不同的命名空间中来实现此功能。MapRoute允许您指定哪个命名空间对应于一个路由。

示例

假设有以下这些控制器:

namespace CustomControllerFactory.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
           return new ContentResult("Controllers");
        }
    }
}

namespace CustomControllerFactory.ServiceControllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
           return new ContentResult("ServiceControllers");
        }
    }
}

以下是路由设置

 routes.MapRoute(
           "Services",
           "Services/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new string[] { "CustomControllerFactory.ServiceControllers" } // Namespace
        );


        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new string[] { "CustomControllerFactory.Controllers"} // Namespace
        );

您应该期望以下响应

/Services/Home

ServiceController

/Home

Controllers


你可以这样做并返回一个ContentResult或任何非视图结果,只要记住如果你决定返回任何类型的视图,你将需要创建一个自定义视图引擎。 - Ahmad
1
是的,上面的答案只解决了问题的路由部分。如果您返回一个ViewResult,您需要修改选择视图的约定。 如果您选择实现自定义视图引擎,这个可能会有所帮助。 您还可以尝试基于一个重写View()的基类来实现您的服务控制器,并在那里实现您的约定。 知道您采取哪种方法会很好。 - CGK

2
在Asp.Net Core中:我使用了AreaFeature库的ServiceCollectionExtensions。
首先设置您的中间件;
    services.AddMvc(options => 
        options.EnableEndpointRouting = false).
        AddFeatureFolders().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Latest);

在扩展中:
return AddFeatureFolders(services, new FeatureFolderOptions());

根据您的要求进行实现:

 public static IMvcBuilder AddFeatureFolders(this IMvcBuilder services, FeatureFolderOptions options)
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            if (options == null)
                throw new ArgumentException(nameof(options));

            var expander = new FeatureViewLocationExpander(options);

            services.AddMvcOptions(o => o.Conventions.Add(new FeatureControllerModelConvention(options)))
                .AddRazorOptions(o =>
                {
                    o.ViewLocationFormats.Clear();
                    o.ViewLocationFormats.Add(options.FeatureNamePlaceholder + @"\{0}.cshtml");
                    o.ViewLocationFormats.Add(options.FeatureNamePlaceholder + @"\_Views\{0}.cshtml");
                    o.ViewLocationFormats.Add(options.FeatureFolderName + @"\Shared\{0}.cshtml");
                    o.ViewLocationFormats.Add(options.DefaultViewLocation);

                    o.ViewLocationExpanders.Add(expander);
                });

            return services;
        }

在我的情况下,我更喜欢在功能文件夹中为视图创建一个单独的_View文件夹。
~/Features/Account/_Views/login.cshtml
~/Features/Account/AccountController.cs
~/Features/Account/AccountModel.cs

0

如果您看到黄色文件夹名称,请在根目录中添加文件夹名称

之后,您必须将routes.MapRoute修改为"App_Start > RouteConfig"

修改默认路由

routes.MapRoute(
          "Default",
          "{controller}/{action}/{id}",
          new { controller = "Home", action = "Index", id =     UrlParameter.Optional },
          new string[] { "mvcPartialView.HomeController" } // Namespace 
      );

并添加此内容

routes.MapRoute(
       "ApiControllerOne", // Name of folder
       "ApiControllerOne/{controller}/{action}/{id}",
        new { controller = "ApiFactory", action = "callFactoryOne", id = UrlParameter.Optional },
        new string[] { "mvcPartialView.ApiControllerOne" } // Namespace
    );

0

4
链接已损坏 :( - JDandChips

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接