0

2 つの部分ビューと Ajax を使用して、「高度な検索」ビューを作成しようとしています。利用可能なすべての検索条件をプロパティとして持つ「SearchFilter」エンティティを定義しました。「_Filter」部分ビュー (OnSuccess AjaxOption) での送信時に、「_Results」部分ビューを更新する「ListResults」アクションにそれを渡す必要があります。

問題は、ListResults アクションの着信パラメーターとして常に null エンティティを取得することです。

コードは次のとおりです。

AdvancedSearchView.cshtml

@model MyApp.ViewModels.SearchFormViewModel
@{
    ViewBag.Title = "Advanced search";
}
    <div id="divFilter">
        @Html.Partial("_Filter", Model)
    </div>
    <div id="divResults">
        @Html.Partial("_Results", Model.ResultsList)
    </div>

_Filter.cshtml

@model MyApp.ViewModels.SearchFormViewModel
<script type="text/javascript">
    function getForm(url, divName) {
        var obj = new Date();
        url = (url.indexOf('?', 0) != -1) ? url + '&uid=' + obj.getTime() : url + '?uid=' + obj.getTime();
        $.get(url, function (data) {
            $("#" + divName).html(data);
        });
    }
</script>

    @using (Ajax.BeginForm("Search", null, new AjaxOptions
    {
        UpdateTargetId = "divFilter",
        InsertionMode = InsertionMode.Replace,
        OnSuccess="getForm('"+Url.Action("ListResults", "Products", new { myFilter = Model.CurrentFilter}) + "','divResults')"
    }, new { id = "idSearchForm" }))
    {
        <fieldset style="width: 800px; line-height: 1.4em;">
            <legend>Configure your search filters</legend>
        ...
        </fieldset>
        <input type="submit" value="Rechercher" class="submit" style="width: 280px" />
    }

コントローラ

    public ActionResult Search()
    {
SearchFilter currentFilter = new SearchFilter();
List<Product> filteredProductsList = repository.FindProducts_Filtered(currentFilter);
          return View("AdvancedSearchView", new AdvancedSearchFormViewModel(currentFilter, filteredProductsList/* , necessary select lists */));
    }

    [HttpPost]
    public ActionResult Search(AdvancedSearchFormViewModel model)
    {
        SearchFilter currentFilter = model.CurrentFilter;
        // set the necessary select lists

        List<Product> filteredProductsList = repository.FindProducts_Filtered(currentFilter);
        return PartialView("_Filter", AdvancedSearchFormViewModel(currentFilter, filteredProductsList/* , necessary select lists */));
    }

    public ActionResult ListResults(SearchFilter myFilter)
    {
        List<Product> filteredProductsList = repository.FindProducts_Filtered(currentFilter);
        return PartialView("_Results", filteredProductsList);
    }

ビューモデル

public class AdvancedSearchFormViewModel
    {
        // Properties
        public SearchFilter CurrentFilter { get; set; }
        public List<Product> ResultsList { get; set; }
        // some SelectLists

        // Constructor

        public AdvancedSearchFormViewModel()
        {}

        public AdvancedSearchFormViewModel(SearchFilter pCurrentFilter, List<Product> pResultsList, /* necessary select lists*/)
        {
            CurrentFilter = pCurrentFilter;
            ResultsList = pResultsList;
            // the SelectLists
        }
    }

私が何か間違ったことをしていることは間違いありませんが、それが何であるかはわかりません。

BeginForm の生成された HTML マークアップは次のようになります。

<form action="/Products/Search" data-ajax="true" data-ajax-mode="replace" data-ajax-success="getForm(&#39;/Products/ListResults?myFilter=MyApp.Models.SearchFilter&amp;uid=2622ea0e-d7dc-48fa-b65d-519978ee40b3&#39;,&#39;divResults&#39;)" data-ajax-update="#divFilter" id="idSearchForm" method="post">
4

1 に答える 1

1

ListResultsアクションのmyFilter引数にnull値を取得する理由は、これがサーバーに送信するものであるためです。

/Products/ListResults?myFilter=MyApp.Models.SearchFilter&uid=2622ea0e-d7...

デフォルトのmodelbinderは、文字列「MyApp.Models.SearchFilter」をMyApp.Models.SearchFilterのインスタンスに変換しようとしていますが、これは実行できません。

このモデルオブジェクトのコードは表示されませんが、modelbinderがそのプロパティからSearchFilterのインスタンスを構築できるように、各パラメーターを個別に送信してみてください。

OnSuccess="getForm('"+Url.Action("ListResults", "Products", new { 
    Prop1 = Model.CurrentFilter.Prop1, 
    Prop2 = Model.CurrentFilter.Prop2, 
    etc...
})...

コメント1の後に更新

URLにパラメータ値を表示することについての質問に答えるために、これがHTTPの仕組みです。サーバーに送信されたパラメーターをURLに表示したくない場合は、HTTPGETの代わりにHTTPPOSTを実行する必要があります。

ただし、操作がべき等である場合は常に、HTTPGETを使用する必要があります。HTTP POSTは、入力送信によってアプリケーションの状態が何らかの形で変更される場合に備えて予約する必要があります。public ActionResult Search(AdvancedSearchFormViewModel model)実際には、アクションメソッドに[HttpPost]を使用することに同意しません。表示するデータを返すだけなので、べき等のアクションです。

とはいえ、このガイドラインに違反し、GETの代わりにHTTPPOSTを実行することを妨げるものは何もありません。個人的には、URLパラメータに問題はありません。あなたはそれらをウェブ上でいつも見ています。たとえば、このリンクのURLを参照してください

HTTPは複雑なオブジェクトを理解せず、テキストのみを理解します。複雑なオブジェクトのデータをHTTP経由で送信するには、それらをテキスト部分に分割する必要があります。このようなデータをHTTPGET経由で送信するには、URLに含まれている必要があります。

于 2012-01-03T14:13:22.807 に答える