WCF Web 服务在反序列化请求消息正文以进行操作时出错



这个问题来自另一个问题。代码基本相同,除了我删除的FirstMethodLastMethod方法,因为它们带来了问题(我在同一问题中对其进行了注释)。

即使这样,我也会在这里复制服务接口以供参考。如果你们中的一些人觉得有必要在这里复制完整的代码,我没有问题,我会在这里复制它。

服务协定接口

[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);
}

我想OperationContractAttributeAction参数定义了在服务中调用的方法(如果我错了,请再次纠正我),所以我更改了它,只是为了测试它,结果如下:

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  ;

所以,不,我错了:(

是的,这就是我能说的,我不知道为什么会发生这种情况。老实说,我认为"引用提供者"会生成对服务方法的调用,因为它在服务接口中,但是好吧,我想我不明白它......

反正我现在不知道该怎么办。任何帮助将不胜感激...再。


编辑:

好的,我无法为我在评论中写的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 自动生成充满错误的代码有什么意义。

即使有了这一切,我也没有放弃我指出的评论中的 xamarin 问题。

我放弃了这个。我刚刚制作了一个 ASP.Net 核心的Web API。

使用WCF网络服务,我在阅读,学习和与之抗争之间花费了一个多星期:永远不要按预期工作。

使用Web api,我花了半天时间阅读和学习(其中大部分是YouTube视觉工作室频道上的视频)。我一直讨厌 MSDN 文章解释事物的方式,但这个视频是一个真正的实时保护程序),一天和一个早上让它工作,包括Xamarin.Forms客户端,所有这些都以前对 HTTP 或 ASP.Net 知之甚少。

现在一切都很完美。感谢您尝试帮助:)

最新更新