从类型'System.String'到类型'T'的参数转换失败,因为没有类型转换器可以在这些类型之间进行转换

时间:2011-06-20 01:15:59

标签: asp.net-mvc

注意:这里的所有代码都被解释为一个例子,因为我无法显示真实的代码。

我有一个看起来像

的视图模型类
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。此控制器处理创建过滤器类并重定向到“搜索”操作。

类似的东西:

    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,并将List集合填充回搜索操作。

但是,在搜索操作中,ModelState.IsValid现在返回false。这是因为模型绑定器抛出了这个异常:

  

从类型转换参数   'System.String'键入'Filter'   失败因为没有类型转换器可以   在这些类型之间转换。

查看ModelState中“过滤器”的原始值,显示为字符串:

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

似乎在动作之间的转换过程中List的实际内容丢失了,可能是因为它只在属性成员上调用了ToString()。

此时,我有一个模糊的想法,为什么这是失败的,我想我可以写一个自定义模型绑定器或类型转换器,使其工作,但是,我觉得这种方法闻起来,这是可能是微不足道的事情,我只是接近它错了。

那么,将一组复杂类型从一个动作传递到另一个动作的适当的ASP.NET MVC 3是什么?

2 个答案:

答案 0 :(得分: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在请求之间存储状态,或者如果合适,可以使用客户端cookie。

如果您希望搜索结果页面在用户浏览器中可收藏,则需要使用REST或某种形式的序列化字符串(例如JSON)在URL中表示搜索参数的状态

答案 1 :(得分:0)

导致此错误的常见原因之一是使用某种reserve words,例如&#34;操作,评论,过滤等等&#34; 。因此,使用其他名称(即&#34; ApplyFilter&#34; )更改Action名称​​&#34;过滤&#34; 可能会解决问题。希望这会有所帮助...