C# 类型转换列表<;T>;从TempData

C# 类型转换列表<;T>;从TempData,c#,asp.net-mvc-4,C#,Asp.net Mvc 4,我正在尝试创建一个MVC视图,为我的搜索结果显示一个“详细信息”页面,它可以是多种不同的类型(应用程序、人员、计算机、许可证等) 考虑到所有这些不同的类型都没有相同的对象属性,甚至没有相同的基本属性,我决定要做的是将搜索视图上的结果列表传递给Details控制器 但是,我在控制器内读取该信息时遇到问题。。。以下是我目前掌握的代码(部分): public ActionResult Details(int index) { List<object> SearchR

我正在尝试创建一个MVC视图,为我的搜索结果显示一个“详细信息”页面,它可以是多种不同的类型(应用程序、人员、计算机、许可证等)

考虑到所有这些不同的类型都没有相同的对象属性,甚至没有相同的基本属性,我决定要做的是将搜索视图上的结果列表传递给Details控制器

但是,我在控制器内读取该信息时遇到问题。。。以下是我目前掌握的代码(部分):

public ActionResult Details(int index)
    {
        List<object> SearchResults = TempData.ContainsKey("SearchItems") ? TempData["SearchItems"] as List<object> : null;
        if(SearchResults == null)
        {
            //go to error page.
            ViewBag.ErrorDescription = "Oups! Something went wrong trying to load the profile information. If you continue to see this error message, please contact the system administrator with the details below.";
            ViewBag.ErrorMessage = "An internal error occurred: TempData object key not found.";
            return View("Error");
        }

        if(SearchResults.Count == 0)
        {
            //go to error page.
            ViewBag.ErrorDescription = "Oups! Something went wrong trying to load the profile information. If you continue to see this error message, please contact the system administrator with the details below.";
            ViewBag.ErrorMessage = "An internal error occurred: TempData object contains no elements.";
            return View("Error");
        }

        //I also check if the index is out of range and stuff... 

        object TypeUse = SearchResults[0];

         //case statement and other actions are here...

    }
public ActionResult详细信息(int索引)
{
列出SearchResults=TempData.ContainsKey(“SearchItems”)?TempData[“SearchItems”]作为列表:null;
if(SearchResults==null)
{
//转到错误页面。
ViewBag.ErrorDescription=“Oups!尝试加载配置文件信息时出错。如果您继续看到此错误消息,请与系统管理员联系,并提供以下详细信息。”;
ViewBag.ErrorMessage=“发生内部错误:找不到TempData对象键。”;
返回视图(“错误”);
}
if(SearchResults.Count==0)
{
//转到错误页面。
ViewBag.ErrorDescription=“Oups!尝试加载配置文件信息时出错。如果您继续看到此错误消息,请与系统管理员联系,并提供以下详细信息。”;
ViewBag.ErrorMessage=“发生内部错误:TempData对象不包含任何元素。”;
返回视图(“错误”);
}
//我还检查索引是否超出范围,以及其他内容。。。
对象类型使用=搜索结果[0];
//案例陈述和其他行动在此。。。
}
到目前为止,我可以通过在调试器中查找
TempData[SearchItems]
来读取列表,它向我显示了正确的信息,但是,由于某种原因,只要我尝试转换到
list
搜索结果就会变为空

从上面的代码可以看出,我遵循的逻辑是:
  • 检查列表是否存在
  • 检查它是否是空的
  • 其他支票;及
  • 只有这样,才能通过列表中的第一个元素将其类型转换为真实类型

  • 从那里,我将在视图中显示该类型对象的正确信息

    所以我的问题有两个方面:

  • 我这样做的逻辑正确吗
  • 有没有其他方法/标准方法可以做到这一点
  • (除非
    T
    对象
    )。您可以强制转换为
    IEnumerable
    ,并更改“第一个”对象提取:

    IEnumerable<object> SearchResults = 
        TempData.ContainsKey("SearchItems") ? 
            TempData["SearchItems"] as IEnumerable<object> : 
            null;
    
    ...
    
    object TypeUse = SearchResults.First();
    
    IEnumerable SearchResults=
    TempData.ContainsKey(“搜索项”)?
    TempData[“SearchItems”]作为IEnumerable:
    无效的
    ...
    object TypeUse=SearchResults.First();
    
    (除非
    T
    对象
    )。您可以强制转换为
    IEnumerable
    ,并更改“第一个”对象提取:

    IEnumerable<object> SearchResults = 
        TempData.ContainsKey("SearchItems") ? 
            TempData["SearchItems"] as IEnumerable<object> : 
            null;
    
    ...
    
    object TypeUse = SearchResults.First();
    
    IEnumerable SearchResults=
    TempData.ContainsKey(“搜索项”)?
    TempData[“SearchItems”]作为IEnumerable:
    无效的
    ...
    object TypeUse=SearchResults.First();
    
    这是由于

    Cat
    Dog
    都是从
    Animal
    继承的

    您可能希望能够将
    列表
    转换为
    列表
    ,例如

    List<Cat> cats = new List<Cat>();
    cats.Add(new Cat());
    List<Animal> animals = (List<Animal>)cats;
    
    Animal first = animals[0];
    
    Dog
    不是要存储到
    列表中的有效类型

    当您想要提取一组基本类型时,可以使用
    IEnumerable

    IEnumerable动物=(IEnumerable)猫;
    动物优先=猫。优先();//使用Linq;
    
    请注意,出于类似的原因,您不能直接返回到
    IEnumerable
    ,因为并非所有
    动物都是
    Cat
    。您可以使用Linq扩展方法
    OfType()
    Cast()
    来执行此操作

    因此,在您的情况下,您需要
    SearchResults
    类型为
    IEnumerable
    ,或者甚至是一个基本接口/类,所有可搜索类型都从该接口/类继承,从而允许您利用逻辑中的任何公共属性

    跟进

    如果您使用的是.Net 4.5,则可以使用
    IReadonlyList
    而不是
    IEnumerable
    。这提供了仍然提供计数和项目索引的额外优势

    这是由于

    Cat
    Dog
    都是从
    Animal
    继承的

    您可能希望能够将
    列表
    转换为
    列表
    ,例如

    List<Cat> cats = new List<Cat>();
    cats.Add(new Cat());
    List<Animal> animals = (List<Animal>)cats;
    
    Animal first = animals[0];
    
    Dog
    不是要存储到
    列表中的有效类型

    当您想要提取一组基本类型时,可以使用
    IEnumerable

    IEnumerable动物=(IEnumerable)猫;
    动物优先=猫。优先();//使用Linq;
    
    请注意,出于类似的原因,您不能直接返回到
    IEnumerable
    ,因为并非所有
    动物都是
    Cat
    。您可以使用Linq扩展方法
    OfType()
    Cast()
    来执行此操作

    因此,在您的情况下,您需要
    SearchResults
    类型为
    IEnumerable
    ,或者甚至是一个基本接口/类,所有可搜索类型都从该接口/类继承,从而允许您利用逻辑中的任何公共属性

    跟进


    如果您使用的是.Net 4.5,则可以使用
    IReadonlyList
    而不是
    IEnumerable
    。这提供了仍然提供计数和项目索引的额外优势

    TempData是单读的,我知道,这很好。。。我只需要通过querystring传递结果集和索引号。。。一旦我在另一个控制器中读取它,我就可以将它作为单个对象存储在该控制器中。请注意,不能将
    列表
    强制转换为
    列表
    (除非
    T<