2010-08-04 3 views
0

ASP.NET MVC2 앱에 REST 비헤이비어를 작성하려고하지만 원하는대로 해당 경로를 작동시키는 방법을 찾지 못했습니다.ASP.NET MVC에서 요청한 데이터 유형을 기반으로하는 라우팅

/Users/Get/1 <- returns a regular HTML-based reply 
/Users/Get.xml/1 <- returns the data from Get as XML 
/Users/Get.json/1 <- returns the data as JSon 

나는이 같은 경로를 설정하려고했습니다 :

내 라우팅을하고 싶습니다

은 다음과 같이 작동합니다

routes.MapRoute("Rest", 
"{controller}/{action}{format}/{id}" (...) 

을하지만 내가 사이에 구분이 필요 불만 {동작} 및 {형식}도

다음

routes.MapRoute("Rest", 
    "{controller}/{action}.{format}/{id}" (...) 

은/Users/Get/1을 유효하지 않게 만듭니다 (/Users/Get./1은 받아 들일 수 없습니다)

어떤 제안이 있습니까?

------------- EDIT -------------------------------- ----

내가 지금 하나 개의 솔루션을 가지고,하지만 난 그것으로 정말 행복하지 않다 :

이것은 또한 /Users/Get.whateverFormat/1와 모두 작동
routes.MapRoute(
      "DefaultWithFormat", // Route name 
      "{controller}/{action}.{format}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", format = "HTML", id = UrlParameter.Optional } // Parameter defaults 
     ); 
     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
     ); 

/사용자/받기/1

이유는 내가/사용자/가져 오기/1 (.format없이)하면 첫 번째 경로를 건너 뛴 다음 형식을 포함하지 않는 다음으로 이동한다는 것입니다. 내가 ActionFilterAttribute 만든 반환을 처리하고이 같은 OnActionExecuted 방법을 재정의하려면 :

var type = filterContext.RouteData.Values["format"]; 
if (type != null && attributes != null) 
{ 
    if (type == "HTML") return; 
    if (type.ToString().ToLower() == "xml" && attributes.Any(a => a.AllowedTypes.Any(a2 => a2 == ResponseType.XML))) 
    { 
     filterContext.Result = new XmlResult(filterContext.Controller.ViewData.Model); 
     filterContext.HttpContext.Response.Clear(); 
     filterContext.HttpContext.Response.ContentType = "text/xml"; 
     return; 
    } 
    if (type.ToString().ToLower() == "json" && attributes.Any(a => a.AllowedTypes.Any(a2 => a2 == ResponseType.JSON))) 
    { 
     filterContext.Result = new JsonResult() { Data = (filterContext.Controller.ViewData.Model), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; 
     filterContext.HttpContext.Response.Clear(); 
     filterContext.HttpContext.Response.ContentType = "text/json"; 
     return; 
    } 
} 

을 그리고 나는 또한 그들이 허용해야 returnType이 무엇인지와 행동 장식 나를 수있는 ResponseTypeAttribute 있습니다

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] 
public sealed class ResponseTypeAttribute : Attribute 
{ 
    List<ResponseType> allowedTypes; 

    public List<ResponseType> AllowedTypes 
    { 
     get { return allowedTypes; } 
     set { allowedTypes = value; } 
    } 

    public ResponseTypeAttribute(params ResponseType[] allowedTypes) 
    { 
     this.allowedTypes = new List<ResponseType>(); 
     this.allowedTypes.AddRange(allowedTypes); 
    } 


} 

public enum ResponseType 
{ 
    XML, JSON 
} 

XmlResult는 단순한 개체 serializer입니다.

답변

0

브래드 윌슨 (Brad Wilson)이 고급 ASP.NET MVC2라는 제목으로 이야기를 나눴는데, 여기서 그는 원하는 작업을 정확하게 수행하는 방법을 보여주었습니다.

http://bradwilson.typepad.com/blog/talks.html

(. 그것은 페이지의 첫 번째 이야기이고, 나는 잘 편안한 URL을 기억한다면 이야기의 첫 번째 주제)

+0

슬라이드가 다음과 같이 말하기 때문에 실제로 도움이되지 않습니다. "데모 - REST와 유사한 URL 지원"예제 코드에는 예제가 없습니다. –

+0

이 비디오를 보았습니다 : http : //events.boostweb20 .com/Events/SeattleCodeCamp2010/# state = sessionCode % 242003-4. 시간이 있으면 봐. :) 그것은 편안한 URL에 대한 데모를 보여줍니다 .... – apolka

+0

이제는 꽤 달콤한 해결책입니다! : D –

0

있다 : 당신은 슬라이드와 여기 예제 코드를 다운로드 할 수 있습니다 {format}의 기본값을 html으로 설정하려고 했습니까?

0

아마도이 옵션을 사용할 수 있습니다 ('대신'/ '사용).') :

routes.MapRoute(
     "Rest1", 
     "Users/Get/{format}/{id}", 
     new { controller = "Users", action = "Get", format = "HTML" } 
     ); 

그리고

public class UsersController : Controller { 
    public ActionResult Get(string format, int id) { 
     switch (format) { 
     case "json": 
      break; 
     case "xml": 
      break; 
     default: 
      break; 
     } 
     return new ContentResult(); // Or other result as required. 
    } 
} 
+0

물론,하지만 그건 내 질문이 아니야) –

0

또 다른 아이디어 :

routes.MapRoute(
    "Rest1", 
    "Users/Get/{id}.{format}", 
    new { controller = "Users", action = "Get", format = "HTML" } 
    ); 

그리고 CONTROLER 방법에

+0

그럼/사용자/가져 오기/1 실 거예요 ... 나는 "/ 사용자/가져 오기/1"작성해야합니다. 경로가 작동하려면 ... –

0

당신은 regular expressions in your route를 사용할 수있는 ID와 형식을 retreaving에 대한 몇 가지 코드를 추가를 그런 다음 "." 귀하의 경로에서 선택 문자로.