I'm working on a Silverlight 3 project, and I have to connect to a database through a web service. One of the aspects of this web service is that there is a single common method that accepts the name of the stored proc to execute, and one or more parameters of various types.
Some things I learned along the way to figuring out my not-so-elegant solution:
0) Silverlight doesn't support the
Serialize
attribute.
1) A web service method can't accept generic lists of objects (nor apparently an array of
object
objects).
After playing with this for a couple of days, I came up with the following solution. The short version is that I created a xml string in the client, and parse it in the web service. To convert to a xml string, I did this:
public static XElement MakeXmlParameter(string name, object value)
{
XElement element = new XElement("Parameter",
new XElement("Name", name),
new XElement("Type", value.GetType()),
new XElement("Value", value));
return element;
}
And in the service, I have this method:
public class Parameters :List<SqlParameter>
{
}
private Parameters MakeSqlParameters(string xmlData)
{
Parameters parameters = null;
if (string.IsNullOrEmpty(xmlData))
{
XDocument xDoc = XDocument.Parse(xmlData);
XElement root = xDoc.Element("Parameters");
if (root.HasElements)
{
parameters = new Parameters();
IEnumerable<xelement> children = (from item in root.Elements() select item);
foreach (XElement value in children)
{
string paramName = value.Element("Name").Value;
string typeName = value.Element("Type").Value;
object obj = Convert.ChangeType(value.Element("Value").Value,
Type.GetType(typeName));
SqlParameter parameter = new SqlParameter(paramName, obj);
parameters.Add(parameter);
}
}
}
return parameters;
}</xelement>
There's probably a better way to do this given the project architecture, but I needed to get something working fast.
Side benefit - notice the call to the
Convert.ChangeType
method, I searched google for several hours before finding out that you could convert to a named type this way. Look at how much time I saved you from having to do the same google search! :)
EDIT===========================
You can make the
MakeSqlParameters()
method more generic by simply retrieving the first element before looping through all of the child elements. That way, it doesn't matter what they called the root node.