0

ページング、並べ替え、検索の 3 つの目的を果たす asp.net mvc サイトにフォームがあります。正しい検索結果を返すかどうかは、3 つの側面すべての変数に依存するため、これらのアイテムはすべて同じ形式でレンダリングする必要があります。私がやろうとしているのは、パラメーターをクエリ文字列から移動し、正規の URL に配置することです。

これまでのところ、3 つのルート構成があります (エリア、コントローラー、およびアクション名に T4MVC を使用)。

context.MapRoute(null,
    "my-area/my-widgets/search/{size}-results-max/page-{page}/order-by-{sort}",
    new
    {
        area = MVC.MyArea.Name,
        controller = MVC.MyArea.MyWidgets.Name,
        action = MVC.MyArea.MyWidgets.ActionNames.Search,
        page = UrlParameter.Optional,
        size = UrlParameter.Optional,
        sort = UrlParameter.Optional,
    }
);

context.MapRoute(null,
    "my-area/my-widgets/canonicalize-search",
    new
    {
        area = MVC.MyArea.Name,
        controller = MVC.MyArea.MyWidgets.Name,
        action = MVC.MyArea.MyWidgets.ActionNames.CanonicalizeSearch,
    }
);

context.MapRoute(null,
    "my-area/my-widgets",
    new
    {
        area = MVC.MyArea.Name,
        controller = MVC.MyArea.MyWidgets.Name,
        action = MVC.MyArea.MyWidgets.ActionNames.CanonicalizeSearch,
    }
);

ビュー内のフォームは、次の構文を使用して CanonicalizeSearch ルートに送信されます。

@using (Html.BeginForm(MVC.MyArea.MyWidgets.CanonicalizeSearch(), 
    FormMethod.Get))

MyWidgetsController には、2 つのアクション メソッドがあります。

[ActionName("canonicalize-search")]
public virtual RedirectToRouteResult CanonicalizeSearch(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending")
{
    var result = RedirectToRoutePermanent(new
    {
        area = MVC.MyArea.Name,
        controller = MVC.MyArea.MyWidgets.Name,
        action = MVC.MyArea.MyWidgets.ActionNames.Search,
        page = page,
        size = size,
        sort = sort,
        keyword = keyword,
    });
    return result;
}

[ActionName("search")]
public virtual ViewResult Search(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending")
{
    // code to perform query
    return View(model);
}

これは、キーワードを除くすべてのクエリ文字列変数を正規化されたルートに移動するために機能します。最初のルートにキーワード パラメータを追加すると、CanonicalizeSearch アクションは、キーワードが null、空、または空白でない場合にのみ Search アクションにリダイレクトされます。キーワードが入力されていない場合、ページの結果を閲覧できなくなるため、これは良くありません。

私はすべてを試したと思います-キーワードにコントローラーのデフォルト値を与え、他の3つのパラメーターにキーワードを追加する4番目のルートを追加するなど。ただし、これを機能させる唯一の方法は、キーワードをそのままにしておくことですクエリ文字列パラメーター。(実際には、CanonicalizeSearch でキーワードの前にアンダースコアを追加し、Search で削除することで機能させることができますが、これはかなりハックです)。

何か助けはありますか?

4

2 に答える 2

1

最初のルートでパラメータを設定UrlParameter.Optionalしてみましたか?keyword当たり前で馬鹿げているように聞こえますが、あなたはそれを除外することはありませんでした。

于 2011-01-20T04:59:17.047 に答える
1

別の問題を解決しようとすることで、これに対するより良い解決策を見つけたと思います。

誰かがキーワード ボックスに「私の検索用語」と入力したとします。CanonicalizeSearch メソッドをパスにルーティングさせる送信:

/my-area/my-widgets/search/10-results-per-page/page-1/
    order-by-Title-Ascending/my%20search%20terms

これらの %20 記号は煩わしいものです。URL は次のようになります。

/my-area/my-widgets/search/10-results-per-page/page-1/
    order-by-Title-Ascending/my-search-terms

これは次の方法で実現できます (永続的なリダイレクトから一時的なリダイレクトへの変更に注意してください)。

[ActionName("canonicalize-search")]
public virtual RedirectToRouteResult CanonicalizeSearch(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending")
{
    var result = RedirectToRoute(new
    {
        area = MVC.MyArea.Name,
        controller = MVC.MyArea.MyWidgets.Name,
        action = MVC.MyArea.MyWidgets.ActionNames.Search,
        page = page,
        size = size,
        sort = sort,
        keyword = (string.IsNullOrWhiteSpace(keyword)) 
            ? "no-keywords" : keyword.Replace(' ', '-'),
    });
    TempData["keyword"] = keyword;
    return result;
}

[ActionName("search")]
public virtual ViewResult Search(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending")
{
    keyword = TempData["keyword"] as string ?? keyword;
    // code to perform query
    return View(model);
}

これにより、ここに投稿した質問と %20 記号の削除の両方が解決されます。キーワードが null 空または空白の場合は常に、URL をレンダリングします

/my-area/my-widgets/search/10-results-per-page/page-1/
    order-by-Title-Ascending/no-keywords

...そして、ルートは常に一致します。

于 2011-01-20T06:19:30.923 に答える