1

MVC 5 で属性ルーティングを設定しようとしています。デフォルト アクションを持つルートがありますが、そのアクションがテンプレートにまったくありません。ここが私の旧ルートです。

routes.MapRoute(null,
    "Article/{id}/{*path}",
    new { controller = "Article", action = "Index" , id = UrlParameter.Optional, path = UrlParameter.Optional }
  );

これにより、パス内のアクションにインデックスを使用する必要なく、/Articles/1/test のルートが満たされます (つまり、/Articles/Index/1/test)。

また、デフォルトのマップ ルート ..../Article/Items によってキャッチされる別のメソッドもあります。

私の問題は、MVC 5 の新しい属性ルーティングを使用してこのルートをセットアップする方法がわからないことです。以下のコードは機能しますが、各メソッドにルートを追加する必要はありません。すべてのメソッドを満たすクラスの先頭に何かを配置することを望んでいましたが、Index メソッドに何か他のものを追加するだけです。

[RoutePrefix("Article")]
public class ArticleController: BaseController
{
  [Route("{id?}/{*path?}")]
  public ActionResult Index(int id, string path)
  {

  }

  [Route("Items")]
  public ActionResult Items()
  {

  }

  [Route("TestMethod")]
  public ActionResult TestMethod()
  {

  }
}

以下のようなものを期待していました。問題は、パスの前にインデックスを配置する必要があることです.../Index/1/test.

[RoutePrefix("Article")]
[Route("{action=Index}")]
public class ArticleController : BaseController
{
  Route[("{id?}/{*path?}")]
  public ActionResult Index(int id, string path)
  {

  }

  public ActionResult Articles()
  {

  }

  public ActionResult TestMethod() 
  {

  }
}
4

1 に答える 1

2

以下は、上記のシナリオを実現する方法です。(アクションにヒットする可能性のある URL を説明するコードで私のコメントを見つけることができます)。

int「id」ルート変数にインライン制約を使用したことに注意してください。これは、「Article/TestMethod」のようなリクエストがルート「Article/{id?}/{*path}」によってキャプチャされないようにするためです。理想的には、上記のようなシナリオを回避するために、属性ルートに Order プロパティを配置して順序付けする必要がありますが、最後の最後でそれを削除し、正しく行うことを確認したかったため、再度追加する時間がありませんでした。すべてのシナリオに関して。(実際には、事前属性ルーティングの変更でこの同様の問題に直面しているはずです...事前属性ルート構成がどのように見えるかを共有できますか?)

デフォルトでは、一般的なルートの前に最も具体的なルートを配置するようにルートを並べ替えます。したがって、現在のケースでは、1 つのルート 'Article/{id:int?}/{*path}' に制約があるため、一般的なルート 'Article/{action}' の前に配置され、これが機能している理由です。現在。

次のリリースでは、このようなシナリオにより柔軟に対応できる Order プロパティを再導入します。

[RoutePrefix("Article")]
[Route("{action}")]
public class ArticleController : Controller
{
    // GET /Article
    // GET /Article/10
    // GET /Article/10/abc/def
    [Route("{id:int?}/{*path}")]
    public ActionResult Index(int? id, string path)
    {
        return Content("Index:" + id + ":" + path);
    }

    // GET /Article/Articles
    public ActionResult Articles()
    {
        return Content("Articles");
    }

    // GET /Article/TestMethod
    public ActionResult TestMethod()
    {
        return Content("TestMethod");
    }
}
于 2013-11-21T18:42:30.043 に答える