ابتدا مدل و منبع داده نمونه زیر را در نظر بگیرید:
به همراه کنترلر زیر برای نمایش لیست اطلاعات و همچنین نمایش جزئیات یک issue انتخابی:
و View زیر کار نمایش لیست بازخوردهای یک پروژه را انجام میدهد:
در این حالت اگر پروژه را اجرا کنیم، هر لینک نمایش داده شده، چنین فرمی را خواهد داشت:
سؤال: آیا میشود این لینکها را کمی زیباتر و SEO Friendlyتر کرد؟
برای مثال آنرا به نحو زیر نمایش داد:
پاسخ: بلی. برای اینکار تنها کافی است از امکانات مسیریابی استفاده کنیم:
در اینجا یک route جدید به نام دلخواه IssueDetails پیش از route پیش فرض، تعریف شده است.
این route جدید با مسیرهایی مطابق پارامتر url آن تطابق خواهد یافت. پس از آن کوئری استرینگ متناظر با issueId را به پارامتر issueId اکشن متدی به نام Details و کنترلر Home ارسال خواهد کرد؛ به همین ترتیب در مورد projectId عمل خواهد شد.
ضمنا در url نهایی نمایش داده شده، دیگر اثری از کوئری استرینگها نبوده و برای نمونه در این حالت، اولین لینک نمایش داده شده شکل زیر را خواهد داشت:
البته باید دقت داشت، یک چنین اصلاح خودکاری تنها در حالت استفاده از متد Html.ActionLink رخ میدهد و اگر Urlها را دستی ایجاد کنید، تغییری را مشاهده نخواهید کرد.
using System.Collections.Generic; namespace TestRouting.Models { public class Issue { public int IssueId { set; get; } public int ProjectId { set; get; } public string Title { set; get; } public string Body { set; get; } } public static class IssuesDataSource { public static IList<Issue> CreateDataSource() { var results = new List<Issue>(); for (int i = 0; i < 100; i++) { results.Add(new Issue { IssueId = i, ProjectId = i, Body = "Test...", Title = "Title " + i }); } return results; } } }
using System.Linq; using System.Web.Mvc; using TestRouting.Models; namespace TestRouting.Controllers { public class HomeController : Controller { public ActionResult Index() { var issuesList = IssuesDataSource.CreateDataSource(); return View(issuesList); //show the list } public ActionResult Details(int issueId, int projectId) { var issue = IssuesDataSource.CreateDataSource() .Where(x => x.IssueId == issueId && x.ProjectId == projectId) .FirstOrDefault(); return View(issue); } } }
@model IEnumerable<TestRouting.Models.Issue> @{ ViewBag.Title = "Index"; } <h2> Issues</h2> <ul> @foreach (var item in Model) { <li> @Html.ActionLink(linkText: item.Title, actionName: "Details", controllerName: "Home", routeValues: new { issueId = item.IssueId, projectId = item.ProjectId }, htmlAttributes: null) </li> } </ul>
http://localhost:1036/Home/Details?issueId=0&projectId=0
برای مثال آنرا به نحو زیر نمایش داد:
http://localhost:1036/Home/Details/0/0
using System.Web.Mvc; using System.Web.Routing; namespace TestRouting { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "IssueDetails", url: "Details/{issueId}/{projectId}", //تطابق با یک چنین مسیرهایی defaults: new { controller = "Home", //کنترلری که این نوع مسیرها را پردازش خواهد کرد action = "Details", // اکشن متدی که نهایتا پارامترها را دریافت میکند issueId = UrlParameter.Optional, //این خواص نیاز است هم نام پارامترهای اکشن متد تعریف شوند projectId = UrlParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } }
این route جدید با مسیرهایی مطابق پارامتر url آن تطابق خواهد یافت. پس از آن کوئری استرینگ متناظر با issueId را به پارامتر issueId اکشن متدی به نام Details و کنترلر Home ارسال خواهد کرد؛ به همین ترتیب در مورد projectId عمل خواهد شد.
ضمنا در url نهایی نمایش داده شده، دیگر اثری از کوئری استرینگها نبوده و برای نمونه در این حالت، اولین لینک نمایش داده شده شکل زیر را خواهد داشت:
http://localhost:1036/Home/Details/0/0