适用于Web服务PUT / POST方法的XML序列化

时间:2015-12-17 12:59:49

标签: c# xml web-services wcf

我有WCF网络服务,它有下一个PUT方法

[OperationContract]
[WebInvoke(Method = "PUT", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
void ScanPatient(PatientInfo patientInfo);

//...

[XmlRoot("PatientInfo")]
public class PatientInfo
{
    [XmlElement("FirstName")]
    public string FirstName { get; set; }
    [XmlElement("LastName")]
    public string LastName { get; set; }
    [XmlElement("SSN")]
    public string SSN { get; set; }
    [XmlElement("Birthday")]
    public DateTime? Birthday { get; set; }
    [XmlElement("RequestedClientID")]
    public Guid RequestedClientID { get; set; }
    [XmlElement("patientId")]
    public Guid patientId { get; set; }
}

我使用WebRequest与此服务进行通信

private void ExecuteWebServiceCommand(string method, string command, string parameters = "")
{
    var request = (HttpWebRequest)WebRequest.Create(new Uri(command));
    request.ContentType = "application/xml";
    request.Method = method;

    string responseFromServer = null;
    byte[] bytes = Encoding.UTF8.GetBytes(parameters);

    request.ContentLength = bytes.Length;
    using (var newStream = request.GetRequestStream())
    {
        newStream.Write(bytes, 0, bytes.Length);
    }
    var response = request.GetResponse();
}

如果parameters使用下一个格式,则效果很好:

<PatientInfo><FirstName>{0}</FirstName><LastName>{1}</LastName><RequestedClientID>{2}</RequestedClientID></PatientInfo>

显然,我不想手动编写数据,因为每个新字段都需要更新模板。所以,我试图使用XMLSerializer

private string SerializeToString(object data)
{
    if (data == null) return null;
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("", "");

    using (var stringwriter = new System.IO.StringWriter())
    {
        var serializer = new XmlSerializer(data.GetType(), "");
        serializer.Serialize(stringwriter, data, ns);
        return stringwriter.ToString();
    }
}

但在序列化PatientInfo

时,我会得到下一个结果
"<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<PatientInfo>\r\n  <FirstName>Andrew</FirstName>\r\n  <LastName>Fox</LastName>\r\n  <Birthday d2p1:nil=\"true\" xmlns:d2p1=\"http://www.w3.org/2001/XMLSchema-instance\" />\r\n  <RequestedClientID>2c547deb-2395-4334-b1b0-58e6562b5843</RequestedClientID>\r\n  <patientId>00000000-0000-0000-0000-000000000000</patientId>\r\n</PatientInfo>"

它不适合ExecuteWebServiceCommand,给我(400)Bad Request异常。

那么,我怎样才能将对象正确地序列化为XML,使其适合这样的代码呢?或者我如何模拟代码来接受这样的数据呢?

1 个答案:

答案 0 :(得分:1)

您应该使用您使用正确的XmlWriter实例化的XmlWriterSettings来省略Xml声明,并且没有序列化的换行符。将此应用于您的代码时,您最终会得到:

private string SerializeToString(object data)
{
    if (data == null) return null;
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("", "");

    // what should the XmlWriter do?
    var settings = new XmlWriterSettings
    {
        OmitXmlDeclaration = true,
        NewLineChars = ""
    };

    using (var stringwriter = new System.IO.StringWriter())
    {
       // Use an XmlWriter to wrap the StringWriter
       using(var xmlWriter = XmlWriter.Create(stringwriter, settings))
       {
           var serializer = new XmlSerializer(data.GetType(), "");
           // serialize to the XmlWriter instance
           serializer.Serialize(xmlWriter, data, ns);
           return stringwriter.ToString();
       }
    }
}

这会给我这个结果:

  

&LT; PatientInfo&GT;&LT;姓&GT;富&LT; /姓&GT;&LT;生日&GT; 2015-12-19T16:21:48.4009949 + 01:00&LT; /生日&GT;&LT; RequestedClientID&GT; 00000000-0000-0000-0000-000000000000&LT ; / RequestedClientID&GT; 00000000-0000-0000-0000-000000000000&LT; / patientId&GT;&LT; / PatientInfo&GT;