1

最近在linux(CLI自托管)上构建了一个RESTful WCF,该程序在.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 

应用程序配置

<?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;
        }
    }

提琴手邮报

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

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

提琴手归来

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>
4

1 回答 1

1

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

于 2013-08-02T12:48:19.900 回答