ASP.NET Core(C#)调用第三方API遇CommunicationObjectFaultedException问题求助
我在ASP.NET Core(C#)应用中调用第三方API,连接阶段就出问题了,API提供商对C#不熟悉,没法提供有效帮助。为了测试,我把代码直接写在HomeController的Index方法里:
public IActionResult Index() { // 创建绑定实例 BasicHttpBinding binding = new BasicHttpBinding(); binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; binding.MaxReceivedMessageSize = int.MaxValue; binding.Security.Mode = (BasicHttpSecurityMode)SecurityMode.Transport; try { using (var client = new V3PortClient(binding, new EndpointAddress(new Uri("https://platform.com/Webservices/V3?wsdl")))) { // 发送消息到平台 var result = client.sendMsgAsync(accesscode, userIdentifier, title, body, senderIdentifier, 0, 0, false); ViewBag.Message = result.Result; } } catch (Exception ex) { // 处理异常 ViewBag.Message = ex; } return View(); }
这段代码在using (var client = new V3PortClient…)的闭合括号处抛出以下错误:
System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state. at System.ServiceModel.Channels.CommunicationObject.System.ServiceModel.IAsyncCommunicationObject.CloseAsync(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.CloseAsyncInternal(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout) at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
我的引用类中有如下代码(类的一部分):
public V3PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress)
我确定密码(accesscode)不需要配置在绑定中,因为每次调用任务时都会通过sendMsgAsync(string accesscode,…)参数传入。
[System.ServiceModel.OperationContractAttribute(Action="https://platform.com/Webservices/V3#sendMsg", ReplyAction="*")] [System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)] [return: System.ServiceModel.MessageParameterAttribute(Name="return")] System.Threading.Tasks.Task<object> sendMsgAsync(string accesscode, string userIdentifier, string title, string body, string senderIdentifier, object attachments, int coaccount, bool copyToLVS);
我对这个领域完全陌生,希望能得到帮助。
解决思路和方案
1. 修复异步调用的阻塞问题
直接用.Result同步阻塞异步方法sendMsgAsync,极易引发死锁和通道状态异常,改用await异步调用是核心修复点:
修改Index方法为异步:
public async Task<IActionResult> Index() { BasicHttpBinding binding = new BasicHttpBinding(); binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; binding.MaxReceivedMessageSize = int.MaxValue; binding.Security.Mode = BasicHttpSecurityMode.Transport; // 直接用枚举值,避免强制转换的潜在错误 try { // 初始化客户端时无需在URL后加?wsdl,客户端会自动获取元数据 using (var client = new V3PortClient(binding, new EndpointAddress("https://platform.com/Webservices/V3"))) { // attachments参数类型为object,传0可能类型不匹配,改为传null(若API允许空值) var result = await client.sendMsgAsync(accesscode, userIdentifier, title, body, senderIdentifier, null, 0, false); ViewBag.Message = result; } } catch (Exception ex) { ViewBag.Message = ex.ToString(); // 输出完整异常栈,方便排查具体错误 } return View(); }
2. 处理故障状态的通道
当客户端通道进入Faulted状态时,using语句自动调用Close()会触发异常,可在catch块中主动判断并终止通道:
catch (Exception ex) { if (client.State == CommunicationState.Faulted) { client.Abort(); } else { client.Close(); } ViewBag.Message = ex.ToString(); }
3. 开启WCF日志排查深层问题
如果以上修复仍未解决,开启WCF日志可以获取详细的请求/响应数据,定位身份验证、序列化或协议层面的问题:
在appsettings.json添加配置:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "System.ServiceModel": "Information", "System.ServiceModel.MessageLogging": "Information" } }, "System.ServiceModel.MessageLogging": { "LogEntireMessage": true, "LogMessagesAtServiceLevel": true, "LogMessagesAtTransportLevel": true } }
在Program.cs中配置日志过滤:
builder.Logging.AddFilter("System.ServiceModel", LogLevel.Information); builder.Logging.AddFilter("System.ServiceModel.MessageLogging", LogLevel.Information);
内容的提问来源于stack exchange,提问作者ElectricalStorm

