How to pass a Dictionary in a web service
I have created a simple service to provide configuration options as a Dictionary. I created a new SerializableDictionary class that implements IXmlSerializable as described on this board. When I add the service (via "Add Service Reference" in my consumer project), the method signature shows that it returns a DataSet. When I examine the DataSet at runtime it is empty.
Here is my service:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class AppSettingsService : System.Web.Ser开发者_StackOverflow社区vices.WebService
{
[WebMethod]
public SerializableDictionary<string, string> ReadAppSettings()
{
return AppSettings.Settings; // Settings is a SerializableDictionary<string, string>
}
}
On the Client side I do this:
using Clients.AppSettingsServiceReference;
static AppSettings()
{
AppSettingsServiceSoapClient client = new AppSettingsServiceSoapClient();
var settings = client.ReadAppSettings();
// ...
}
I expect settings to be a SerializableDictionary but it's an empty DataSet. I've tried sending it as a List of KeyValuePairs as suggested here and elsewhere but that also returns a DataSet. I'm using C#, ASP.Net 3.5, VS2008 Pro I'm sure I'm overlooking something simple but I can't find it. Can someone show me how to do this?
In general, web services of any kind do not understand data types which are specific to the platform you're running on.
In particular, there's no general concept of "dictionary", so web services don't understand them.
More to the point, there's no way to get anything like a dictionary across ASMX web services. If you were using WCF (as you should be doing for all new development), then you could use the same types on the client as on the service.
Of course, you'd still have the same problem if your client and service are not both running .NET.
John Saunders is right: this isn't really possible. The "right" way to do what you're trying to do is to create a class that represents the key-value pairs you're really trying to return, and then return an IEnumerable
of that class. For example:
public class AppSetting
{
public string Name {get;set;}
public string Value {get;set;}
}
[WebMethod]
public IEnumerable<AppSetting> ReadAppSettings()
{
return AppSettings.Settings.Select(
kvp => new AppSetting{Name = kvp.Key, Value = kvp.Value});
}
This provides the data straight to the consumer: let them decide whether they want to represent this as a Dictionary/Hashtable, List, Array, Tree, or any other data structure they decide to make of it. All you care about from a data-integrity standpoint is making sure each key is tied to the right value.
精彩评论