1

Julian と同様の状況: MVC - クエリ文字列を使用したルート

フォームから定義されたルートと値を使用して、GET リクエストを使用してフォームを操作する方法を把握できません。

(編集:ジュリアンの問題と本質的に同じコンテキストですが、javascriptライブラリやカスタムルーティングの観点から特定の解決策について尋ねます(一般的な領域ではなく、特定のコードに問題と異なるアプローチが必要な理由を説明するのではなく) ; また、global.asaxを使用していない; 質問から 1 年以上経過しているということは、他のオプションも利用できる可能性があることを意味します。)

初心者の場合、クライアント ライブラリが圧倒的に多く、関連するカスタム ルート プロバイダーをどこから始めればよいかほとんどわからないため、先に進むのは困難ですが、サーバー側のルーティングと 301 リダイレクトを維持するシンプルさのためには、これがより望ましいようです。

さまざまなルート(明らかに「カスタム」ではない)を試し、多くのライブラリを調べましたが、具体的な進歩はありませんでした。

ルーティングの例/キーワード/リンク、単純なクライアント コードの例 (このコンテキストなど) などの単純なポインターは非常に役立ちます。


このチュートリアルを使用して、タイトルジャンルによる映画の検索ページを作成します。]

ここに私の特定のコードがあります:

ルート構成:

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

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

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

アクション結果:

public ActionResult SearchIndex(string title, string genre)
{
            var genreQuery = from g in db.Movies
                         orderby g.Genre
                         select g.Genre;
            var genres = new List<string>();
            genres.AddRange(genreQuery.Distinct());
            ViewBag.Genre = new SelectList(genres);

            var movies = from m in db.Movies
                         select m;

            if (!string.IsNullOrEmpty(title))
            {
                movies = movies.Where(s => s.Title.Contains(title));
            }
            if (!string.IsNullOrEmpty(genre))
            {
                movies = movies.Where(s => s.Genre == genre);
            }

            return View(movies);
        }

SearchIndex.cshtml:

    @model IEnumerable<DefaultMvcIA.Models.Movie>

@{
    ViewBag.Title = "SearchIndex";
}

<h2>SearchIndex</h2>

<p>
    @Html.ActionLink("Create New", "Create")
    @using (Html.BeginForm("SearchIndex", "Movies", FormMethod.Get))
    {
        <p>Genre: @Html.DropDownList("Genre", "All")
        Title: @Html.TextBox("Title")<br />
        <input type="submit" value="Filter" /></p>
    }
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.MovieID }) |
            @Html.ActionLink("Details", "Details", new { id=item.MovieID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.MovieID })
        </td>
    </tr>
}

</table>

問題 GET 要求では、ブラウザーはクエリ文字列を使用するだけで、RouteConfig でルーティングを設定しません (当然のことです)。これらのクエリ文字列をルーティングするか、クライアント ライブラリを使用するようにリダイレクトするには、カスタム ルートを記述する必要があります。多くの異なるルーティング ライブラリがあり、(望ましい) 301 カスタム ルーティング メソッドをどこから始めればよいかわからないため、特定の情報は非常に役立ちます。

4

1 に答える 1

1

編集:午後8時46分

コントローラー/アクション。検索/インデックスをオーバーロードして、クエリ文字列があるかどうか、取得リクエストであるかどうかなどに応じて異なる結果を返すことができます。

public ActionResult Index(){} will be hit by host/ControllerName/Index

public ActionResult Index(string searchTerm) will be hit by host/ControllerName/Index?searchTerm=ABC

編集: 午前 9 時 23 分

投稿先のアクションを動的に変更する必要がある場合は、get リクエストをインターセプトする JavaScript ライブラリがあります。ajax の使用を気にしない場合は、いつでもhttp://www.malsup.com/jquery/form/を調べてフォーム リクエストをインターセプトし、リンクを好きなように変更できます。

編集: 6/16 9:22 AM 上記のコードには、行があります

@using (Html.BeginForm("SearchIndex", "Movies", FormMethod.Get))

これは、Get リクエストが「SearchIndexController」および「Movies」ActionResult に対して「Get」リクエストを実行することを示します。

(そのため、引き続き global.asax ルーティングのコードを使用して、そのコントローラー/アクションにルーティングします) global.asax のこのルーティング コードは、すべての要求に対して常に使用されます。


応答を編集して、クエリ文字列にアクセスする方法に焦点を当てます (パスを再ルーティングするため)

クエリ文字列に直接バインドできます。他の回答でテキストが重複しないよう にするには、クエリ文字列から値を取得する方法について、「 ASP.NET MVC - QueryString 値の取得」を参照してください。

ActionResult メソッド シグネチャでそれらに直接バインドしたくない場合は、Request.Querystring オブジェクトを使用してクエリ文字列にアクセスします。すなわち。

 var searchTerm = Request.QueryString["searchTerm"].ToString();
 var sortColumn = Request.QueryString["sortColumn"].ToString();

また

 var searchTerms = Request.QueryString["searchTerms"].ToString().SplitBy(",")

クエリ開始の構文に応じて...

クエリ文字列パラメーターの結果に基づいてメソッドをリダイレクトするには、いつでも別のアクション メソッドを返すか、Action にリダイレクトできます。

 ie. return this.Index2( ..param...); 

また

 RedirectToAction("ActionName", "ControllerName")

... 選択したアクションにリダイレクトする方法はたくさんあります。


フォームを「アクション」する方法は、私にはあまり意味がありません。

mvc では、簡単な設定は次のような形式にすることです

@{using(Html.BeginForm("Index","Home",FormMethod.Post)){
  @Html.LabelFor(m => m.Word)
  @Html.TextBoxFor(m => m.Word, new { @Value = Model.Word})
  <input type="submit" value="Submit">
}

ここで、"Index" はアクション名、"Home" はコントローラー名です。これは、HomeController の Action メソッドにルーティングされます。このルーティング パスは、Global.asax で指定されたルーティングで実際にカスタマイズできます。global.asax には、次のようなコード スニペットがあります。

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

これにより、フォーム A/B/C の URL が AController、パラメーター Id=3 を持つ ActionResult B にルーティングされます。

これが、従うべき適切なチュートリアルを探すのに役立つ十分な情報であることを願っています. あなたがまだ学生である場合 (または大学の電子メールを持っているか、友人がいる場合) は、http://www.pluralsight.com/training でビデオをご覧ください。mvc3/4 の基本を学ぶのに役立つ優れた紹介ビデオがあります。

于 2013-06-16T04:33:05.820 に答える