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