【问题标题】:How to return list<dynamic> from webservice如何从 web 服务返回 list<dynamic>
【发布时间】:2014-10-13 23:53:37
【问题描述】:

我有一个返回动态列表的函数,我想将它返回。这可能吗?

我的功能是

   public List<dynamic> GiveMeProjects(int id)
        {
            Entities.VSTMEntities vstm = new Entities.VSTMEntities();
            var currentUserProject = (from users in vstm.Users
                                      from project in users.Projects
                                      where users.UserID == id
                                      select new
                                      {
                                          Id = project.ProjectID,
                                          Name = project.ProjectName
                                      }).ToList<dynamic>();

            return currentUserProject;
        }

并将其称为

  [WebMethod()]
  public List<dynamic> GiveMeProjects(string id)
  {
     int pId = Convert.ToInt32(id);
     return projectItems.GiveMeProjects(pId);
   }

当我在测试服务时,这个函数正在生成异常

There was an error generating the XML document. ---> System.InvalidOperationException: f__AnonymousType102[System.Int32,System.String] cannot be serialized because it does not have a parameterless constructor. at System.Xml.Serialization.TypeDesc.CheckSupported() at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError) at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException(Type type) at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write9_ArrayOfAnyType(Object o) at Microsoft.Xml.Serialization.GeneratedAssembly.ListOfObjectSerializer.Serialize(Object objectToSerialize, XmlSerializationWriter writer) at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) --- End of inner exception stack trace --- at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces) at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue) at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream) at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues) at System.Web.Services.Protocols.WebServiceHandler.Invoke()

如何解决此问题

【问题讨论】:

  • 不,您不能从 Web 服务返回动态。它必须为返回类型定义一个结构。您可以返回一个 XML 或 JSON 字符串,但是客户端在看到返回数据之前不知道会收到什么数据。
  • 由于您知道在这种情况下返回的内容的结构,因此这里不需要动态。如果这是您的实际用例,那么只需使用 IdName 构建一个类。
  • @JoeEnos 问题是,如果我返回列表,那么该类中的每个属性也会被发送。我有兴趣只发送特定的属性值
  • 对 - 您不必返回原始对象,但您可以将其转换为更简单的对象 - 您的查询很接近,但您可以使用 select new { Id = project.ProjectID, Name = project.ProjectName }).ToList&lt;dynamic&gt;(); 而不是 select new Foo { Id = project.ProjectID, Name = project.ProjectName }).ToList(); ,假设您有一个名为 Foo 的类,其中包含这两个属性。
  • 我再次使用了我的小技巧,我只是将结果转换为 json 字符串并发送回

标签: c# .net web-services serialization asmx


【解决方案1】:

C# 动态关键字不打算这样使用。既然你现在要返回什么,正确的方法是创建一个类或结构并返回它。

public class ProjectOverview
{
   public int Id { get; set; }
   public int Name { get; set; }
}
public List<ProjectOverview> GiveMeProjects(int id)
        {
            Entities.VSTMEntities vstm = new Entities.VSTMEntities();
            var currentUserProject = (from users in vstm.Users
                                      from project in users.Projects
                                      where users.UserID == id
                                      select new ProjectOverview()
                                      {
                                          Id = project.ProjectID,
                                          Name = project.ProjectName
                                      }).ToList();

            return currentUserProject;
        }

动态关键字只能在特殊场合使用。您可以在officals MSDN article 中找到详细信息。如果您不想这样做,您可以检查现有的类,如 KeyValuePair 或 Tuple。虽然不建议这样做。服务需要一个清晰的界面,以便客户可以轻松访问它。这最好通过将自定义类公开为返回值来完成(也涉及在某一点扩展您的界面)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2019-02-14
    • 2010-10-28
    相关资源
    最近更新 更多