The code itself is nothing special, .NET makes it pretty easy to actually POST to the webservice. I wrote it in SharpDevelop (a freeware .NET coding environment thats not half bad) and compiled it with Mono. Also tested it with the MS compiler and framework v1.1 without problem.
Below the actual class library I am attaching a driver which implements the other half of the equation for the sample code found on the wiki
Before anyone goes on any while "well you should have coded it this way" session please note that this was written to be easy to read/understand. It is by no means designed for high performance, if I wanted that I wouldn't have used GetElementsByTagName in my xml calls, along with any number of other changes (Error handing for the webservice post, error handling for data-types, UriEncoding of sent data). Please use this code simply to understand how the process works and I hope it leads to someone coding something really cool.
CODE
// C# XMLRPC FOR SL Example by JustAnother Millhouse
// 2/10/2005
// Released to the SL public for whatever use they so please. If you make something nifty with it
// let me know, I'm always interested in seeing cool stuff.
using System;
using System.Text;
using System.Xml;
using System.Net;
namespace XMLRPC
{
//
public class XmlRPCResponseException : Exception
{
private string mMessage;
private int mErrorCode;
public string FaultMessage
{
get{ return this.mMessage; }
}
public int FaultCode
{
get{ return this.mErrorCode; }
}
public XmlRPCResponseException(string msg, int val)
{
this.mMessage = msg;
this.mErrorCode = val;
}
public override string ToString()
{
return base.ToString() + this.mMessage + " : " + this.mErrorCode;
}
}
public class XmlRPCRequest
{
public XmlRPCRequest()
{
}
// some public values to hold request/response
public string Channel;
public int IntValue;
public string StringValue;
public void SendXMLRPC()
{
//setup a webclient
WebClient web = new WebClient();
//build XML to send as request
byte[] byteArray = Encoding.ASCII.GetBytes(BuildRequest());
//post to server
byte[] responseArray = web.UploadData("http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi","POST",byteArray);
string serverResponse = Encoding.ASCII.GetString(responseArray);
//parse response
ParseResponse(serverResponse);
}
private string BuildRequest()
{
//use stringbuilder to build the XML request we are going to send to
//the server.
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\"?>");
sb.Append("<methodCall>");
sb.Append(" <methodName>llRemoteData</methodName>");
sb.Append(" <params>");
sb.Append(" <param>");
sb.Append(" <value>");
sb.Append(" <struct>");
sb.Append(" <member>");
sb.Append(" <name>Channel</name>");
sb.AppendFormat(" <value><string>{0}</string></value>",Channel);
sb.Append(" </member>");
sb.Append(" <member>");
sb.Append(" <name>IntValue</name>");
sb.AppendFormat(" <value><int>{0}</int></value>",IntValue);
sb.Append(" </member>");
sb.Append(" <member>");
sb.Append(" <name>StringValue</name>");
sb.AppendFormat(" <value><string>{0}</string></value>",StringValue);
sb.Append(" </member>");
sb.Append(" </struct>");
sb.Append(" </value>");
sb.Append(" </param>");
sb.Append(" </params>");
sb.Append("</methodCall>");
return sb.ToString();
}
// parse response, if there is a fault string, throw an exception with faultCode
private void ParseResponse(string response)
{
XmlDocument tempDom = new XmlDocument();
try
{
//load up our response xml into a DOM document
tempDom.LoadXml(response);
}
catch
{
// if we cannot load up response into XML dom then bad things happened
// throw generic exception
throw new Exception("Corrupt XML response received from server.");
}
// if a fault occured, throw an exception
if(tempDom.GetElementsByTagName("name")[0].InnerText.ToLower() == "faultstring")
{
throw new XmlRPCResponseException(tempDom.GetElementsByTagName("string")[0].InnerText, Int32.Parse(tempDom.GetElementsByTagName("int")[0].InnerText));
}
else
{
this.Channel = tempDom.GetElementsByTagName("string")[0].InnerText;
this.StringValue = tempDom.GetElementsByTagName("string")[1].InnerText;
this.IntValue = Int32.Parse(tempDom.GetElementsByTagName("int")[0].InnerText);
}
}
}
}
Sample Driver
CODE
using System;
namespace XMLRPC
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
XmlRPCRequest s = new XmlRPCRequest();
s.Channel = "88733d7d-c46f-bef5-3a6f-f7eb59ecfb13"; // set the UUID the script from the wiki outputs to you here
s.IntValue = 4;
s.StringValue = "How are you?";
s.SendXMLRPC();
Console.WriteLine(s.StringValue);
Console.ReadLine();
}
}
}