Development Tip

ASP.NET MVC CMS 용 데이터베이스의 동적 경로

yourdevel 2020. 11. 14. 11:09
반응형

ASP.NET MVC CMS 용 데이터베이스의 동적 경로


기본적으로 ASP.NET MVC를 사용하여 구축 한 CMS 백엔드가 있으며 이제 프런트 엔드 사이트로 이동 중이며 입력 한 경로에 따라 cms 데이터베이스에서 페이지를로드 할 수 있어야합니다.

따라서 사용자가 domain.com/students/information을 입력하면 MVC는 페이지 테이블에서 학생 / 정보와 일치하는 영구 링크가있는 페이지가 있는지 확인합니다. 그렇다면 페이지 컨트롤러로 리디렉션 한 다음 페이지를로드합니다. 데이터베이스에서 데이터를 가져 와서 표시 할보기로 반환합니다.

지금까지 모든 경로를 잡으려고 시도했지만 두 개의 URL 세그먼트에서만 작동하므로 / students / information이지만 / students / information / fall은 아닙니다. 이 작업을 수행하는 방법에 대해 온라인에서 아무것도 찾을 수 없으므로 여기에서 물어볼 것이지만 ASP.NET MVC cms를 찾아서 오픈 소스하고 코드를 분석하기 전에.

여기까지 제가 가지고있는 경로 구성이 있지만 더 나은 방법이 있다고 생각합니다.

 public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Default route to handle core pages
        routes.MapRoute(null,"{controller}/{action}/{id}",
                        new { action = "Index", id = UrlParameter.Optional },                  
                        new { controller = "Index" }
        );

        // CMS route to handle routing to the PageController to check the database for the route.


        var db = new MvcCMS.Models.MvcCMSContext();
        //var page = db.CMSPages.Where(p => p.Permalink == )
        routes.MapRoute(
            null,
            "{*.}",
            new { controller = "Page", action = "Index" }
        );          
    }

누구든지 최대 3 개의 URL 세그먼트를 사용하여 데이터베이스에서 CMS 페이지를로드하는 방법에 대해 올바른 방향을 알려줄 수 있고 컨트롤러와 작업이 미리 정의 된 핵심 페이지를로드 할 수 있습니다.


제약 조건을 사용하여 기본 라우팅 논리를 재정의할지 여부를 결정할 수 있습니다.

public class CmsUrlConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var db = new MvcCMS.Models.MvcCMSContext();
        if (values[parameterName] != null)
        {
            var permalink = values[parameterName].ToString();
            return db.CMSPages.Any(p => p.Permalink == permalink);
        }
        return false;
    }
}

경로 정의에서 사용하십시오.

routes.MapRoute(
    name: "CmsRoute",
    url: "{*permalink}",
    defaults: new {controller = "Page", action = "Index"},
    constraints: new { permalink = new CmsUrlConstraint() }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

이제 '페이지'컨트롤러에 '인덱스'액션이있는 경우

public ActionResult Index(string permalink)
{
    //load the content from db with permalink
    //show the content with view
}
  1. 모든 URL은 첫 번째 경로에서 포착되고 제약 조건에 의해 확인됩니다.
  2. 영구 링크가 db에 존재하는 경우 URL은 페이지 컨트롤러의 색인 작업에 의해 처리됩니다.
  3. 그렇지 않으면 제약 조건이 실패하고 URL이 기본 경로로 대체됩니다 (프로젝트에 다른 컨트롤러가 있는지 여부와 404 논리를 결정하는 방법을 알 수 없습니다).

편집하다

To avoid re querying the cms page in the Index action in Page controller, one can use the HttpContext.Items dictionary, like

in the constraint

var db = new MvcCMS.Models.MvcCMSContext();
if (values[parameterName] != null)
{
    var permalink = values[parameterName].ToString();
    var page =  db.CMSPages.Where(p => p.Permalink == permalink).FirstOrDefault();
    if(page != null)
    {
        HttpContext.Items["cmspage"] = page;
        return true;
    }
    return false;
}
return false;

then in the action,

public ActionResult Index(string permalink)
{
    var page = HttpContext.Items["cmspage"] as CMSPage;
    //show the content with view
}

hope this helps.


I use simpler approach that doesn't require any custom router handling. Simply create a single/global Controller that handles a few optional parameters, then process those parameters as you like:

//Route all traffic through this controller with the base URL being the domain 
[Route("")]
[ApiController]
public class ValuesController : ControllerBase
{
    //GET api/values
    [HttpGet("{a1?}/{a2?}/{a3?}/{a4?}/{a5?}")]
    public ActionResult<IEnumerable<string>> Get(string a1 = "", string a2 = "", string a3 = "", string a4 = "", string a5 = "")
    {
        //Custom logic processing each of the route values
        return new string[] { a1, a2, a3, a4, a5 };
    }
}

Sample output at domain.com/test1/test2/test3

["test1","test2","test3","",""]

참고URL : https://stackoverflow.com/questions/16026441/dynamic-routes-from-database-for-asp-net-mvc-cms

반응형