通过Web服务序列化自定义对象中的名称/值对 [英] Serializing Name/Value Pairs in a Custom Object via Web Service

查看:74
本文介绍了通过Web服务序列化自定义对象中的名称/值对的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个非常复杂的问题,涉及在未严格键入数据时如何通过Web服务调用来序列化数据的问题.我会尽力将其布局.

This is a very complicated question concerning how to serialize data via a web service call, when the data is not-strongly typed. I'll try to lay it out as best possible.

示例存储对象:

[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>

原因&其他资料:

首先,对这篇文章的篇幅感到抱歉,但我也想提供可复制的代码.

First, I'm sorry for the length of the post, but I wanted to give reproducible code as well.

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

I want it in this format, because I'm consuming the web services from PHP. I want to easily go:

//这很重要

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

如果采用其他格式,那么我将完全没有办法实现.此外,如果使用C#,则在使用该服务时,我还希望能够执行以下操作:

If it's in the other format, then there would be no way for me to accomplish that, at all. Additionally, in C# if I am consuming the service, I would also like to be able to do the following:

//这很重要

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

不幸的是,我不确定如何做到这一点.通过构建实现IXmlSerializer的自定义词典(参见 StackOverflow:IXmlSerializer词典),但是,它使WSDL模式泛滥成灾.这也太复杂了,在我的WinFormsTester应用程序中产生了可怕的结果!

Unfortunately, I'm not sure how to accomplish this. I was able to get it this way, by building a custom Dictionary that implemented IXmlSerializer (see StackOverflow: IXmlSerializer Dictionary), however, it blew the WSDL schema out of the water. It's also much too complicated, and produced horrible results in my WinFormsTester application!

有什么办法可以做到这一点?我需要创建什么类型的对象?除了建立强类型的collection/之外,是否有其他方法可以做到这一点?显然,如果我使它像这样强键入:

Is there any way to accomplish this ? What type of objects do I need to create ? Is there any way to do this /other than by making a strongly typed collection/ ? Obviously, if I make it strongly typed like this:

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

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

Then it would work perfectly, I would have no WSDL issues, I would be able to easily access it from PHP, and C# (.OtherInfo.Hobbies).

但是,我将完全失去NVP的意义,因为我必须提前知道列表是什么,并且它是不可更改的,例如从数据库中更改.

However, I would completely lose the point of NVP's, in that I would have to know in advance what the list is, and it would be unchangeable.. say, from a Database.

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

Thanks everyone!! I hope we're able to come up with some sort of solution to this. Here's are the requirements again:

  1. WSDL模式不应中断
  2. 名称值对(NVP)应该序列化为属性格式
  3. 使用名称["Hobbyies"]可以很容易地在PHP中访问NVP.
  4. 应该易于在C#中访问(并与其Proxy生成器兼容)
  5. 易于序列化
  6. 不需要我强烈键入数据

现在,我愿意/完全/愿意以更好/不同的方式进行输入.我正在存储一些相对静态"的信息(例如Name)和一堆数据.如果有更好的方法,我很想听听.

Now, I am /completely/ open to input on a better/different way to do this. I'm storing some relatively "static" information (like Name), and a bunch of pieces of data. If there's a better way, I'd love to hear it.

推荐答案

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

This is like dynamic properties for a object. C# is not quite a dynamic language unlike javascript or maybe PHP can parse the object properties on the fly. The following two methods are what I can think of. The second one might fit into your requirements.

KISS方式

保持简单愚蠢的方式

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

您可以使用以"|"分隔的名称/值对

You can have name value pairs which is separated by '|'

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元素,以便您可以动态构建它.

Make the name value pair part become an XML element so that you can build it dynamically.

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

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

You can easily build up OtherInfo object as element centric e.g.

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>

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

or build it as attribute centric

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.

For any dynamic language, it can access to the properties directly. For the rest, they can access the value by read the XML. Reading XML is well supported by most of framework.

这篇关于通过Web服务序列化自定义对象中的名称/值对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆