web-dev-qa-db-ja.com

エリアで機能しない属性ルーティング

シナリオ:ASP.NET MVC 5サイトにフォーム領域があります。

新しい属性ルーティング機能を使用して定義されたカスタムルートを使用する詳細アクションにリダイレクトしようとしています。

RedirectToAction:

return RedirectToAction("Details", new { slug });

リダイレクト先のアクション:

[HttpGet]
[Route("forms/{slug}")]
public ActionResult Details(string slug)
{
    var form = FormRepository.Get(slug);

    ...

    return View(model);
}

http://localhost/forms/my-slugへのリダイレクトが必要ですが、代わりにアプリがhttp://localhost/Forms/Details?slug=my-slugにリダイレクトしています。

これは、属性ルーティングが機能していないことを意味します。

これはどのように解決できますか?

Routes.MapMvcAttributeRoutes();を追加しました。 RouteConfigへの行:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

そして、ここに私のApplication_Start()があります:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}
45
Thomas Stock

おそらく、慣習ベースのルーティングと属性ルーティングを組み合わせているので、属性ルートをマップした後にエリアを登録する必要があります

この線

AreaRegistration.RegisterAllAreas();

この行の後に呼び出す必要があります。

routes.MapMvcAttributeRoutes();

説明( http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#route-areasから ):

ルート属性を持つエリアと、コンベンションベースのルート(AreaRegistrationクラスによって設定される)を持つエリアの両方を使用している場合、MVC属性ルートが構成された後、ただしデフォルトのコンベンションベースのルートが設定される前に、エリアの登録を行う必要がありますセット。理由は、ルート登録を最も具体的な(属性)からより一般的な(エリア登録)からミストジェネリック(デフォルトルート)に並べて、ジェネリックルートが着信リクエストを早めに一致させることでより具体的なルートを「隠す」ことを避けるためですパイプライン。

空のasp.net mvc Webサイトを作成し、エリアを追加して属性ルーティングの使用を開始すると、Visual Studioの「エリアの追加」アクションがルート構成の前にApplication_StartにRegisterAllAreas呼び出しを追加するため、この問題が発生します。

代替ソリューション

おそらく、規約ベースのルーティングを使用し続けるつもりはなく、属性ルーティングのみを使用することを好みます。この場合、FormsAreaRegistration.csファイルを削除するだけです。

89
Thomas Stock

AreaRegistration.RegisterAllAreas()をRouteConfig.csに移動するだけでは十分ではありませんでした。 RouteArea属性にAreaPrefixパラメーターを使用する必要もありました。

//Use the named parameter "AreaPrefix"
[RouteArea("AreaName", AreaPrefix = "area-name-in-url")]
[RoutePrefix("controller-name-in-url")]
public class SampleController : Controller
{
    [Route("{actionParameter}")]
    public ActionResult Index(string actionParameter)
    {
        return View();
    }
}

編集:ある時点で、属性ルーティングの処理方法をうまく示したマイクロソフトのサンプルソリューションに出会いました。また、SelectListinput[type="radio"]アイテムの配列に変換する方法と、input[type="checkbox"]アイテムの配列で同じことを行う方法の素敵な例を示しました(覚えている場合)。このサンプルソリューションは、おそらくこの質問に対するより良い答えです。また、ラジオボタンとチェックボックスアイテムの表示に関するいくつかの良い例を示します。このサンプルソリューションをご存知の方は、リンクを記載したコメントを追加してください。

38