c# - 通过 Web 服务序列化自定义对象中的名称/值对

标签 c# php web-services serialization class-design

这是一个非常复杂的问题,涉及当数据不是强类型时如何通过网络服务调用序列化数据。我会尽量把它布置好。

示例存储对象:

[Serializable]
public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  public List<NameValuePairs> OtherInfo { get; set; }  
}
[Serializable]   
public class NameValuePairs {
  public string Name { get; set; }
  public string Value { get; set; }
}

示例使用:

[WebMethod]
    public List<StorageObject> GetStorageObjects() {
      List<StorageObject> o = new List<StorageObject>() {
        new StorageObject() { 
          Name = "Matthew",
          Birthday = "Jan 1st, 2008", 
          OtherInfo = new List<NameValuePairs>() {
            new NameValuePairs() { Name = "Hobbies", Value = "Programming" },
            new NameValuePairs() { Name = "Website", Value = "Stackoverflow.com" }
          }
        },
        new StorageObject() { 
          Name = "Joe",
          Birthday = "Jan 10th, 2008",
          OtherInfo = new List<NameValuePairs>() { 
            new NameValuePairs() { Name = "Hobbies", Value = "Programming" },
            new NameValuePairs() { Name = "Website", Value = "Stackoverflow.com" }
          }
        }
      };

      return o;
    }

Web 服务的返回值:

<StorageObject>
    <Name>Matthew</Name>
    <Birthday>Jan 1st, 2008</Birthday>
    <OtherInfo>
        <NameValuePairs>
            <Name>Hobbies</Name>
            <Value>Programming</Value>
        </NameValuePairs>
        <NameValuePairs>
            <Name>Website</Name>
            <Value>Stackoverflow.com</Value>
        </NameValuePairs>
    </OtherInfo>
</StorageObject>

我想要的:

<OtherInfo>
    <Hobbies>Programming</Hobbies>
    <Website>Stackoverflow.com</Website>
</OtherInfo>

原因及其他内容:

首先,对于帖子的长度,我深表歉意,但我也想提供可重现的代码。

我想要这种格式,因为我正在使用来自 PHP 的 Web 服务。我想轻松走:

//这很重要

In PHP => "$Result["StorageObject"]["OtherInfo"]["Hobbies"]".  

如果它是其他格式,那么我根本无法完成它。此外,在 C# 中,如果我正在使用该服务,我还希望能够执行以下操作:

//这很重要

In C# => var m = ServiceResult[0].OtherInfo["Hobbies"];

不幸的是,我不确定如何完成此操作。通过构建实现 IXmlSerializer 的自定义字典(请参阅 StackOverflow: IXmlSerializer Dictionary ),我能够以这种方式获得它,但是,它使 WSDL 架构大打折扣。它也太复杂了,并且在我的 WinFormsTester 应用程序中产生了可怕的结果!

有什么办法可以实现吗?我需要创建什么类型的对象?有没有办法做到这一点/除了制作强类型集合/?显然,如果我像这样强类型化:

public class OtherInfo {
  public string Hobbies { get; set; }
  public string FavoriteWebsite { get; set; }
}

然后它将完美地工作,我将没有 WSDL 问题,我将能够从 PHP 和 C# (.OtherInfo.Hobbies) 轻松访问它。

但是,我会完全失去 NVP 的意义,因为我必须提前知道列表是什么,而且它是不可更改的……比如说,来自数据库。

谢谢大家!!我希望我们能够对此提出某种解决方案。再次是要求:

  1. WSDL 架构不应中断
  2. 应将名称值对 (NVP) 序列化为属性格式
  3. 应该可以通过名称 ["Hobbies"] 轻松访问 PHP 中的 NVP
  4. 应该很容易在 C# 中访问(并与其代理生成器兼容)
  5. 易于序列化
  6. 不要求我强类型数据

现在,我/完全/愿意接受更好/不同方式的意见。我正在存储一些相对“静态”的信息(如名称)和一堆数据。如果有更好的方法,我很乐意听到。

最佳答案

这就像对象的动态属性。 与 javascript 不同,C# 不是一种动态语言,或者 PHP 可以即时解析对象属性。以下两种方法是我能想到的。第二个可能符合您的要求。

KISS 方式

保持简单愚蠢的方法

public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  public List<string> OtherInfo { get; set; }  
}

你可以有由'|'分隔的名称值对

OtherInfo = {"Hobbies|Programming", "Website|Stackoverflow.com"}

序列化表单

<StorageObject>
    <Name>Matthew</Name>
    <Birthday>Jan 1st, 2008</Birthday>
    <OtherInfo>
        <string>Hobbies|Programming</string>
        <string>Website|Stackoverflow.com</string>
    </OtherInfo>
</StorageObject>

C# 中的动态方式

将名称值对部分变成一个 XML 元素,以便您可以动态构建它。

public class StorageObject {
  public string Name { get; set; }
  public string Birthday { get; set; }
  public XElement OtherInfo { get; set; } // XmlElement for dot net 2
}

您可以轻松地构建以元素为中心的 OtherInfo 对象 例如

XElement OtherInfo = new XElement("OtherInfo");
OtherInfo.Add( ..Hobbies xelement & text value..);
OtherInfo.Add( ..WebSite xelement & text value..);

序列化形式将是

<OtherInfo>
    <Hobbies>Programming</Hobbies>
    <Website>Stackoverflow.com</Website>
</OtherInfo>

或将其构建为以属性为中心

XElement OtherInfo = new XElement("OtherInfo");
OtherInfo.Add( ..nvp xattribute Hobbies & value..);
OtherInfo.Add( ..nvp xattribute WebSite & value..);

<OtherInfo>
    <nvp n="Hobbies" v="Programming" />
    <nvp n="Website" v="Stackoverflow.com" />
</OtherInfo>

对于任何动态语言,它都可以直接访问属性。 对于其余部分,他们可以通过读取 XML 来访问该值。大多数框架都很好地支持读取 XML。

关于c# - 通过 Web 服务序列化自定义对象中的名称/值对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/255400/

相关文章:

c# - 是什么导致 Web 服务 URL 和 namespace 之间存在差异?

javascript - 除了 PHP 或 JavaScript 之外,浏览器还有转义字符吗?

php - 即使使用 set_time_limit(0) PHP/Apache,脚本也会超时

java - 在 WCF 客户端的 Java Web 服务(或重用类型)之间共享数据契约

android - 无法在我的项目中包含 AndroidHttpTransport

php - 不使用 WordPress 中的 dbDelta() 创建触发器

c# - 如何更新 Entity Framework Core 中修改的列?

c# - 如何防止创建的线程多于可用的硬件线程数?

c# - 使用 JsonConvert.DeserializeObject 将 Json 反序列化为 C# POCO 类

c# - KeyEvent 没有检测到任何键 C#