- دوشنبه ۱۸ بهمن ۹۵
- ۱۳:۴۳
Dynamic URL یکی از ویژگی های فوق العاده در کار با MVC می باشد . Friendly URL حتی بهتر هم میباشد . مقاله ای که برای شما آماده کرده ایم ، راه مناسبی برای کار با Friendly URL ها می باشد .
خب ، حال به سراغ یکسری قرارداد ها می رویم :
1. URLها باید درون یک Repository ذخیره شوند . این بدان معناست که ما قصد ایجاد و تغییر یک URL را در Repository خود داریم .
2. یک یا چندین URL میتوانند به یک Controller/Action اشاره داشته باشند . این بدان معناست که ما میخواهیم که URL ها نام داشته باشند .
3. اگر یک URL در Repository ما وجود ندارد ، سعی کنید با استفاده از رفتارهای پیش فرض Controllerها و Action ها در MVC این مسئله را مرتفع سازید . این بدان معناست که ، رفتار های پیش فرض MVC هنوز کار خواهند کرد .
4. URL نمی تواند در انتها شامل ID باشند . این بدان معناست که آخرین قسمت ، میتواند شامل یک ID Number طولانی باشد .
اول از همه ، MVC دارای ساختار درونی برای URL های dynamic و Friendly نمی باشد . شما باید کدهای خودتان رو بنویسید .
برای Solution ما به قسمت های زیر نیاز داریم :
1. پروژه MVC
2. یک کلاس برای مدیریت درخواست های Route
3. یک Route Repository
4. Controllerها و Viewها
ما از پایگاه داده برای ذخیره سازی این URL ها استفاده نمیکنیم ما از Repository Pattern و Dependency Resolver برای پیکربندی این استفاده میکنیم . بنابراین ، شما میتوانید در آینده یک پایگاه داده Reository ایجاد کنید .
کلاسی که یک URL را میشناسد :
Handlers/UrlHandler.cs :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
public sealed class UrlHandler {
public static UrlRouteData GetRoute( string url) {
url = url ? ? "/" ;
url = url == "/" ? "" : url;
url = url.ToLower();
UrlRouteData urlRoute = null ;
using ( var repository = DependencyResolver.Current.GetService < IRouteRepository > ()) {
var routes = repository.Find(url);
var route = routes.FirstOrDefault();
if (route != null ) {
route.Id = GetIdFromUrl(url);
urlRoute = route;
urlRoute.Success = true ;
} else {
route = GetControllerActionFromUrl(url);
urlRoute = route;
urlRoute.Success = false ;
}
}
return urlRoute;
}
private static RouteData GetControllerActionFromUrl( string url) {
var route = new RouteData();
if (! string .IsNullOrEmpty(url)) {
var segmments = url.Split( '/' );
if (segmments.Length >= 1) {
route.Id = GetIdFromUrl(url);
route.Controller = segmments[0];
route.Action = route.Id == 0 ? (segmments.Length >= 2 ? segmments[1] : route.Action) : route.Action;
}
}
return route;
}
private static long GetIdFromUrl( string url) {
if (! string .IsNullOrEmpty(url)) {
var segmments = url.Split( '/' );
if (segmments.Length >= 1) {
var lastSegment = segmments[segmments.Length - 1];
long id = 0;
long .TryParse(lastSegment, out id);
return id;
}
}
return 0;
}
} |
Route Handler که تمام درخواست ها را مدیریت میکند .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{ var routeData = requestContext.RouteData.Values;
var url = routeData[ "urlRouteHandler" ] as string ;
var route = UrlHandler.GetRoute(url);
routeData[ "url" ] = route.Url;
routeData[ "controller" ] = route.Controller;
routeData[ "action" ] = route.Action;
routeData[ "id" ] = route.Id;
routeData[ "urlRouteHandler" ] = route;
return new MvcHandler(requestContext);
} |
پیکربندی Route Handler :
App_Start/RouteConfig.cs :
1
2
3
4
5
6
7
8
9
10
11
|
public class RouteConfig
{ public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute(
"IUrlRouteHandler" ,
"{*urlRouteHandler}" ).RouteHandler = new UrlRouteHandler();
}
} |
Repository/IRouteRepository.cs :
1
2
3
4
|
public interface IRouteRepository: IDisposable
{ IEnumerable < RouteData > Find( string url);
} |
Repository/StaticRouteRepository.cs :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public class StaticRouteRepository: IRouteRepository
{ public void Dispose() {
}
public IEnumerable < RouteData > Find( string url) {
var routes = new List < RouteData > ();
routes.Add( new RouteData() {
RoouteId = Guid.NewGuid(),
Url = "how-to-write-file-using-csharp" ,
Controller = "Articles" ,
Action = "Index" });
routes.Add( new RouteData() {
RoouteId = Guid.NewGuid(),
Url = "help/how-to-use-this-web-site" ,
Controller = "Help" ,
Action = "Index" });
if (! string .IsNullOrEmpty(url)) {
var route = routes.SingleOrDefault(r => r.Url == url);
if (route == null ) {
route = routes.FirstOrDefault(r => url.Contains(r.Url)) ? ? routes.FirstOrDefault(r => r.Url.Contains(url));
}
if (route != null ) {
var newRoutes = new List < RouteData > ();
newRoutes.Add(route);
return newRoutes;
}
}
return new List < RouteData > ();
}
} |
ما دو URL ایجاد کردیم ، ک URL به HelpController اشاره دارد درحالی که دیگری به ArticleController اشاره میکند . برای پیکربندی Dependency Resolver ما از Ninject استفاده میکنیم .
App_Start/NinjectWebCommon.cs :
1
2
3
4
|
private static void RegisterServices(IKernel kernel)
{ kernel.Bind < Repository.IRouteRepository > ().To < Repository.StaticRouteRepository > ();
} |