0

私の ASP.NET MVC アプリケーションでは、次の概念を実装しようとしています。

  • ブラウズhttp://.../PersonData/Show?id=A5668A31-9AAC-4A14-B471-7C9BA236961Dすると、指定された ID で識別される人物のデータが表示されます。
  • ブラウジングhttp://.../PersonData/Showすると、テキスト ボックスに ID を入力できるフォームを含むビューが表示されます。フォームを送信すると、ブラウザは上記の URL に移動しますが、投稿はしません (つまり、フォームのメソッドが GET に設定されています)。
  • ID を入力せずにフォームを送信すると (URLが参照http://.../PersonData/Show?id=される)、ASP.NET MVC モデルの検証で、ID が必要であるというメッセージが表示されます。(JavaScript が有効になっているかどうかに関係なく)。

これを実装するために、次のようなモデルを構築します。

class Model
{
  [Required]
  public Guid? Id { get; set; }
}

そして今http://.../PersonData/Show、初めて閲覧するときに、ASP.NET モデルの検証ですぐに ID が必要であるというエラーが表示されるという問題があります。これは、フォームが ID なしで送信され?id=た場合 ( ) と、アクションが初めて呼び出されました (id はまったく指定されていません)。

私が持っていたアイデア:

  • 2 つの異なるコントローラー アクションと URL (http://.../PersonData/Searchと などhttp://.../PersonData/Show?id=) を使用して、最初の閲覧と空のフォーム送信を区別します。
  • 追加のフォーム パラメータ (http://.../PersonData/Showや などhttp://.../PersonData/Show?valueGiven=true&id=) を使用します。
  • Requestオブジェクトを使用してアクション メソッドから URL パラメーターを検査し、そのキーが URL に存在しないかどうかModelStateのエラーをクリアします。"id"

これを解決するための最良の/推奨される方法は何ですか? より良い4番目のアプローチはありますか?

(失敗したことの 1 つは、GET アクションに同じ名前の 2 つのアクション メソッドを追加することでした。

[HttpGet]
public void Show() { /* return view with initial browsing logic */ }
[HttpGet]
public void Show(Model model) { /* return view with subsequent browsing logic */ }

これは ASP.NET MVC では許可されていないようです。)

2013 年 6 月 25 日の更新:申し訳ありませんが、私のサンプルには 2 つの間違いがありました。ID はGuid文字列ではなく である必要がありました。もちろん、Required属性を評価する必要があるため、アクション メソッドでモデルをバインドしています。

そして、これは私のルーティング構成です:

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

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

3 に答える 3

1

両方のメソッドを GET として使用する場合は、最初のアプローチを好みます。パラメータが渡された検索ページと結果ページです。これは、すべてのパラメータがクエリ文字列になります。

一方、共有が問題にならない場合は、GET メソッドを使用してフォームを表示し、同じ名前のアクション メソッドの POST バージョンに送信します。

于 2013-06-24T15:51:41.247 に答える
1

id を渡さない場合、id は null になります。id に値を渡すと、id は "" (つまり、空の文字列.. String.Empty) になります。

そのため、エラーが発生するため、Required 属性を使用することはできません。コントローラーで値を手動で確認する必要があります。

より良いアプローチは、ルート制約を使用して、id を持つバージョンを処理する特別なルートを作成することです。このルートの ID はオプションではありませんが、ID をまったく持たないルートが選択されないようにする制約があります。

現時点では、このケースを作成してテストすることはできませんが、これで何かを進めることができるはずです。おそらく、他の誰かが何かを盛り上げることができます。

ルートの制約に関する情報は、次の場所にあります。

http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-route-constraint-cs

于 2013-06-24T15:51:23.363 に答える
0

最初の show 関数に if ケースを追加するだけです

[HttpGet]
public void Show(int? id) {

    if(id.HasValue) {
     /* return view with subsequent browsing logic */ 
    }
    else {
      /* return view with initial browsing logic */
    }
}

編集:これはうまくいくかもしれません

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class RequestMatchAnyAttribute : ActionNameSelectorAttribute
    {
        public string MatchFormKey { get; set; }

        public RequestMatchAnyAttribute(string matchAnyFormKeys)
        {
            this.MatchFormKey = matchAnyFormKeys;
        }

        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            return controllerContext.HttpContext.Request[MatchFormKey] != null;
        }
    }


[HttpGet]
public void Show() {
    /* default view */
}

[ActionName("Show")]
[RequestMatchAny("Id")]
[HttpGet]
public void ShowEdit(int? id) {

    if(id.HasValue) {
     /* return edit view */ 
    }
    else {
      /* return create view */
    }
}
于 2013-06-24T16:58:46.240 に答える