태그 보관물: decorator

decorator

메서드 특성을 통한 ASP.NET MVC 라우팅 [닫힌] 뒷받침 할 것으로

에서 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를 익숙한 속성 UrlRouteUrlRouteParameterDefault속성으로 장식 합니다.

[UrlRoute(Path = "ActionName/{title}")]
[UrlRouteParameterDefault(Name = "title", Value = "latest-post")]
public ActionResult ActionNameCompleted(string title)
{
    ...
}

같은 문제를 가진 사람에게 도움이되기를 바랍니다.


답변