8

ASP.NET MVC4の既存のコントローラー/アクション/IDルーティングをデフォルトのコントローラー=ホームおよびデフォルトのアクション=インデックスで維持したいが、2番目の項目がない限り、コントローラー/IDがコントローラーのインデックスメソッドにルーティングできるようにしたい既知のアクション。

たとえば、アクションインデックスと送信を備えたコントローラーホームがあるとします。

/Home/Send -> controller's Send method
/Home -> controller's Index method
/Home/Send/xyz -> controller's Send method with id = xyz
/Home/abc -> controller's Index method with id = abc

ただし、どちらかのルートを最初に定義すると、もう一方のルートが非表示になります。どうすればいいですか?

4

6 に答える 6

5

デフォルトのジェネリックのものの前に、最初に特定のものを実行します。順序が重要です。

routes.MapRoute(name: "single", url: "{controller}/{id}",
    defaults: new { controller = "Home", action = "Index" }, 
    constraints: new { id = @"^[0-9]+$" });

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home",
    action = "Index",
    id = UrlParameter.Optional }
);
于 2012-12-11T19:26:25.933 に答える
2

アクションのリスト(例:Send)がよく知られており、それらの(アクション)名をID値と同じにすることができない場合は、カスタムConstraintImplementationを使用できます。

public class MyRouteConstraint : IRouteConstraint
{
  public readonly IList<string> KnownActions = new List<string> 
       { "Send", "Find", ... }; // explicit action names

  public bool Match(System.Web.HttpContextBase httpContext, Route route
                  , string parameterName, RouteValueDictionary values
                  , RouteDirection routeDirection)
  {
    // for now skip the Url generation
    if (routeDirection.Equals(RouteDirection.UrlGeneration))
    {
      return false; // leave it on default
    }

    // try to find out our parameters
    string action = values["action"].ToString();
    string id = values["id"].ToString();

    // id and action were provided?
    var bothProvided = !(string.IsNullOrEmpty(action) || string.IsNullOrEmpty(id));
    if (bothProvided)
    {
      return false; // leave it on default
    }

    var isKnownAction = KnownActions.Contains(action
                           , StringComparer.InvariantCultureIgnoreCase);

    // action is known
    if (isKnownAction)
    {
      return false; // leave it on default
    }

    // action is not known, id was found
    values["action"] = "Index"; // change action
    values["id"] = action; // use the id

    return true;
  }

また、ルートマップ(デフォルトのマップの前-両方を指定する必要があります)は、次のようになります。

routes.MapRoute(
  name: "DefaultMap",
  url: "{controller}/{action}/{id}",
  defaults: new { controller = string.Empty, action = "Index", id = string.Empty },
  constraints: new { lang = new MyRouteConstraint() }
);

概要:この場合、「action」パラメーターの値を評価しています。

  • 1)アクションと2)IDの両方が提供されている場合、ここでは処理しません。
  • また、これが既知のアクション(リスト内、または反映されている...)である場合も同様です。
  • アクション名が不明な場合のみ、ルート値を変更しましょう。アクションを「インデックス」に設定し、アクション値をIDに設定します。

注:action名前とid値は一意である必要があります...そうすればこれは機能します

于 2012-12-12T07:15:46.323 に答える
1

最も簡単な方法は、コントローラーで2つのアクションメソッドを作成することです。1つはインデックス用、もう1つは送信用で、文字列IDパラメーターを両方に配置します。アクションメソッドを複製したりオーバーロードしたりすることはできないので、それでその問題は解決します。これで、Indexメソッドは、IDが存在するかどうか(null)のインデックスパスまたは空白パスの両方を処理し、ビューをそのように処理します。Sendメソッドは、Indexとまったく同じように動作します。その後、idがnullかどうかに応じて、好きなようにルーティング、処理、またはリダイレクトできます。これは、RouteConfig.csを変更しなくても機能するはずです。

public ActionResult Index(string id) {if (id == null) Do A else Do B}

public ActionResult Send(string id) {if (id == null) Do A else Do B}

私は長い間この苦労をしました、そしてこれは最も簡単な解決策でした。

于 2017-07-01T11:08:34.753 に答える
0

2つの競合するルートがあるため、要件に対する解決策はないと思います。たぶん、特定の何かを定義することができます(他のコントローラーがない場合)。

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

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

routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index",
                                               id = UrlParameter.Optional }
    );
于 2012-12-11T22:06:02.967 に答える
0

これは私のために働いたものです:

1)RouteConfigで、これを最初の行にします。

routes.MapRoute(name: "single", url: "{controller}/{lastName}",
            defaults: new { controller = "LeaveRequests", action = "Index" });

2)私のコントローラー:

public ViewResult Index(string lastName)
{
    if (lastName == null)
    {
        return //return somthing
    }
    else
    {
        return //return something
    }
 }

3)コントローラーを呼び出すとき

http://localhost:34333/leaveRequests/Simpsons

それはあなたにシンプソンズのすべての要求を与えるでしょう。

あなたがそれを呼ぶならば、http://localhost:34333/leaveRequests/ それはすべての要求を与えるでしょう

于 2013-08-10T16:48:38.917 に答える
0

これは私のために働いています

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
            name: "Default1",
            url: "{id}",
            defaults: new { controller ="Home", action ="Index" }
        );
routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller ="Home", action ="Index", id = UrlParameter.Optional }
        );
于 2016-03-28T15:06:10.363 に答える