2014-05-07 64 views
0

我遇到的情況,我需要對類對象發送到WCF REST方法輸入下面給出。我們如何將類對象作爲XML傳遞給WCF REST post方法?

[OperationContract] 
     [WebInvoke(Method = "POST", UriTemplate = "/InsertContact", ResponseFormat = WebMessageFormat.Xml, 
      RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped)] 
     int InsertContact(ContactType objContactType); 

提示以下錯誤:在提琴手

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none"><Code><Value>Receiver</Value><Subcode><Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</Value></Subcode></Code><Reason><Text xml:lang="en-US">Error in deserializing body of request message for operation 'InsertContact'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'InsertContact' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'ContactType' and namespace ''</Text></Reason><Detail><ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><HelpLink i:nil="true"/><InnerException><HelpLink i:nil="true"/><InnerException i:nil="true"/><Message>OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'InsertContact' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'ContactType' and namespace ''</Message><StackTrace> at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)&#xD; 
    at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)&#xD; 
    at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)</StackTrace><Type>System.Runtime.Serialization.SerializationException</Type></InnerException><Message>Error in deserializing body of request message for operation 'InsertContact'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'InsertContact' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'ContactType' and namespace ''</Message><StackTrace> at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)&#xD; 
    at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)&#xD; 
    at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)&#xD; 
    at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)&#xD; 
    at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)&#xD; 
    at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.ServiceModel.CommunicationException</Type></ExceptionDetail></Detail></Fault> 

我想讓我的REST API JSON或XML請求取決於client.Do接受我需要在WebInvoke設置該屬性屬性還是在web.config中?

傳遞以下XML

<ContactType> 
    <ContactTypeID>3</ContactTypeID> 
    <Name>Assistant Sales Representative</Name> 
    <ModifiedDate>2002-06-01T00:00:00</ModifiedDate> 
</ContactType> 

誰能幫助我對此?

+0

您是否使用了命名空間來驗證?如果沒有,那麼也許只是刪除它 - 然後重試。 –

+0

@AnthonyHorne通過這項XML 3 助理銷售代表 2002-06-01T00:00:00

+0

最近我的服務寫入允許用戶發送txt,XMLElement(或Document)或實際的對象。界面只是單獨定義它們。我需要改變System.Linq的對system.xml(否則沒有工作),並在我的情況,要求我刪除NS(作爲賣方放入一個無效) –

回答

2

錯誤指出你有問題:

希望能夠找到節點類型「元素」名爲「InsertContact」和命名空間「http://tempuri.org/」。發現節點類型「元素」名爲「ContactType」和命名空間'

當你聲明的BodyStyleWebInvokeWrapped,這意味着你必須包裝與操作名稱的請求體(和適當的XML名稱空間)。

下面的代碼顯示的值傳遞給您的操作的一種方式。

public class StackOverflow_23526051 
{ 
    [ServiceContract] 
    public interface ITest 
    { 
     [WebInvoke(Method = "POST", UriTemplate = "/InsertContact", ResponseFormat = WebMessageFormat.Xml, 
      RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped)] 
     int InsertContact(ContactType objContactType); 
    } 
    public class Service : ITest 
    { 
     public int InsertContact(ContactType objContactType) 
     { 
      Console.WriteLine("objContactType: {0}", objContactType); 
      return 0; 
     } 
    } 

    [DataContract(Name = "ContactType", Namespace = "")] 
    public class ContactType 
    { 
     [DataMember(Order = 1)] 
     public int ContactTypeID { get; set; } 

     [DataMember(Order = 2)] 
     public string Name { get; set; } 

     [DataMember(Order = 3)] 
     public string ModifiedDate { get; set; } 

     public override string ToString() 
     { 
      return string.Format("ContactType[Id={0},Name={1},ModifiedDate={2}]", ContactTypeID, Name, ModifiedDate); 
     } 
    } 

    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     WebClient c = new WebClient(); 
     c.Headers.Add(HttpRequestHeader.ContentType, "text/xml"); 
     var xml = @"<t:objContactType> 
      <ContactTypeID>3</ContactTypeID> 
      <Name>Assistant Sales Representative</Name> 
      <ModifiedDate>2002-06-01T00:00:00</ModifiedDate> 
     </t:objContactType>"; 

     xml = "<t:InsertContact xmlns:t=\"http://tempuri.org/\">" + xml + "</t:InsertContact>"; 

     Console.WriteLine(c.UploadString(baseAddress + "/InsertContact", xml)); 
     Console.WriteLine(); 

     // To find out the request format: use the following 5 lines, look at Fiddler 
     var factory = new WebChannelFactory<ITest>(new Uri(baseAddress)); 
     var proxy = factory.CreateChannel(); 
     proxy.InsertContact(new ContactType { ContactTypeID = 123, ModifiedDate = "the date", Name = "John Doe" }); 
     ((IClientChannel)proxy).Close(); 
     factory.Close(); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
+0

carlosfigueira感謝您的幫助。關於Wrap我有幾個問題。 1.這是否會影響XML對象? 2.我必須將類ContactType轉換爲XML。 XML字符串會有所不同嗎? 3.我已經按照給定的方式實現,但不返回請求ContactTypeId。 –

+0

正文樣式影響需要作爲請求正文傳遞的XML正文的格式(模式)。只要XML遵循指定的模式,它就可以工作。嘗試使用** WCF客戶端**發送請求(正如我在代碼的最後一部分中所示),然後查看使用Fiddler等工具發送的內容。這將告訴你確切的請求需要發送的格式。 – carlosfigueira

+0

我發送xml字符串爲「 3 助理銷售代表 2002-06-01T00:00:00 「。在服務中,驗證if contactType對象是否爲空返回ContactTypeId。總是我得到contactId爲零而不是三。 –

相關問題