ابتدا مدل و منبع داده نمونه زیر را در نظر بگیرید:
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;
}
}
}
به همراه کنترلر زیر برای نمایش لیست اطلاعات و همچنین نمایش جزئیات یک issue انتخابی:
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);
}
}
}
و View زیر کار نمایش لیست بازخوردهای یک پروژه را انجام میدهد:
@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
سؤال: آیا میشود این لینکها را کمی زیباتر و SEO Friendlyتر کرد؟
برای مثال آنرا به نحو زیر نمایش داد:
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 جدید به نام دلخواه IssueDetails پیش از route پیش فرض، تعریف شده است.
این route جدید با مسیرهایی مطابق پارامتر url آن تطابق خواهد یافت. پس از آن کوئری استرینگ متناظر با issueId را به پارامتر issueId اکشن متدی به نام Details و کنترلر Home ارسال خواهد کرد؛ به همین ترتیب در مورد projectId عمل خواهد شد.
ضمنا در url نهایی نمایش داده شده، دیگر اثری از کوئری استرینگها نبوده و برای نمونه در این حالت، اولین لینک نمایش داده شده شکل زیر را خواهد داشت:
http://localhost:1036/Home/Details/0/0
البته باید دقت داشت، یک چنین اصلاح خودکاری تنها در حالت استفاده از متد Html.ActionLink
رخ میدهد و اگر Urlها را دستی ایجاد کنید، تغییری را مشاهده نخواهید کرد.