でStackOverflowのポッドキャスト#54、ジェフは、彼らがStackOverflowの中にそのURLルートを登録言及ハンドルルートという方法上記の属性を経由してコードベース。良いコンセプトのように聞こえます(ルートの優先順位に関してPhil Haackが提起した警告があります)。
誰かがこれを実現するためのサンプルを提供できますか?
また、このスタイルのルーティングを使用するための「ベストプラクティス」はありますか?
でStackOverflowのポッドキャスト#54、ジェフは、彼らがStackOverflowの中にそのURLルートを登録言及ハンドルルートという方法上記の属性を経由してコードベース。良いコンセプトのように聞こえます(ルートの優先順位に関してPhil Haackが提起した警告があります)。
誰かがこれを実現するためのサンプルを提供できますか?
また、このスタイルのルーティングを使用するための「ベストプラクティス」はありますか?
回答:
更新:これはcodeplexに投稿されました。完全なソースコードとコンパイル済みのアセンブリがダウンロードできます。私はまだサイトにドキュメントを投稿する時間がなかったので、このSO投稿で今のところ十分である必要があります。
更新: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関数への1回の呼び出しに置き換えます。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteUtility.RegisterUrlRoutesFromAttributes(routes);
}
RouteUtility.RegisterUrlRoutesFromAttributesの定義:
完全なソースはcodeplexにあります。フィードバックやバグレポートがある場合は、サイトにアクセスしてください。
githubまたはnugetから入手できるAttributeRoutingを試すこともできます。
私はプロジェクトの作者なので、これは恥知らずなプラグです。しかし、私がそれを使用することにあまり満足していない場合は、ダメです。あなたもそうかもしれません。githubリポジトリwikiにはたくさんのドキュメントとサンプルコードがあります。
このライブラリを使用すると、多くのことができます。
私が忘れている他のいくつかのものがあると確信しています。見てみな。nuget経由でインストールするのは簡単です。
注:2012年4月16日の時点で、AttributeRoutingは新しいWebAPIインフラストラクチャもサポートしています。あなたがそれを処理できる何かを探している場合に備えて。subkamranに感謝します!
1. RiaLibrary.Web.dllをダウンロードし、ASP.NET MVCWebサイトプロジェクトで参照します
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();
}
}
ところで、「?」サインイン '{?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();
}
{?param}
オプションのパラメータの命名法が好きです。
この投稿は、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も呼び出します。そのため、属性のルート名を実際のルート名にする必要があります。
もう1つ行うことは、デフォルト属性と制約属性をAttributeTargets.Parameterに変換して、パラメーターに固定できるようにすることです。
私はこれらの2つのアプローチを組み合わせて、それを望む人のためにフランケンシュタイン版にしました。(私はオプションのパラメーター表記が好きでしたが、すべてを1つに混合するのではなく、デフォルト/制約とは別の属性にする必要があると考えました)。
http://github.com/djMax/AlienForce/tree/master/Utilities/Web/
AsyncControllerを使用してasp.netmvc 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)
{
...
}
同じ問題を抱えている人の助けになることを願っています。