diff --git a/Kveer.XmlRPC.Tests/paramstest.cs b/Kveer.XmlRPC.Tests/paramstest.cs index 56403f0..dd4db13 100644 --- a/Kveer.XmlRPC.Tests/paramstest.cs +++ b/Kveer.XmlRPC.Tests/paramstest.cs @@ -64,8 +64,14 @@ public object[] Linisgre(params object[] args) return args; } + [XmlRpcMethod] + public int OptioanlNullParameter(string optional = null) + { + return 1; + } - private readonly string massimoRequest = + + private readonly string massimoRequest = @" Send_Param @@ -579,7 +585,49 @@ public void SerializeObjectParams() .Replace("\r\n", Environment.NewLine), reqstr); } - [Test] + [Test] + public void SerializeNullParameterUnallowed() + { + Assert.Throws( + () => SerializeNullParameter(XmlRpcNonStandard.None)); + } + + [Test] + public void SerializeNullParameter() + { + string reqstr = SerializeNullParameter(XmlRpcNonStandard.AllowNull); + Assert.AreEqual( + @" + + SerializeOptionalNullParameter + + + + + + + +" + .Replace("\r\n", Environment.NewLine), reqstr); + } + + private string SerializeNullParameter(XmlRpcNonStandard options) + { + Stream stm = new MemoryStream(); + var req = new XmlRpcRequest(); + req.args = new object[] { null }; + req.method = "SerializeOptionalNullParameter"; + req.mi = typeof(IFoo).GetMethod("SerializeOptionalNullParameter"); + var ser = new XmlRpcSerializer(); + ser.NonStandard = options; + ser.SerializeRequest(stm, req); + stm.Position = 0; + TextReader tr = new StreamReader(stm); + var reqstr = tr.ReadToEnd(); + return reqstr; + } + + [Test] public void SerializeZeroParameters() { Stream stm = new MemoryStream(); diff --git a/Kveer.XmlRPC/XmlRpcNonStandard.cs b/Kveer.XmlRPC/XmlRpcNonStandard.cs index 6fb6971..b2bc5e6 100644 --- a/Kveer.XmlRPC/XmlRpcNonStandard.cs +++ b/Kveer.XmlRPC/XmlRpcNonStandard.cs @@ -37,6 +37,7 @@ public enum XmlRpcNonStandard MapZerosDateTimeToMinValue = 0x8, MapEmptyDateTimeToMinValue = 0x10, AllowInvalidHttpContent = 0x20, - All = 0x7fff + AllowNull = 0x40, + All = 0x7fff } } \ No newline at end of file diff --git a/Kveer.XmlRPC/XmlRpcSerializer.cs b/Kveer.XmlRPC/XmlRpcSerializer.cs index ab8e99a..cdcbba3 100644 --- a/Kveer.XmlRPC/XmlRpcSerializer.cs +++ b/Kveer.XmlRPC/XmlRpcSerializer.cs @@ -72,7 +72,9 @@ public class XmlRpcSerializer private bool MapZerosDateTimeToMinValue => (NonStandard & XmlRpcNonStandard.MapZerosDateTimeToMinValue) != 0; - public void SerializeRequest(Stream stm, XmlRpcRequest request) + private bool AllowNull => (NonStandard & XmlRpcNonStandard.AllowNull) != 0; + + public void SerializeRequest(Stream stm, XmlRpcRequest request) { var xtw = new XmlTextWriter(stm, XmlEncoding); ConfigureXmlFormat(xtw); @@ -137,11 +139,24 @@ private void SerializeParams(XmlTextWriter xtw, XmlRpcRequest request, } } - if (request.args[i] == null) - throw new XmlRpcNullParameterException(string.Format( - "Null method parameter #{0}", i + 1)); - xtw.WriteStartElement("", "param", ""); - Serialize(xtw, request.args[i], mappingAction); + xtw.WriteStartElement("", "param", ""); + if (request.args[i] == null) + { + if (!AllowNull) + { + throw new XmlRpcNullParameterException(string.Format( + "Null method parameter #{0}", i + 1)); + } + + xtw.WriteStartElement("", "value", ""); + xtw.WriteStartElement("", "nil", ""); + xtw.WriteEndElement(); + xtw.WriteEndElement(); + } + else + { + Serialize(xtw, request.args[i], mappingAction); + } xtw.WriteEndElement(); } }