WCF 实现 IErrorHandler 遇到注册扩展“enforceGreetingFaults”无法加载

问题描述 投票:0回答:1

我有一个旧的 WCF 项目,它接收 xml 类型的调用后。
最近,呼叫者称他们在拨打我们的端点时遇到 500。
但当我们查看日志时,并没有与调用失败相关的记录。

经过进一步调查,我们认为调用从未执行/正确输入方法,因此没有日志。
该调用没有命中该方法,因为帖子中的 xml 内容被截断,因此无法反序列化参数。
例如

<!-- missing </PartNumberUpdate> -->
<PartNumberUpdate>
  <PartNumbers>
    <PartNumber>
      <LicenseNo>001</LicenseNo>
      <Description>xxx</Description>
    </PartNumber>
    <PartNumber>
      <LicenseNo>001</LicenseNo>
      <Description>yyy</Description>
    </PartNumber>
  <PartNumbers> 

// the xml in post can't convert to param input cause it's incomplete
public void ProcessPartNumberUpdate(PartNumberUpdate input)
{
    ...
}

但是调用者声称他们发布的 XML 是完整的,并且由于调用从未命中该方法,因此我们没有任何日志来判断这是否属实。

因此,我试图找到一种方法来记录错误,即使该方法未执行。 我在网上搜索了一下,似乎IErrorHandler最符合我的要求。

但是,根据说明将代码和xml设置移植到我的项目后。 我遇到了

类型'Microsoft.WCF.Documentation.EnforceGreetingFaultBehavior, HostApplication,版本=0.0.0.0,文化=中性, PublicKeyToken=null' 为扩展 'enforceGreetingFaults' 注册 无法加载。

而 IIS 则表达 Visual Studio 中的 Web 服务。

错误列表中也有警告

元素“behavior”具有无效的子元素 '强制问候错误'。预期可能的元素列表: 'serviceAuthenticationManager,明确,serviceAuthorization, 服务凭证、服务元数据、服务安全审计、 服务节流、数据契约序列化器、服务调试、 serviceTimeouts、删除、useRequestHeadersForMetadataAddress、 persistenceProvider、workflowRuntime、etwTracking、bufferedReceive、 工作流空闲、工作流UnhandledException、sendMessageChannelCache、 sqlWorkflowInstanceStore、workflowInstanceManagement、 服务发现、路由'。

不知道是不是因为我的WCF已经很老了?但我已经将目标框架更新到4.7.2.

我使用指令中的所有 C# 代码创建了一个 ServiceHostGeneralErrorHandler 类。
并将xml设置移植到我的as

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true"/>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="MyPorjectMetadata_RESTService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General" logWarningsWhenNoCategoriesMatch="false">
    <listeners>
      <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" source="MyPorjectMetadata" formatter="Text Formatter" log="MyPorjectMetadata" machineName="." traceOutputOptions="None"/>
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="Message: {message}{newline}" name="Text Formatter"/>
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Event Log Listener"/>
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="Off" name="All Events"/>
      <notProcessed switchValue="Off" name="Unprocessed Category"/>
      <errors switchValue="Off" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Event Log Listener"/>
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <system.net>
    <mailSettings>
      <smtp>
        <network host="smtp-americas.my-company.com" port="25"/>
      </smtp>
    </mailSettings>
  </system.net>
  <connectionStrings>
    <add name="MyPorjectMetadata_RESTService.Properties.Settings.strConnectionString" connectionString="server=.;database=my-companyDistributionKeyStore;Trusted_Connection=Yes; application name=MyPorjectMetadata_RESTService"/>
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.7.2"/>
    <authentication mode="Windows"/>
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="largeMessageBinding" maxReceivedMessageSize="4194304"/>
      </webHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="MyPorjectMetadata_RESTService.Service1Behavior" name="MyPorjectMetadata_RESTService.Service1">
        <endpoint address="" binding="webHttpBinding" contract="MyPorjectMetadata_RESTService.IService1" behaviorConfiguration="web" bindingConfiguration="largeMessageBinding">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="MyPorjectMetadata_RESTService.Service1Behavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <enforceGreetingFaults/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add
          name="enforceGreetingFaults"
          type="Microsoft.WCF.Documentation.EnforceGreetingFaultBehavior, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
        />
      </behaviorExtensions>
    </extensions>
  </system.serviceModel>
  <applicationSettings>
    <MyPorjectMetadata_RESTService.Properties.Settings>
    <!-- some properites -->
    </MyPorjectMetadata_RESTService.Properties.Settings>
  </applicationSettings>
</configuration>

我想也许是因为我没有dll?所以我试图从 Nuget 中找到

Microsoft.WCF.Documentation.EnforceGreetingFaultBehavior
但找不到类似的东西。

总结一下我的问题,

  1. 如何解决此扩展程序无法加载的问题?
  2. 或者有其他方法来捕获发布错误吗?
wcf web-config
1个回答
0
投票

我的资深同事指导我使用。

关键是,

Microsoft.WCF.Documentation.EnforceGreetingFaultBehavior
是我们应该自己写的。 所以你需要在你的项目下创建类(
IServiceBehavior
)。

public class EnforceGreetingFaultBehavior : BehaviorExtensionElement, IServiceBehavior
{
    public override Type BehaviorType => typeof(EnforceGreetingFaultBehavior);

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        IErrorHandler errorHandler = new ServiceHostGeneralErrorHandler();
        foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
        {
            cd.ErrorHandlers.Add(errorHandler);
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        return;
    }

    protected override object CreateBehavior()
    {
        return new EnforceGreetingFaultBehavior();
    }
}

然后是

IErrorHandler

的课程
public class ServiceHostGeneralErrorHandler : IErrorHandler
{
    #region IErrorHandler Members
    public bool HandleError(Exception error)
    {
        Console.WriteLine("HandleError called.");
        // Returning true indicates you performed your behavior.
        return true;
    }

    // This is a trivial implementation that converts Exception to FaultException<GreetingFault>.
    public void ProvideFault(
      Exception error,
      MessageVersion ver,
      ref Message msg
    )
    {
        Console.WriteLine("ProvideFault called. Converting Exception to GreetingFault....");
        FaultException<string> fe
          = new FaultException<string>(error.Message);
        MessageFault fault = fe.CreateMessageFault();
        msg = Message.CreateMessage(
          ver,
          fault,
          "http://microsoft.wcf.documentation/ISampleService/SampleMethodGreetingFaultFault"
        );
    }
    #endregion
}

最后,在 web.config 中

behaviorExtensions
,您需要正确的程序集限定名称

<extensions>
  <behaviorExtensions>
    <add
      name="enforceGreetingFaults"
      type="MyPorjectMetadata_RESTService.ServiceBehaviors.EnforceGreetingFaultBehavior, MyPorjectMetadata_RESTService, Version=2.0.0.5, Culture=neutral, PublicKeyToken=null"
    />
  </behaviorExtensions>
</extensions>

您可以获得合格的名字

string qn = typeof(EnforceGreetingFaultBehavior).Assembly.FullName.ToString();

完成上述

<enforceGreetingFaults/>
中的
serviceBehaviors
后应该可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.