C# 如何在 WebService 中返回通用字典
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/679050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Return Generic Dictionary in a WebService
提问by Jhonny D. Cano -Leftware-
I want a Web Service in C# that returns a Dictionary, according to a search:
我想要一个 C# 中的 Web 服务,根据搜索返回一个字典:
Dictionary<int, string> GetValues(string search) {}
The Web Service compiles fine, however, when i try to reference it, i get the following error: "is not supported because it implements IDictionary."
Web 服务编译得很好,但是,当我尝试引用它时,出现以下错误:“不支持,因为它实现了 IDictionary。”
?What can I do in order to get this working?, any ideas not involving return a DataTable?
?我该怎么做才能使这个工作?,任何不涉及返回数据表的想法?
采纳答案by Moose
This articlehas a method to serialize IDictionaries. Look for " I've noticed that XmlSerializer won't serialize objects that implement IDictionary by default. Is there any way around this?" about 2/3 the way down the page.
这篇文章有一个序列化IDictionaries的方法。查找“我注意到 XmlSerializer 默认不会序列化实现 IDictionary 的对象。有什么办法可以解决这个问题?” 大约在页面下方的 2/3 处。
回答by John Saunders
Create a type MyKeyValuePair<K,V>
, and return a List<MyKeyValuePair<int,string>>
, copied from the dictionary.
创建一个 type MyKeyValuePair<K,V>
,并返回 a List<MyKeyValuePair<int,string>>
,从字典中复制。
回答by Moose
I use this util class for serializing dictionaries, maybe it can be useful for you
我使用这个 util 类来序列化字典,也许它对你有用
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Utils {
///<summary>
///</summary>
public class SerializableDictionary : IXmlSerializable {
private readonly IDictionary<int, string> dic;
public DiccionarioSerializable() {
dic = new Dictionary<int, string>();
}
public SerializableDictionary(IDictionary<int, string> dic) {
this.dic = dic;
}
public IDictionary<int, string> Dictionary {
get { return dic; }
}
public XmlSchema GetSchema() {
return null;
}
public void WriteXml(XmlWriter w) {
w.WriteStartElement("dictionary");
foreach (int key in dic.Keys) {
string val = dic[key];
w.WriteStartElement("item");
w.WriteElementString("key", key.ToString());
w.WriteElementString("value", val);
w.WriteEndElement();
}
w.WriteEndElement();
}
public void ReadXml(XmlReader r) {
if (r.Name != "dictionary") r.Read(); // move past container
r.ReadStartElement("dictionary");
while (r.NodeType != XmlNodeType.EndElement) {
r.ReadStartElement("item");
string key = r.ReadElementString("key");
string value = r.ReadElementString("value");
r.ReadEndElement();
r.MoveToContent();
dic.Add(Convert.ToInt32(key), value);
}
}
}
}
回答by Warren Blanchet
There's no "default" way to take a Dictionary and turn it into XML. You have to pick a way, and your web service's clients will have to be aware of that same way when they are using your service. If both client and server are .NET, then you can simply use the same code to serialize and deserialize Dictionaries to XML on both ends.
没有“默认”方法可以将 Dictionary 转换为 XML。您必须选择一种方式,并且您的 Web 服务的客户在使用您的服务时也必须意识到同样的方式。如果客户端和服务器都是 .NET,那么您可以简单地使用相同的代码在两端将 Dictionaries 序列化和反序列化为 XML。
There's code to do this in this blog post. This code uses the default serialization for the keys and values of the Dictionary, which is useful when you have non-string types for either. The code uses inheritance to do its thing (you have to use that subclass to store your values). You could also use a wrapper-type approach as done in the last item in this article, but note that the code in that article just uses ToString, so you should combine it with the first article.
这篇博文中有代码可以做到这一点。此代码使用字典的键和值的默认序列化,这在您具有非字符串类型时非常有用。代码使用继承来完成它的工作(您必须使用该子类来存储您的值)。您也可以使用本文最后一项中所做的包装器类型的方法,但请注意,该文章中的代码仅使用 ToString,因此您应该将其与第一篇文章结合使用。
Because I agree with Joel about StackOverflow being the canonical source for everything, below is a copy of the code from the first link. If you notice any bugs, edit this answer!
因为我同意 Joel 关于 StackOverflow 是所有内容的规范来源的观点,下面是第一个链接中的代码副本。如果您发现任何错误,请编辑此答案!
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
回答by Gennady G
This solution with SerializableDictionary works great, but during work You can get
这个带有 SerializableDictionary 的解决方案效果很好,但在工作期间你可以得到
cannot convert from 'SerializableDictionary<string,string>' to 'System.Data.DataSet'
cannot convert from 'SerializableDictionary<string,string>' to 'System.Data.DataSet'
error. In this case You should go Project-> Show all files, and then edit argument type to SerializableDictionary in Reference.cs file of web service. It's an official microsoft bug, more detailed here:
错误。在这种情况下,您应该转到 Project-> Show all files,然后在 Web 服务的 Reference.cs 文件中将参数类型编辑为 SerializableDictionary。这是一个官方的微软错误,更详细的在这里: