2012-01-18 68 views
0

編輯: 顯然我有什麼工作。我一直在使用從序列化對象生成的xml進行測試,該序列化對象不起作用。我正在更多地討論它,並決定嘗試使用我創建的動態XML(與此處發佈的相同),並且它工作正常。我認爲也許是因爲當我在使用相同的命名空間之前以這種方式嘗試它時... 但是,如何使用序列化對象中的xml不起作用?我注意到當它由對象創建時,它在xml中使用不同的名稱空間。這是爲什麼?REST API服務中的對象作爲參數問題

原文章: 我有一個將自定義對象傳遞給我創建的REST API的問題。現在我只是試圖通過發佈Lead類型的對象到WebInvoke方法來測試它。 我的服務是用WCF編寫的。 Lead對象位於一個單獨的類庫項目中,將由我的業務邏輯層完成。

我使用常規的ASP .net頁面發佈。您將在下面的代碼段中看到,我嘗試了以兩種方式手動構建xml,並且還將該對象序列化爲xml並將其用作POST數據。都不工作,我得到這個錯誤: 遠程服務器返回一個錯誤:(400)錯誤的請求。

我知道服務配置正確,因爲我可以調用並從我寫的其他WebInvoke方法獲得響應,這是一種GET方法。

這裏是衛浴套間代碼: 服務接口代碼:

[ServiceContract(Namespace = "http://www.mytestnamespace.com/test")] 
public interface IRESTService 
{ 
    [OperationContract] 
    [WebInvoke(Method = "POST", 
     UriTemplate = "leads", 
     RequestFormat = WebMessageFormat.Xml, 
     ResponseFormat = WebMessageFormat.Xml)] 
    string AddLead(Lead lead); 

    [OperationContract] 
    [WebInvoke(Method = "GET", 
     UriTemplate = "lead/{id}", 
     ResponseFormat = WebMessageFormat.Xml)] 
    string LeadData(string id); 
} 

服務代碼:

public class RESTService : IRESTService 
{ 
    public string AddLead(Lead lead) 
    { 
     return "AddLead Hit"; 
    } 

    public string LeadData(string id) 
    { 
     return "LeadData was hit, id=" + id; 
    } 
} 

鉛對象代碼:

[DataContract(Name="Lead", 
    Namespace = "http://www.mytestnamespace.com/test")] 
public class Lead 
{ 
    [DataMember(Name="FirstName")] 
    public string FirstName { get; set; } 
    [DataMember(Name = "LastName")] 
    public string LastName { get; set; } 
    [DataMember(Name = "Email")] 
    public string Email { get; set; } 
    [DataMember(Name = "Phone")] 
    public string Phone { get; set; } 
} 

最後我是代碼在aspx頁面上使用以發佈數據:

try 
    { 
     Lead l = new Lead(); 
     l.FirstName = "John"; 
     l.LastName = "Doe"; 
     l.Email = "[email protected]"; 
     l.Phone = "5555551234"; 

     XmlSerializer ser = new XmlSerializer(typeof(Lead)); 
     StringWriter sw = new StringWriter(); 
     ser.Serialize(sw, l); 

     string s = sw.ToString(); 




     /*XmlDocument doc = new XmlDocument(); 
     XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null); 

     XmlElement root = doc.CreateElement("Lead"); 
     root.SetAttribute("xmlns", "http://www.mytestnamespace.com/test"); 
     //root.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); 
     doc.InsertBefore(dec, doc.DocumentElement); 
     doc.AppendChild(root); 

     XmlElement firstName = doc.CreateElement("FirstName"); 
     XmlElement lastName = doc.CreateElement("LastName"); 
     XmlElement email = doc.CreateElement("Email"); 
     XmlElement phone = doc.CreateElement("Phone"); 

     firstName.AppendChild(doc.CreateTextNode("John")); 
     lastName.AppendChild(doc.CreateTextNode("Doe")); 
     email.AppendChild(doc.CreateTextNode("[email protected]")); 
     phone.AppendChild(doc.CreateTextNode("8885551234")); 

     root.AppendChild(firstName); 
     root.AppendChild(lastName); 
     root.AppendChild(email); 
     root.AppendChild(phone);*/ 

     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri("http://localhost:54966/RESTService.svc/leads")); 
     req.Method = "POST"; 
     req.ContentType = "application/xml"; 
     //byte[] formData = UTF8Encoding.UTF8.GetBytes(doc.InnerXml); 
     byte[] formData = UTF8Encoding.UTF8.GetBytes(s); 
     req.ContentLength = formData.Length; 

     using (Stream post = req.GetRequestStream()) 
     { 
      post.Write(formData, 0, formData.Length); 
     } 

     string result = null; 
     using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) 
     { 
      StreamReader reader = new StreamReader(resp.GetResponseStream()); 
      result = reader.ReadToEnd(); 
     } 
    } 
    catch (Exception exc) 
    { 
     throw exc; 
    } 
+1

您正在使用XmlSerializer來序列化您的Lead對象,並猜測您的服務使用DataContractSerializer對其進行反序列化,因此您會收到400錯誤的請求錯誤。嘗試在對象上使用DataContractSerializer。 – Rajesh 2012-01-18 10:15:16

回答

1

雖然您可以使用DataContractSerializer對IXmlSerializable,[Serializable],POCO等類型進行序列化,就好像它們已經使用其本機序列化程序進行序列化一樣,但反過來卻並非如此。您不能使用其他序列化器對[DataContract]類型進行序列化/反序列化,並仍然得到您實際打算獲得的結果。在這種情況下,XmlSerializer完全忽略了[DataContract]屬性,但它不會引發異常。這是因爲它假定它像另一個帶有公共字段和屬性的POCO(普通的舊C#對象)類型,並試圖使用該模型序列化它。

有關更多信息,請參閱博客帖子在http://blogs.msdn.com/b/sowmy/archive/2006/02/22/536747.aspxhttp://blogs.msdn.com/b/sowmy/archive/2006/05/14/why-prevent-datacontract-ixmlserializable.aspx

所以,這裏的解決方案是兩件事情之一: - 從你的DataContract類型刪除DataContract等,並開始使用[Serializable接口] ,IXmlSerializable的,ISerializable的,POCO,或者你可以用XmlFormatter使用一些其他的serializaton機制或XmlSerializer的

  • 刪除XmlSerializer的使用量和使用的DataContractSerializer來代替。