单声道WCF休息发布多个参数返回错误(500)

时间:2013-07-31 05:15:39

标签: wcf rest mono

最近在linux上构建一个RESTful WCF(CLI自托管),该程序在.NET下很好但在Mono下失败。 严格说来,使用GET和非参数/单参数POST的功能都不错,如果发布多个参数则返回错误500.

另一个问题是,如果将INVALID json传递给mono(说,标题中没有Content-Type,或者json格式无效),CLI将关闭而不是抛出异常并继续服务,这是非常致命的。

Unhandled Exception: System.Xml.XmlException: Invalid comma before an end of object (4,1)
  at System.Runtime.Serialization.Json.JsonReader.ReadContent (Boolean objectValue) [0x00000] in <filename unknown>:0 

请帮助,谢谢!

下面的第一个问题详情

单声道异常

Exception 'Element' is an invalid node type.  Line 1, position 53.   at System.Xml.XmlReader.ReadEndElement () [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.WebMessageFormatter.DeserializeObject (System.Runtime.Serialization.XmlObjectSerializer serializer, System.ServiceModel.Channels.Message message, System.ServiceModel.Description.MessageDescription md, Boolean isWrapped, WebContentFormat fmt) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.WebMessageFormatter+WebDispatchMessageFormatter.DeserializeRequest (System.ServiceModel.Channels.Message message, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Description.WebHttpBehavior+DispatchPairFormatter.DeserializeRequest (System.ServiceModel.Channels.Message message, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.OperationInvokerHandler.BuildInvokeParams (System.ServiceModel.Dispatcher.MessageProcessingContext mrc, System.Object[]& parameters) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.OperationInvokerHandler.DoProcessRequest (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.OperationInvokerHandler.ProcessRequest (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.BaseRequestProcessorHandler.ProcessRequestChain (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.BaseRequestProcessorHandler.ProcessRequestChain (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.HandlersChain.ProcessRequestChain (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] in <filename unknown>:0 
  at System.ServiceModel.Dispatcher.BaseRequestProcessor.ProcessRequest (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] in <filename unknown>:0 

的App.config

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>      
    <services>
      <service name="Contracts.MyService" behaviorConfiguration="MEXBehavior">
        <endpoint address="" binding="webHttpBinding" contract="Contracts.IMyService" behaviorConfiguration="MyRestBehavior" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.99:18688/MyService"/>
          </baseAddresses>
        </host>
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior name="MyRestBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="MEXBehavior">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata/>
        </behavior>
      </serviceBehaviors>
    </behaviors>    
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup></configuration>

接口

[ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "Ping")]
        bool Ping();

        [OperationContract]
        [WebInvoke(Method = "POST",RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.Wrapped, UriTemplate="echo")]
        string Echo(string name,string say);
    }

实施

 [ServiceBehavior]   
    public class MyService:IMyService
    {

        public bool Ping()
        {
            return true;
        }

        public string Echo(string name, string say)
        {
            return name + " says: " + say;
        }
    }

Fiddler Post

User-Agent: Fiddler
Host: 192.168.1.99:18688
Content-Length: 41
Content-Type: application/json

{
"name":"Alex",
"say":"Hello World"
}

Fiddler返回

HTTP/1.1 500 Internal Server Error
Content-Type: application/xml; charset=utf-8
Server: Mono-HTTPAPI/1.0
Date: Wed, 31 Jul 2013 04:31:20 GMT
Content-Length: 216
Connection: close

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none"><Code><Value>Receiver</Value></Code><Reason><Text xml:lang="en-US">'Element' is an invalid node type.  Line 1, position 53.</Text></Reason></Fault>

1 个答案:

答案 0 :(得分:1)

经过几天的搜索,似乎是单声道实现的错误。 因此,如果你进入这个,一个快速的技巧是将序列化的自定义类作为post参数,对于其他数据(例如int,string,bool),使用WebInvoke.UriTemplate发布它们。呀,和你使用WebGet一样。 通过这种方式,我们可以在发布多个参数时避免(-ish)这个错误。 在大多数情况下,这已经足够了。