에서 StackOverflow의 포드 캐스트 # 54 , 제프들은 StackOverflow에 자신의 URL 경로는 방법을 처리하는 경로 위의 속성을 통해 코드베이스 등록 언급하고있다. 좋은 개념처럼 들립니다 (Phil Haack이 경로 우선 순위에 대해 제기 한 경고 포함).
누군가이를 위해 샘플을 제공 할 수 있습니까?
또한이 라우팅 스타일을 사용하기위한 “모범 사례”가 있습니까?
답변
업데이트 : 이것은 codeplex 에 게시되었습니다. 전체 소스 코드와 사전 컴파일 된 어셈블리를 다운로드 할 수 있습니다. 아직 사이트에 문서를 게시 할 시간이 없었기 때문에 지금은이 글로 충분해야합니다.
업데이트 : 1) 경로 순서 지정, 2) 경로 매개 변수 제약 조건 및 3) 경로 매개 변수 기본값을 처리하기 위해 몇 가지 새로운 속성을 추가했습니다. 아래 텍스트는이 업데이트를 반영합니다.
실제로 MVC 프로젝트에 대해 이와 같은 작업을 수행했습니다 (Jeff가 stackoverflow로 어떻게 작업하는지 모르겠습니다). 사용자 지정 특성 집합 인 UrlRoute, UrlRouteParameterConstraint, UrlRouteParameterDefault를 정의했습니다. 경로, 제약 조건 및 기본값이 자동으로 바인딩되도록 MVC 컨트롤러 작업 메서드에 연결할 수 있습니다.
사용 예 :
(이 예제는 다소 인위적이지만 기능을 보여줍니다)
public class UsersController : Controller
{
// Simple path.
// Note you can have multiple UrlRoute attributes affixed to same method.
[UrlRoute(Path = "users")]
public ActionResult Index()
{
return View();
}
// Path with parameter plus constraint on parameter.
// You can have multiple constraints.
[UrlRoute(Path = "users/{userId}")]
[UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
public ActionResult UserProfile(int userId)
{
// ...code omitted
return View();
}
// Path with Order specified, to ensure it is added before the previous
// route. Without this, the "users/admin" URL may match the previous
// route before this route is even evaluated.
[UrlRoute(Path = "users/admin", Order = -10)]
public ActionResult AdminProfile()
{
// ...code omitted
return View();
}
// Path with multiple parameters and default value for the last
// parameter if its not specified.
[UrlRoute(Path = "users/{userId}/posts/{dateRange}")]
[UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
[UrlRouteParameterDefault(Name = "dateRange", Value = "all")]
public ActionResult UserPostsByTag(int userId, string dateRange)
{
// ...code omitted
return View();
}
UrlRouteAttribute의 정의 :
/// <summary>
/// Assigns a URL route to an MVC Controller class method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteAttribute : Attribute
{
/// <summary>
/// Optional name of the route. If not specified, the route name will
/// be set to [controller name].[action name].
/// </summary>
public string Name { get; set; }
/// <summary>
/// Path of the URL route. This is relative to the root of the web site.
/// Do not append a "/" prefix. Specify empty string for the root page.
/// </summary>
public string Path { get; set; }
/// <summary>
/// Optional order in which to add the route (default is 0). Routes
/// with lower order values will be added before those with higher.
/// Routes that have the same order value will be added in undefined
/// order with respect to each other.
/// </summary>
public int Order { get; set; }
}
UrlRouteParameterConstraintAttribute의 정의 :
/// <summary>
/// Assigns a constraint to a route parameter in a UrlRouteAttribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterConstraintAttribute : Attribute
{
/// <summary>
/// Name of the route parameter on which to apply the constraint.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Regular expression constraint to test on the route parameter value
/// in the URL.
/// </summary>
public string Regex { get; set; }
}
UrlRouteParameterDefaultAttribute의 정의 :
/// <summary>
/// Assigns a default value to a route parameter in a UrlRouteAttribute
/// if not specified in the URL.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterDefaultAttribute : Attribute
{
/// <summary>
/// Name of the route parameter for which to supply the default value.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Default value to set on the route parameter if not specified in the URL.
/// </summary>
public object Value { get; set; }
}
Global.asax.cs의 변경 사항 :
MapRoute에 대한 호출을 RouteUtility.RegisterUrlRoutesFromAttributes 함수에 대한 단일 호출로 바꿉니다.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteUtility.RegisterUrlRoutesFromAttributes(routes);
}
RouteUtility.RegisterUrlRoutesFromAttributes의 정의 :
전체 소스는 codeplex에 있습니다. 피드백이나 버그 보고서가 있으면 사이트로 이동하십시오.
답변
github 또는 nuget을 통해 사용할 수있는 AttributeRouting 을 사용해 볼 수도 있습니다 .
제가 프로젝트 작성자이기 때문에 이것은 뻔뻔한 플러그입니다. 그러나 내가 그것을 사용하는 것이별로 행복하지 않다면 dang. 당신도 그럴 수 있습니다. github 저장소 위키 에는 많은 문서와 샘플 코드가 있습니다.
이 라이브러리를 사용하면 다음과 같은 많은 작업을 수행 할 수 있습니다.
- GET, POST, PUT 및 DELETE 속성으로 작업을 장식하십시오.
- 여러 경로를 단일 작업에 매핑하고 Order 속성으로 순서를 지정합니다.
- 속성을 사용하여 경로 기본값 및 제약 조건을 지정합니다.
- 간단한?로 선택적 매개 변수를 지정하십시오. 매개 변수 이름 앞의 토큰.
- 명명 된 경로를 지원하기위한 경로 이름을 지정합니다.
- 컨트롤러 또는 기본 컨트롤러에서 MVC 영역을 정의합니다.
- 컨트롤러 또는 기본 컨트롤러에 적용된 경로 접두사를 사용하여 경로를 그룹화하거나 중첩합니다.
- 레거시 URL을 지원합니다.
- 작업에 대해 정의 된 경로, 컨트롤러 내, 컨트롤러 및 기본 컨트롤러 간의 경로 우선 순위를 설정합니다.
- 소문자 아웃 바운드 URL을 자동으로 생성합니다.
- 고유 한 사용자 지정 경로 규칙을 정의하고이를 컨트롤러에 적용하여 상용구 속성없이 컨트롤러 내에서 작업에 대한 경로를 생성합니다 (RESTful 스타일을 고려하십시오).
- 제공된 HttpHandler를 사용하여 경로를 디버그합니다.
내가 잊고있는 다른 것들이있을 거라고 확신합니다. 확인 해봐. 너겟을 통해 설치하는 것은 어렵지 않습니다.
참고 : 2012 년 4 월 16 일부터 AttributeRouting은 새로운 웹 API 인프라도 지원합니다. 당신이 그것을 처리 할 수있는 것을 찾고 있다면. 감사합니다 subkamran !
답변
1. RiaLibrary.Web.dll을 다운로드 하고 ASP.NET MVC 웹 사이트 프로젝트에서 참조합니다.
2. [Url] 속성을 사용하여 컨트롤러 메서드를 장식합니다.
public SiteController : Controller
{
[Url("")]
public ActionResult Home()
{
return View();
}
[Url("about")]
public ActionResult AboutUs()
{
return View();
}
[Url("store/{?category}")]
public ActionResult Products(string category = null)
{
return View();
}
}
BTW, ‘?’ 로그인 ‘{? category}’매개 변수는 선택 사항임을 의미합니다. 다음과 같은 경로 기본값에 명시 적으로 지정할 필요가 없습니다.
routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });
3. Global.asax.cs 파일 업데이트
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoutes(); // This does the trick
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
기본값 및 제약 조건을 설정하는 방법은 무엇입니까? 예:
public SiteController : Controller
{
[Url("admin/articles/edit/{id}", Constraints = @"id=\d+")]
public ActionResult ArticlesEdit(int id)
{
return View();
}
[Url("articles/{category}/{date}_{title}", Constraints =
"date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
public ActionResult Article(string category, DateTime date, string title)
{
return View();
}
}
주문 설정 방법? 예:
[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
return View();
}
[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
return View();
}
답변
이 게시물은 DSO의 답변을 확장하기위한 것입니다.
내 경로를 속성으로 변환하는 동안 ActionName 속성을 처리해야했습니다. 따라서 GetRouteParamsFromAttribute에서 :
ActionNameAttribute anAttr = methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), false)
.Cast<ActionNameAttribute>()
.SingleOrDefault();
// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
RouteName = routeAttrib.Name,
Path = routeAttrib.Path,
ControllerName = controllerName,
ActionName = (anAttr != null ? anAttr.Name : methodInfo.Name),
Order = routeAttrib.Order,
Constraints = GetConstraints(methodInfo),
Defaults = GetDefaults(methodInfo),
});
또한 경로 이름이 적합하지 않음을 발견했습니다. 이름은 controllerName.RouteName을 사용하여 동적으로 빌드됩니다. 그러나 내 경로 이름은 컨트롤러 클래스의 const 문자열이며 해당 const를 사용하여 Url.RouteUrl도 호출합니다. 그래서 실제로 경로의 실제 이름이되는 속성의 경로 이름이 필요합니다.
내가 할 또 다른 일은 기본 및 제약 조건 속성을 AttributeTargets.Parameter로 변환하여 매개 변수에 고정 할 수 있도록하는 것입니다.
답변
저는이 두 가지 접근 방식을 원하는 사람을 위해 프랑켄슈타인 버전으로 결합했습니다. (선택적 매개 변수 표기법이 마음에 들었지만, 모두 하나에 섞이는 것이 아니라 default / constraints와 별개의 속성이어야한다고 생각했습니다).
http://github.com/djMax/AlienForce/tree/master/Utilities/Web/
답변
AsyncController를 사용하여 asp.net mvc 2에서 ITCloud 라우팅이 작동하도록해야했습니다. 그렇게하려면 소스에서 RouteUtility.cs 클래스를 편집하고 다시 컴파일하기 만하면됩니다. 98 행의 작업 이름에서 “Completed”를 제거해야합니다.
// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
RouteName = String.IsNullOrEmpty(routeAttrib.Name) ? null : routeAttrib.Name,
Path = routeAttrib.Path,
ControllerName = controllerName,
ActionName = methodInfo.Name.Replace("Completed", ""),
Order = routeAttrib.Order,
Constraints = GetConstraints(methodInfo),
Defaults = GetDefaults(methodInfo),
ControllerNamespace = controllerClass.Namespace,
});
그런 다음 AsyncController에서 XXXXCompleted ActionResult를 익숙한 속성 UrlRoute
과 UrlRouteParameterDefault
속성으로 장식 합니다.
[UrlRoute(Path = "ActionName/{title}")]
[UrlRouteParameterDefault(Name = "title", Value = "latest-post")]
public ActionResult ActionNameCompleted(string title)
{
...
}
같은 문제를 가진 사람에게 도움이되기를 바랍니다.