【问题标题】:Custom route and action names in asp.net core mvcasp.net core mvc 中的自定义路由和操作名称
【发布时间】:2020-12-03 10:14:30
【问题描述】:

我正在开发一个 Asp.Net Core 3.1 MVC 项目,并希望更改 url 中的一些控制器和操作名称。 几乎所有答案都与 .net core API 或 mvc(没有 .net core)有关,但我想在 Asp.Net Core Mvc 应用程序中进行。

例如,控制器:

public class ProductCategoriesController : Controller
{

    private readonly DBContext _context;

    public async Task<IActionResult> Details(int? id)
    {
        // Some Codes ...
    }
}

我想要做的是,当我将操作称为“详细信息”时,网址将类似于 (http://domain/product-category/power-tools),其中“电动工具”是类别之一,但作为在 Asp.Net Core MVC 中常见的是 (http://domain/ProductCategories/Details/1)。

我尝试更改控制器前缀名称和操作名称,但它不起作用。 我还尝试在启动时定义新的路由端点,如下所示,但都不起作用。

endpoints.MapControllerRoute(
    name: "category",
    pattern: "product-category/{*title}",
    defaults: new { controller = "ProductCategories", action = "Details" });

是否可以在不使用 Api 控制器的情况下更改操作名称和控制器名称?我怎么做?谢谢

【问题讨论】:

    标签: c# asp.net-core model-view-controller


    【解决方案1】:

    您也应该在模式中添加id 参数,因为您的操作有一个可为空的参数。

    endpoints.MapControllerRoute(
                    name: "category",
                    pattern: "product-category/{title}/{id?}",
                    defaults: new { controller = "ProductCategories", action = "Details" });
    

    更新:添加了一个简单的测试屏幕

    【讨论】:

      【解决方案2】:

      我想做的最好的解决方案不是在启动时改变路线。 特别感谢这篇文章的作者https://rehansaeed.com/seo-friendly-urls-asp-net-core/,我这样改变了我的动作,它已经完成了。

          [HttpGet("ProductCategory/{id}/{title}", Name = "ProductsRelatedToCategory")]
          public async Task<IActionResult> ProductsRelatedToCategory(int? id, string title)
          {
              if (id == null || !await _productCategoryRepo.IsExists((int)id))
              {
                  return NotFound();
              }
      
              var langId = _languageRepository.GetByCode(LanguageCode).Result.Id;
      
              var productsRelatedToThisCategory = await _productRepo.GetByCategoryId((int)id, langId);
              var productCategory = await _productCategoryRepo.GetById((int)id);
              var allCategories = await _productCategoryRepo.GetAll(2);
      
              ViewData["ProductCategory"] = productCategory;
              ViewData["AllProductCategories"] = allCategories.ToList();
      
              string friendlyTitle = FriendlyUrlHelper.GetFriendlyTitle(productCategory.Title);
      
              if (!string.Equals(friendlyTitle, title, StringComparison.Ordinal))
              {
                  return this.RedirectToRoutePermanent("ProductsRelatedToCategory", new { id = id, title = friendlyTitle });
              }
      
              return View("~/Views/Products/ProductsRelatedToCategory.cshtml", productsRelatedToThisCategory.ToList());
          }
      

      并调用操作:

      <a asp-action="ProductsRelatedToCategory" asp-controller="ProductCategories" asp-route-id="14" asp-route-title="Power Tools"><b>Power tools</b></a>
      

      【讨论】:

        【解决方案3】:

        Net .Core 有一点不同的风格,试试这个,你可能还需要更新你的Startup.cs

        [Route("/productcategories/")]
        public class ProductCategoriesController : Controller
        {
        
            private readonly DBContext _context;
        
            [HttpGet("details/{id}")] // here the id is not optional but you can set it to be
            public async Task<IActionResult> Details(int id) // id
            {
                // Some Codes ...
            }
        }
        

        并添加到Startup.cs

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddDbContext<TodoContext>(opt =>
                   opt.UseInMemoryDatabase("TodoList"));
                services.AddControllers();
            }
        
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
        
                app.UseHttpsRedirection();
        
                app.UseRouting();
        
                app.UseAuthorization();
        
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        

        阅读有关 Asp.Net Core 3.1 MVC 约定的更多信息

        https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-26
          • 1970-01-01
          • 2017-01-04
          • 2020-06-29
          • 2016-12-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多