【发布时间】:2019-09-09 14:35:35
【问题描述】:
这个问题来自this other question。除了 FirstMethod 和 LastMethod 方法之外,代码基本相同,因为它们存在问题(我在同一个问题中对其进行了评论)。
即便如此,我还是将服务接口复制到此处以供参考。如果你们中的一些人觉得这里也有必要复制完整的代码,我没问题,我会在这里复制它。
服务合约接口
[ServiceContract]
public interface IMJRFFrasCdadesService
{
[OperationContract]
string Ping();
[OperationContract]
Task<string> GoogleLoginAsync(string email);
[OperationContract]
Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string email);
}
好的,现在当我连接到服务时,它会抛出这个:
Error:
Error in deserializing body of request message for operation 'GoogleLogin'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'GoogleLogin' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'GoogleLoginAsync' and namespace 'http://tempuri.org/' ;
Trace:
at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_remoting_wrapper(intptr,intptr)
at (wrapper remoting-invoke) ServiceReference2.IMJRFFrasCdadesService.GoogleLoginAsync(string)
at ServiceReference2.MJRFFrasCdadesServiceClient.GoogleLoginAsync (System.String email) [0x00006] in <e1f3df4dfbf340f09d2768d7fbc33427>:0
at MJRFFacturasComunidades.Model.WebService.WebServiceClass+<LogEmail>d__6.MoveNext () [0x00023] in <e1f3df4dfbf340f09d2768d7fbc33427>:0 ;
如果我错了,请纠正我,但我知道客户端正在尝试调用一个名为 GoogleLogin 的方法,但该方法名为 GoogleLoginAsync(如您在代码中所见),所以这是,它没有找到方法。很明显。
但是,VStudio 自动生成带有WCF Web Service Reference Provider 的客户端代码...我该怎么办?没看懂。
无论如何,我已经尝试查看客户端生成的代码(我将重复一遍,因为我是 WCF 的新手)并看到了这个:
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "1.0.0.1")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.IMJRFFrasCdadesService")]
public interface IMJRFFrasCdadesService
{
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMJRFFrasCdadesService/Ping", ReplyAction="http://tempuri.org/IMJRFFrasCdadesService/PingResponse")]
System.Threading.Tasks.Task<string> PingAsync();
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMJRFFrasCdadesService/GoogleLogin", ReplyAction="http://tempuri.org/IMJRFFrasCdadesService/GoogleLoginResponse")]
System.Threading.Tasks.Task<string> GoogleLoginAsync(string email);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMJRFFrasCdadesService/UploadFile", ReplyAction="http://tempuri.org/IMJRFFrasCdadesService/UploadFileResponse")]
System.Threading.Tasks.Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string email);
}
我想OperationContractAttribute 的Action 参数定义了将在服务中调用的方法(再次,如果我错了,请纠正我),所以我改变了它,只是为了测试它,结果如下:
Error:
The message with Action 'http://tempuri.org/IMJRFFrasCdadesService/GoogleLoginAsync' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None). ;
Trace:
at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_remoting_wrapper(intptr,intptr)
at (wrapper remoting-invoke) ServiceReference1.IMJRFFrasCdadesService.GoogleLoginAsync(string)
at ServiceReference1.MJRFFrasCdadesServiceClient.GoogleLoginAsync (System.String email) [0x00006] in <7e18c3beb694450a8a87883f2950def0>:0
at MJRFFacturasComunidades.Model.WebService.WebServiceClass+<LogEmail>d__6.MoveNext () [0x00023] in <7e18c3beb694450a8a87883f2950def0>:0 ;
所以,不,我错了:(
是的,我只能这么说,我不知道为什么会这样。老实说,我认为“引用提供者”会生成对服务方法的调用,因为它在服务接口中,但是,我想我没有理解它......
不管怎样,我现在不知道该怎么办。 任何帮助将不胜感激......再次。
编辑:
好的,我无法为我在 cmets 上写的 Xamarin.Forms 问题工作,所以按照 @mahlatse 的建议,这是现在 Web 服务中的服务合同:
[ServiceContract]
public interface IMJRFFrasCdadesService
{
[OperationContract]
string Ping();
[OperationContract]
Task<string> GoogleLoginAsync(string email);
[OperationContract]
Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string email);
}
并且在Xamarin.Forms客户端中自动生成的界面,由我修改:
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "1.0.0.1")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName= "ServiceReference1.IMJRFFrasCdadesService")]
public interface IMJRFFrasCdadesService
{
[System.ServiceModel.OperationContractAttribute(Action=@"http://tempuri.org/IMJRFFrasCdadesService/Ping", ReplyAction=@"http://tempuri.org/IMJRFFrasCdadesService/PingResponse")]
System.Threading.Tasks.Task<string> PingAsync();
[System.ServiceModel.OperationContractAttribute(Action=@"http://tempuri.org/IMJRFFrasCdadesService/GoogleLoginAsync", ReplyAction= @"http://tempuri.org/IMJRFFrasCdadesService/GoogleLoginAsyncResponse")]
System.Threading.Tasks.Task<string> GoogleLoginAsync(string email);
[System.ServiceModel.OperationContractAttribute(Action=@"http://tempuri.org/IMJRFFrasCdadesService/UploadFileAsync", ReplyAction= @"http://tempuri.org/IMJRFFrasCdadesService/UploadFileAsyncResponse")]
System.Threading.Tasks.Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string email);
}
如您所见,我也修改了ReplyAction 参数,我添加了@ 只是为了避免“转义字符问题”。但完全没有变化。
阅读@tgolisch 评论后,我修改了web.config 文件,发现绑定为https。我修改了客户端,并在创建服务客户端类时将绑定设置为http,所以我更改了:
private IMJRFFrasCdadesService _Service;
public WebServiceClass(string url)
{
_ServiceUrl = url;
_Service = new MJRFFrasCdadesServiceClient(
new BasicHttpsBinding(),
new EndpointAddress(_ServiceUrl));
}
我还从自动生成的服务客户端类中更改了此方法,因为当参数引用https 时,它正在创建http 绑定(在第二个if 它使用System.ServiceModel.BasicHttpBinding 而不是https 版本):
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_IMJRFFrasCdadesService))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
return result;
}
if ((endpointConfiguration == EndpointConfiguration.BasicHttpsBinding_IMJRFFrasCdadesService))
{
/*HERE -->*/ System.ServiceModel.BasicHttpsBinding result = new System.ServiceModel.BasicHttpsBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Mode = System.ServiceModel.BasicHttpsSecurityMode.Transport;
return result;
}
throw new System.InvalidOperationException(string.Format("No se pudo encontrar un punto de conexión con el nombre \"{0}\".", endpointConfiguration));
}
在这一切之后,我仍然得到相同的结果。
老实说,我开始问自己让 VStudio 自动生成充满错误的代码有什么意义。
尽管如此,我还没有放弃我指出 cmets 的 xamarin 问题。
【问题讨论】:
-
检查发送方和接收方的合同,接口是否相同
-
查看您的 .config 文件(尤其是您的 WCF)。还要检查 WCF 中的 WSDL 以确认这是正确的(分/治)。顺便说一句,您的第二个错误表明您正在接近修复。所以你实际上并没有错。继续。你几乎明白了。
-
你们认为我面临这个问题吗:github.com/dotnet/wcf/issues/2463?
-
问题已编辑
-
我完全迷失了这个。我已经尝试了几件事,将端点添加到 web.config 文件,在没有引用提供程序的情况下手动编写客户端代码,使服务器端方法同步方法(令人难以置信的是,现在没有一个名为
GoogleLoginAsync的方法,但是错误一直在说完全相同的事情)。我不知道还能做什么。完全迷路了。
标签: c# web-services wcf xamarin.forms azure-app-service-envrmnt