2012-02-20 6 views
0

APS.NET 라우팅을 사용하여 요청이 AJAX 호출로 시작되었는지 여부에 따라 조건부로 개별 작업으로 라우팅합니까?요청이 AJAX 호출에서 발생한 경우 조건부로 액션으로 라우팅 하시겠습니까?

public ActionResult List() { return View(); } 

public ActionResult ListJSON() { return Content(...); } 

내가 같은 URL을 가지고 모두 작업을하고 싶습니다,하지만 ListJSON()가있는 경우 전화를받을해야합니다

컨트롤러에 예를 들어 나는 두 가지 작업을 할 수 있습니다 요청은 AJAX 호출로 시작되었습니다.

답변

0

그것은 당신이 쉽게 IRouteConstraint를 구현하여 자신의 경로 제약 조건을 정의 할 수 있음을 밝혀이를 위해 사용자 정의 경로를 사용할 수 있습니다. 이 같은

뭔가 :

public class AjaxRouteConstraint : IRouteConstraint { 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { 
     return httpContext.Request.IsAjaxRequest(); 
    } 
} 

그런 다음 단순히 경로에이 제약 조건을 사용합니다. 트릭은이 제약 조건을 가진 경로가 제약 조건이없는 경로 앞에 와야한다는 것입니다. 그렇지 않으면 ajax 경로가 호출되지 않습니다 (not-ajax 경로는 항상 일치합니다).

URL 생성과 관련하여 다음과 같은 결과가 발생할 수 있습니다. 그러나 나는 그것들을 크게 테스트하지 않았다.

2

코드가 동일 할 때 왜 2 개의 별도 동작을 사용합니까? 다른 결과입니다.

대해 어떻게 : 당신은 모든 컨트롤러 액션에서이 작업을 수행해야한다면

public ActionResult List() 
{ 
    var model = ... 
    if (Request.IsAjaxRequest()) 
    { 
     return View(model); 
    } 
    return Json(model); 
} 

분명히 이것은 신속하게 완전한 악몽이 될 것입니다.

[MyFilter] 
public ActionResult List() 
{ 
    var model = ... 
    return View(model); 
} 

사용자가 정의 할 수 있습니다 어디 MyFilterAttribute과 같이 :

그래서 당신은 사용자 지정 작업 필터에이 논리를 구체화 할 수

public class MyFilterAttribute: ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      var result = filterContext.Result as ViewResultBase; 
      if (result != null) 
      { 
       filterContext.Result = new JsonResult 
       { 
        Data = result.Model, 
        JsonRequestBehavior = JsonRequestBehavior.AllowGet 
       }; 
      } 
     } 
    } 
} 

또한 글로벌 작업으로이 작업 필터를 등록 할 수 있습니다 필터를 필요로하는 각 컨트롤러 및 작업에 넣지 않아도됩니다.


UPDATE :

바와 같이 코멘트 섹션에서 설명 IT는 영업 이익은 2 개 개의 다른 작업이 필요한 것으로 보인다.

public class MyRoute : Route 
{ 
    public MyRoute(string url, object defaults) : 
     base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) 
    { 
    } 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var rd = base.GetRouteData(httpContext); 
     if (rd == null) 
     { 
      return null; 
     } 

     if (httpContext.Request.IsAjaxRequest()) 
     { 
      rd.Values["action"] = rd.GetRequiredString("action") + "json"; 
     } 

     return rd; 
    } 
} 

Application_Start에 등록됩니다 :

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

    routes.Add(
     "Default", 
     new MyRoute(
      "{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ) 
    ); 
} 
+0

코드가 동일하지 않을 수 있습니다. 실행 된 쿼리 및 필요한 데이터가 크게 다를 수 있습니다. 테스트 가능성의 관점에서 볼 때, 두 가지 방법을 사용하는 것이 훨씬 깔끔하고, 요청을 기반으로 두 가지 방법을 사용하는 것이 좋습니다. –

+0

@JosephDaigle, 내 업데이트 참조. –

+0

그것은 영리한 생각입니다. 그러나 "action"값을 조작하고 있으므로 아웃 바운드 URL 생성에 어떤 영향을 미치는지 궁금합니다. –

관련 문제