URLهای Dynamic و Friendly با استفاده از MVC

شنبه 18 دی 1395

Dynamic URL یکی از ویژگی های فوق العاده در کار با MVC می باشد . Friendly URL حتی بهتر هم میباشد . مقاله ای که برای شما آماده کرده ایم ، راه مناسبی برای کار با Friendly URL ها می باشد .

URLهای Dynamic و Friendly با استفاده از MVC

خب ، حال به سراغ یکسری قرارداد ها می رویم :

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 :

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 که تمام درخواست ها را مدیریت میکند . 

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 :

public class RouteConfig   
{  
    public static void RegisterRoutes(RouteCollection routes)   
  {  
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  
        routes.MapRoute(  
            "IUrlRouteHandler",  
            "{*urlRouteHandler}").RouteHandler = new UrlRouteHandler();  
    }  
}  

Repository/IRouteRepository.cs :

public interface IRouteRepository: IDisposable   
{  
    IEnumerable < RouteData > Find(string url);  
} 

Repository/StaticRouteRepository.cs :

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 :

private static void RegisterServices(IKernel kernel)  
{  
    kernel.Bind < Repository.IRouteRepository > ().To < Repository.StaticRouteRepository > ();  
} 

آموزش asp.net mvc

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید