.NET 6调用SOAP API报错:指定方法不支持,无可用方法
调用PowerSchool SOAP API时遇到System.NotSupportedException错误
问题背景
我尝试调用PowerSchool的SOAP API,已通过WSDL文件用svcutil工具生成了名为PublicPortalServiceJSONPortTypeClient的代理类。按照微软官方文档步骤调用,但始终无法成功。当前环境是.NET 6 CLI控制台应用。
已尝试的操作:
- 测试了代理类中所有方法(包括
cc.Open()) - 换用WSDL中列出的所有SOAP端点作为请求地址
报错信息
System.NotSupportedException: Specified method is not supported. at System.ServiceModel.MessageSecurityOverHttp.CreateSecurityBindingElement(Boolean isSecureTransportMode, Boolean isReliableSession, MessageSecurityVersion version) at System.ServiceModel.WSHttpSecurity.CreateMessageSecurity(Boolean isReliableSessionEnabled, MessageSecurityVersion version) at System.ServiceModel.WSHttpBinding.CreateMessageSecurity() at System.ServiceModel.WSHttpBindingBase.CreateBindingElements() at System.ServiceModel.WSHttpBinding.CreateBindingElements() at System.ServiceModel.Channels.Binding.EnsureInvariants(String contractName) at System.ServiceModel.Description.ServiceEndpoint.EnsureInvariants() at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEn at System.ServiceModel.ChannelFactory.CreateFactory() at System.ServiceModel.ChannelFactory.OnOpening() at System.ServiceModel.Channels.CommunicationObject.System.ServiceModel.IAsyncCommunicationObject.O at System.ServiceModel.Channels.CommunicationObject.OpenAsyncInternal(TimeSpan timeout) at System.Runtime.TaskHelpers.WaitForCompletion(Task task) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ClientBase`1.Open() at Program.<Main>$(String[] args) in /Users/cd25037/dev/git/cs/PowerschoolAPI/Program.cs:line 30
代码示例
using ServiceReference; using System.ServiceModel; // Create the binding. WSHttpBinding myBinding = new WSHttpBinding(); myBinding.Security.Mode = SecurityMode.TransportWithMessageCredential; myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest; // Create the endpoint address. Note that the machine name // must match the subject or DNS field of the X.509 certificate // used to authenticate the service. EndpointAddress ea = new EndpointAddress("https://fccps.powerschool.com:8443/pearson-rest/services/PublicPortalServiceJSON.PublicPortalServiceJSONHttpsSoap11Endpoint/"); // Create the client. The code for the calculator // client is not shown here. See the sample applications // for examples of the calculator code. PublicPortalServiceJSONPortTypeClient cc = new PublicPortalServiceJSONPortTypeClient(myBinding, ea); // The client must provide a user name and password. The code // to return the user name and password is not shown here. Use // a database to store the user name and passwords, or use the // ASP.NET Membership provider database. cc.ClientCredentials.UserName.UserName = "pearson"; cc.ClientCredentials.UserName.Password = "m0bApP5"; try { // Begin using the client. // cc.Abort(); // await cc.OpenAsync(); // await cc.loginAsync("","",0); cc.Open(); var login = await cc.loginToPublicPortalAsync("<redacted>", "<redacted>"); // cc.Close(); } catch(Exception e){ Console.WriteLine(e); }
WSDL说明
WSDL对应PowerSchool PublicPortalServiceJSON接口,包含SOAP 1.1 HTTPS端点。
解决方案
1. 替换WSHttpBinding为BasicHttpsBinding
报错核心原因是:.NET 6+的WSHttpBinding不支持TransportWithMessageCredential + Digest传输凭据的组合,这是WCF在.NET Core/.NET 5+中的兼容性限制。而PowerSchool的SOAP 1.1端点更适合用BasicHttpsBinding,它专门针对HTTPS上的SOAP 1.1场景设计。
修改绑定代码:
// 替换WSHttpBinding为BasicHttpsBinding BasicHttpsBinding myBinding = new BasicHttpsBinding(); myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest; // BasicHttpsBinding默认就是Transport模式,无需额外设置Security.Mode
2. 统一异步调用逻辑
原代码混合了同步的cc.Open()和异步的loginToPublicPortalAsync(),容易引发死锁。建议全用异步API:
try { await cc.OpenAsync(); var login = await cc.loginToPublicPortalAsync("<redacted>", "<redacted>"); // 处理返回结果 await cc.CloseAsync(); } catch (Exception e) { Console.WriteLine(e); cc.Abort(); }
3. 匹配SOAP版本兼容性
PowerSchool的PublicPortalServiceJSONHttpsSoap11Endpoint是SOAP 1.1端点,而WSHttpBinding默认对应SOAP 1.2,这也是不兼容的原因之一。BasicHttpsBinding可以完美匹配SOAP 1.1的HTTPS端点。
4. 调整凭据配置(可选)
如果上述修改后仍报错,可尝试调整安全模式,明确指定消息凭据类型:
myBinding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential; myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
内容的提问来源于stack exchange,提问作者King Cameron
相关产品推荐
相关产品推荐

