我应该如何从一个控制器操作返回两个对象列表?

Posted

技术标签:

【中文标题】我应该如何从一个控制器操作返回两个对象列表?【英文标题】:How should I return two lists of objects from one Controller Action? 【发布时间】:2015-04-29 00:39:38 【问题描述】:

我有两个来自同一个对象的不同列表。我想同时获取这两个作为单独的列表,或者在返回 JSON 对象时加入这两个相同的列表。

这是我的代码。

List<User> userEntity = users.Where(s => s.Id == Id).ToList();

var GetUserNames = userEntity.SelectMany(s => s.Names.Select(u =>
    new
    
        Name = u.Name,
        Id = u.Id
    )).ToList();

var GetProfile = userEntity.SelectMany(s => s.Profile.Select(u =>
    new
    
        Name = u.Name,
        Id = u.Id
    )).ToList();

return Json(GetUserNames, JsonRequestBehavior.AllowGet);

【问题讨论】:

那么你想做什么 - 返回两个单独的列表,还是将两者结合在一起?如果你想返回两个单独的列表,你可能只想使用一个匿名类型,将它们都包含在... 【参考方案1】:

我希望以不同的方式执行此操作:返回的项目是不同的类型。与其返回带有类型鉴别器的裸 JSON 列表,不如返回一个多属性 JSON 对象:

return Json(new 
 
    Names = GetUserNames, 
    Profiles = GetProfile 
, JsonRequestBehavior.AllowGet);

您返回的 JSON 将以草图形式将 Name, Id 对象分成它们的类型:

 
  Names: [
   Name:"UserName", Id:"3", 
   Name:"OtherUser", Id: "4"
  ],
  Profiles: [
   Name:"Normal", Id:"1", 
   Name:"Admin", Id: "99"
  ]

在大多数 JSON.Net 客户端解析场景(即从 WPF 智能客户端使用 WebAPI)中,您的自动映射(例如来自 RestSharp)将允许您将其反序列化为表单的类

public class NameId

     public int Id get; set;
     public string Name get; set;


public class UserNamesResponse

     public List<NameId> Names get; set;
     public List<NameId> Profiles get; set;

这可能比交错列表更方便和更清晰,交错列表无论如何都必须过滤到单独的列表中进行绑定......(或通过过滤类型转换器馈送,但在 UI 绑定层中会降低性能...... )

【讨论】:

这非常有用,并且很容易在 UI 中转换。非常感谢 @wpfroookie 我完全同意上述观点。我以为你需要它们在一个列表中。 :)【参考方案2】:

你可以使用GetUserNames.Concat(GetProfile)

List<User> userEntity = users.Where(s => s.Id == Id).ToList();

var GetUserNames = userEntity.SelectMany(s => s.Names.Select(u =>
    new
    
        Name = u.Name,
        Id = u.Id
    )).ToList();

var GetProfile = userEntity.SelectMany(s => s.Profile.Select(u =>
  new
  
      Name = u.Name,
      Id = u.Id
  )).ToList();

return Json(GetUserNames.Concat(GetProfile) , JsonRequestBehavior.AllowGet);

Enumerable.Concat Method

根据 cmets 更新

创建一个类和枚举:

public class NameId

    public string  Name get;set;
    public string  Id get;set;
    public ThisType Type  get; set; 


public enum ThisType

   Username,
   Profile

然后将其返回:

List<User> userEntity = users.Where(s => s.Id == Id).ToList();

var GetUserNames = userEntity.SelectMany(s => s.Names.Select(u =>
    new NameId
    
        Name = u.Name,
        Id = u.Id,
        Type = ThisType.Username
    )).ToList();

var GetProfile = userEntity.SelectMany(s => s.Profile.Select(u =>
  new NameId
  
      Name = u.Name,
      Id = u.Id,
      Type = ThisType.Profile
  )).ToList();

return Json(GetUserNames.Concat(GetProfile) , JsonRequestBehavior.AllowGet);

【讨论】:

@hutchnoid 我知道我们可以这样通过,但我的情况是我想在一个列表框中填写用户名,在另一个列表框中填写个人资料。我只会得到一个 Json 对象。如何区分和填充各自的列表框。 @WPFRookie 如果它们不同,也许你应该创建 2 个函数。为什么要在 1 个列表中返回 2 个不同的东西? @peer 因为我不想为两个不同的列表使用相同的 ID 回发两次。 @WPFRookie 查看更新,根据需要命名类/枚举。

以上是关于我应该如何从一个控制器操作返回两个对象列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何将列表和字符串从一个控制器的两个操作传递到一个视图?如何在视图文件中单独获取这些数据?

如何从 Spring MVC 控制器返回对象以响应 AJAX 请求?

从 Spring Boot 控制器返回非 JSON 数据(对象列表)

将 Json 对象从控制器操作返回到 jQuery

从 MVC 控制器返回带有对象列表的 JsonResult

如何从表视图控制器转到详细控制器并返回