I send a Webrequest using
var request = new RestRequest(string.Format(url, config.ApiLocale), Method.POST)
{
RequestFormat = DataFormat.Xml,
XmlSerializer = new RestSharp.Serializers.DotNetXmlSerializer("")
};
My request is built like this:
List<RequestParam> listParams = new List<RequestParam>()
{
new RequestParam("Foo1"),
new RequestParam("Foo2"),
new RequestParam(12345)
};
request.AddBody(new XmlRequest
{
MethodName = "api.Testcall",
ListParams = listParams
});
My classes:
using RestSharp.Deserializers;
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace Testcall
{
[XmlRoot("methodCall")]
public class XmlRequest
{
[XmlElement(ElementName = "methodName")]
public string MethodName { get; set; }
[XmlArray(ElementName = "params")]
[XmlArrayItem("param")]
public List <RequestParam> ListParams { get; set; }
}
public class RequestParam
{
[XmlElement(ElementName = "value")]
public ParamFather Value { get; set; }
public RequestParam() { }
public RequestParam(String PassValue)
{
Value = new StringParam(PassValue);
}
public RequestParam(int PassValue)
{
Value = new IntParam(PassValue);
}
public RequestParam(Boolean PassValue)
{
Value = new BoolParam(PassValue);
}
}
[XmlInclude(typeof(StringParam))]
[XmlInclude(typeof(BoolParam))]
[XmlInclude(typeof(IntParam))]
public class ParamFather
{
[XmlElement(ElementName = "father")]
public String Content { get; set; }
}
public class StringParam : ParamFather
{
[XmlElement(ElementName = "string")]
public String StringContent { get; set; }
public StringParam() { }
public StringParam(String Content)
{
StringContent = Content;
}
}
}
But the Serializer returns an XML including Strange d4p1 and xmlns-Tags. Those I want to omit! I just need the plain xml not wearing any tags.
<methodCall>
<methodName>api.Testcall</methodName>
<params>
<param>
<value d4p1:type=\"StringParam\" xmlns:d4p1=\"http://www.w3.org/2001/XMLSchema-instance\">
<string>Foo1</string>
</value>
</param>
<param>
<value d4p1:type=\"StringParam\" xmlns:d4p1=\"http://www.w3.org/2001/XMLSchema-instance\">
<string>Foo2</string>
</value>
</param>
<param>
<value d4p1:type=\"IntParam\" xmlns:d4p1=\"http://www.w3.org/2001/XMLSchema-instance\">
<int>12345</int>
</value>
</param>
</params>
</methodCall>
I tried using the classic XMLSerializer instead but failed. Is it possible to do this with the DotNetXmlSerializer at all?
Finally I solved the problem by switching to the standard XmlSerializer.
[XmlRoot("methodCall")]
public class XmlRequest
{
[XmlElement(ElementName = "methodName")]
public string MethodName { get; set; }
[XmlArray(ElementName = "params")]
[XmlArrayItem("param")]
public List <RequestParam> ListParams { get; set; }
public string ToXML()
{
using (var stringwriter = new System.IO.StringWriter())
{
using (var xmlwriter = XmlWriter.Create(stringwriter, new XmlWriterSettings { OmitXmlDeclaration = true }))
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", "");
new XmlSerializer(this.GetType()).Serialize(xmlwriter, this, ns);
}
return stringwriter.ToString();
}
}
}
I am calling it like this:
List<RequestParam> listParams = new List<RequestParam>()
{
new RequestParam("user"),
new RequestParam("password"),
new RequestParam(true),
new RequestParam(123)
};
request.Parameters.Clear();
XmlRequest reqObject = new XmlRequest
{
MethodName = "api.Testcall",
ListParams = listParams
};
string rawXml = reqObject.ToXML();
request.AddParameter("application/xml", rawXml, ParameterType.RequestBody);
Notice that I am now using request.AddParameter instead of request.AddBody which I used before. So I have more control, Creating a String by the standard XmlSerializer. The OmitXmlDeclaration suppresses the encoding and the standard start of xml-Document. My Classes changed also:
public class RequestParam
{
[XmlElement(ElementName = "value")]
public Alterable Value { get; set; }
public RequestParam() { }
public RequestParam(int number)
{
Value = new Alterable(number);
}
public RequestParam(String str)
{
Value = new Alterable(str);
}
public RequestParam(Boolean boo)
{
Value = new Alterable(boo);
}
}
public class Alterable
{
[XmlElement(DataType = "string",Type = typeof(string)),
XmlElement(DataType = "int",Type = typeof(int)),
XmlElement(DataType = "boolean",Type = typeof(Boolean))]
public object Changeable { get; set; }
public Alterable() { }
public Alterable(int number)
{
Changeable = number;
}
public Alterable(string str)
{
Changeable = str;
}
public Alterable(Boolean boo)
{
Changeable = boo;
}
}
My Alterable class can take strings, ints and booleans and prints them correctly into the XML. Hope this helps someone having the same issues.
The Result:
<methodCall>
<methodName>api.Testcall</methodName>
<params>
<param>
<value>
<string>user</string>
</value>
</param>
<param>
<value>
<string>password</string>
</value>
</param>
<param>
<value>
<boolean>true</boolean>
</value>
</param>
<param>
<value>
<int>123</int>
</value>
</param>
</params>
</methodCall>