2011-06-20 19 views
3

:ここでのコードはすべて実際には表示できないため、例として言い換えられますコード。タイプ変換器がこれらのタイプ間で変換できないため、タイプ 'System.String'からタイプ 'T'へのパラメータ変換が失敗しました

私は

public SearchViewModel 
{ 
    public string Term 
    { 
    get; set; 
    } 

    public SearchResult Result 
    { 
    get; set; 
    } 

    public List<Filter> Filters 
    { 
    get; set; 
    } 
} 

ようになり、ビューモデルクラスは、これは、通常のコントローラにバインドされ、すべてが正常に動作されている:

public ActionResult Search (SearchViewModel model) 
{ 
     if (ModelState.IsValid) 
     { 
      model.Result = _searchService.Search(model.Term); 
      return View(model); 
     } 
} 

私はまたに取ってハンドル別のアクションを持っていますチェックボックスを含むフォームからのPOST。このコントローラは、Filterクラスの作成を処理し、Searchアクションにリダイレクトします。以下のような

何か:

public ActionResult Filter(FormCollection formParams) 
    { 
     return RedirectToAction("Search", new SearchViewModel 
     { 
      Term = formParams["Term"], 
      Filters = 
       formParams.Keys 
        .Cast<String>() 
        .Where(k => k.Contains("filter")) 
        .Select(k => Filter.Build(k, formParams[k])) 
        .ToList()       
     });           
    } 

これは、検索行動に戻っ人口リストの収集とViewModelに渡します。

ただし、検索アクションでは、ModelState.IsValidがfalseを返すようになりました。

「フィルタ」 を入力するために「可能System.String」型 からパラメータ変換なし型コンバータは これらのタイプ間で変換することができないために失敗した:モデルバインダーは、この例外をスローするためです。文字列である「フィルタ」のショーのためにModelStateで生の値を見てみると

System.Collections.Generic.List`1[Filter] 

それは、アクション間の移行の間に失われたリストの実際の内容のように思える、おそらくそれ理由プロパティメンバーに対してのみToString()が呼び出されます。

この時点で、私はこれがなぜ失敗しているのか、あいまいな考えがありました。カスタムモデルのバインダーやタイプコンバータを作成して動作させることができましたが、このアプローチが匂いを感じています。たぶん些細なことですが、私は間違っているだけです。

複雑なタイプのコレクションをあるアクションから別のアクションに渡すための適切なASP.NET MVC 3は何ですか?

+0

これを試してみてください(私は同じ問題がありましたが、これが解決策であれば覚えていません): return RedirectToAction( "Search"、new RouteValueDictionary( new SearchViewModel {...}) ; – lontivero

答えて

0

RedirectToActionは、単にHTTP 302リダイレクトです。新しいページを再度リクエストするにはブラウザが必要ですか?

たとえば、ページの再読み込みが「投稿データの再送信」ダイアログを表示しないようにしたいですか?

が理由だけではなく、使用しない(POST-REDIRECT-GETパターンを参照してください):

public ActionResult Filter(FormCollection formParams) 
{ 
    return Search(new SearchViewModel{ 
    Term = formParams["Term"], 
    Filters = 
     formParams.Keys 
       .Cast<String>() 
       .Where(k => k.Contains("filter")) 
       .Select(k => Filter.Build(k, formParams[k])) 
       .ToList()       
    });           
} 

は、別の方法としては、適切であれば要求、またはおそらくクライアント側のクッキーの間で状態を保存するためにTempDataをを使用することができます。

ユーザーのブラウザで検索結果ページをブックマークできるようにするには、RESTまたは何らかの形のシリル化された文字列を使用してURLに検索パラメータの状態を表す必要があります(例:JSON)

0

このエラーを引き起こすよくある理由の1つは、「アクション、コメント、フィルタなど」のような何らかの種類のreserve wordsを使用しています。。したがって、Actionという名前を"フィルタ"と変更すると、別の名前、つまり"ApplyFilter"が問題を解決する可能性があります。これが役に立てば幸いです...