C# 反序列化WCF服务时更改区域性
我正在使用C#从Java Web服务读取数据 我在VS2008中创建了一个对服务器的服务引用,可以调用其中的一个方法。但是,返回的一些字段是Decimal类型的,当自动生成的WCF代理返回XML时,它会失败,并出现一个CommunicationException,说明:C# 反序列化WCF服务时更改区域性,c#,wcf,cultureinfo,C#,Wcf,Cultureinfo,我正在使用C#从Java Web服务读取数据 我在VS2008中创建了一个对服务器的服务引用,可以调用其中的一个方法。但是,返回的一些字段是Decimal类型的,当自动生成的WCF代理返回XML时,它会失败,并出现一个CommunicationException,说明: "Error in deserializing body of reply message for operation 'getOpenReceivables'." "There is an error in XML docum
"Error in deserializing body of reply message for operation 'getOpenReceivables'."
"There is an error in XML document (1, 941)."
"Input string was not in a correct format."
[编辑]以下是完整的堆栈跟踪:
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
at System.Decimal.Parse(String s, NumberStyles style, IFormatProvider provider)
at System.Xml.XmlConvert.ToDecimal(String s)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExecutePortType.Read2_XXNG_OPEN_RECEIVABLES(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExecutePortType.Read3_Item()
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer.Deserialize(XmlSerializationReader reader)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
我可以看到返回的十进制数是用标点符号作为十进制数格式化的。出于测试目的,我尝试了Decimal.Parse(“123.99”)并得到了相同的错误。通过设置
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
在我编写Decimal.Parse(“123.99”)的测试代码之前,我已经开始工作了
但是,在调用WCFService方法之前设置CurrentCulture没有任何区别
有什么方法可以让我的WCFService代理对象理解返回的XML位于另一个cultureformat中吗?您是否尝试过使用自定义实现?WCF充满了扩展性点,因此通常很难知道选择哪一个,但反序列化似乎是这项工作的合适工具 看一看与您尝试执行的操作类似的操作:使用WCF客户端调用非WCF web服务,并对响应进行专门处理,以说明服务器上的非WCF行为 以下是该博客的代码摘录:
public object DeserializeReply(Message message, object[] parameters)
{
object helperInstance = Activator.CreateInstance(_return);
//we have special condition where service sets Http response code to 403 that signals that an error has occured
KeyValuePair<string,object> serviceErrorProperty = message.Properties.FirstOrDefault(p => p.Key == ResponseErrorKey);
if (serviceErrorProperty.Key != null)
{
//we have an error message
IResponseErrorProvider responseErrorProvider = helperInstance as IResponseErrorProvider;
if (responseErrorProvider != null)
{
//unpack the error payload from message and assign to the object
ResponseError payload = message.GetBody<ResponseError>();
responseErrorProvider.ServiceError = payload;
//return fixed null type with error attached to it
return helperInstance;
}
}
//another message we might get is <nil-classes type="array"/> for empty arrays.
XmlDictionaryReader xdr = message.GetReaderAtBodyContents();
xdr.MoveToContent();
if (xdr.Name == NullMessage)
{
return helperInstance; //standin for the null value
}
return _formatter.DeserializeReply(message, parameters);
}
public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
{
return _formatter.SerializeRequest(messageVersion, parameters);
}
public对象反序列化reply(消息消息,对象[]参数)
{
object helperInstance=Activator.CreateInstance(_return);
//我们有一个特殊的条件,服务将Http响应代码设置为403,表示发生了错误
KeyValuePair serviceErrorProperty=message.Properties.FirstOrDefault(p=>p.Key==ResponseErrorKey);
if(serviceErrorProperty.Key!=null)
{
//我们收到一条错误消息
IResponseErrorProvider responseErrorProvider=helperInstance as IResponseErrorProvider;
if(responseErrorProvider!=null)
{
//从消息中解压缩错误负载并分配给对象
ResponseError有效负载=message.GetBody();
responseErrorProvider.ServiceError=有效负载;
//返回固定的空类型,并附加错误
返回帮助者立场;
}
}
//我们可能得到的另一条消息是空数组。
XmlDictionaryReader xdr=message.GetReaderAtBodyContents();
xdr.MoveToContent();
if(xdr.Name==NullMessage)
{
return helperInstance;//表示空值
}
返回_formatter.DeserializeReply(消息、参数);
}
公共消息序列化请求(MessageVersion MessageVersion,对象[]参数)
{
返回格式化程序.SerializeRequest(messageVersion,参数);
}
如果文化真的是问题所在,我会非常惊讶。XML规范说小数使用点作为分隔符,(反)序列化程序知道这一点。你能追踪信息,看看941号位置有什么吗?(顺便说一句:除了WCF跟踪之外,我喜欢这些东西)当谈到小数时,可能不同的精度可能是一个问题:如果.net decimal可以处理三分之二的小数,Java服务可能会在后面的7之前放置更多的666666?还有第二个选项:小数实际上不是小数(再次强调:跟踪消息将非常有启发性)。我发现,对于amazon服务有一点遗憾,这可能会将单位转换为十进制值(顺便说一下:WTF!)。但是,对于如何在使用IClientMessageInspector接口将原始消息传递给反序列化之前与原始消息进行交互,有一个很好的描述。如果这种奇怪的情况是您的问题,您可以强制服务提供商遵守其自己的合同,也可以采取这样的措施(如果提供程序不在您的控制范围内,并说“这是设计的”)。您可以将区域性初始值设定项附加到行为,然后将其添加到端点。这将在反序列化响应的线程上设置区域性,因此应正确反序列化该字段
有关这方面的代码示例,请查看以下链接:
实际上,我通过编辑制作Web服务的人给我的.xsd文件解决了这个问题。(有一个.wsdl文件和两个.xsd文件)。你得到了要点,因为这似乎是一个很好的解决方案和很好的链接,但我实际上没有尝试过。你至少应该粘贴博客文章中最相关的代码——链接是deadsorry@CamiloTerevinto——这是我写这篇文章的时候差不多7年前的事了,远远早于“必须将代码与链接一起粘贴”的时间最佳实践被正式化了。我在互联网档案中找到了博客,并用档案链接和代码示例摘录更新了我的答案。