我有一个从外部供应商处接收JSON的WCF Rest Web服务,我正在尝试将通过CustomBehavior收到的确切JSON存档到磁盘。我将CustomBehavior放在一个单独的.DLL中,来自Web服务,给它一个强密钥,然后是GAC。
完整错误文字:
WebHost无法处理请求。发件人信息: System.ServiceModel.ServiceHostingEnvironment + HostingManager / 64525900 异常:System.ServiceModel.ServiceActivationException:服务 由于异常,无法激活'/SRRTREST/SQRTREST.svc' 在编译期间。异常消息是:无法添加行为 将'WcfAuditBehavior'扩展为名为的服务行为 'ServiceBehaviour'因为基础行为类型没有 实现IServiceBehavior接口。 (E:\ IISSite 文件夹\ ServiceEndPoints \ SQRTREST \ web.config第50行)。 ---> System.Configuration.ConfigurationErrorsException:无法添加 行为扩展'WcfAuditBehavior'到名为的服务行为 'ServiceBehaviour'因为基础行为类型没有 实现IServiceBehavior接口。 (E:\ IISSite 文件夹\ ServiceEndPoints \ SQRTREST \ web.config第50行
尽管出现上述错误,但请注意我是否实现了IServiceBehavior接口。我读了这个question,并且似乎不太了解如何将iServiceBehavior放在ErrorHandler上。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Dispatcher;
using System.IO;
using System.Xml;
//using System.Web.Services.Description;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Schema;
//using Newtonsoft.Json;
using System.Runtime.Serialization.Json;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.Collections.ObjectModel;
namespace SQRT_WCFAuditBehavior
{
public class WcfAuditBehaviorClass : BehaviorExtensionElement, IServiceBehavior
{
//* methods for BehaviorExtensionElement
protected override object CreateBehavior()
{
return new WcfAuditMessageInspector();
}
public override Type BehaviorType
{
get
{
return typeof(WcfAuditMessageInspector);
}
}
//* methods for IServiceBehavior
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
private IErrorHandler GetInstance()
{
return new MyErrorHandler();
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandlerInstance = GetInstance();
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(errorHandlerInstance);
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
public class WcfAuditMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();
this.LogMessage(buffer, "Request");
return null;
}
private void LogMessage(MessageBuffer buffer, string messageType)
{
var originalMessage = buffer.CreateMessage();
string messageContent;
using (StringWriter stringWriter = new StringWriter())
{
using (XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter))
{
originalMessage.WriteMessage(xmlTextWriter);
xmlTextWriter.Flush();
xmlTextWriter.Close();
}
messageContent = stringWriter.ToString();
}
// log messageContent to the database
try
{
// TODO copy logic from main routine to get path from web.config and Environment parm
string diskConsumePathName = @"\\myserver\Messages\System\Inbox\OrderIn\";
string formatDateTime = DateTime.Now.ToString("yyyy_MM_dd__hh_mm_sss"); // make sure both files below have exact same date/tiem stamp
string errorFilename = "System_" + formatDateTime + "_" + messageType + "_RawJSON.txt";
string diskErrorFullPathName = System.IO.Path.Combine(diskConsumePathName, errorFilename);
System.IO.File.WriteAllText(diskErrorFullPathName, messageContent);
}
catch (Exception ex)
{
// todo - write to event log?
}
return;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
var buffer = reply.CreateBufferedCopy(Int32.MaxValue);
reply = buffer.CreateMessage();
this.LogMessage(buffer, "Response");
return;
}
}
/*
public class WcfAuditBehaviorExtensionElement : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new WcfAuditBehavior();
}
public override Type BehaviorType
{
get { return typeof(WcfAuditBehavior); }
}
}
*/
public class MyFault
{
}
public class MyErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
{
var vfc = new MyFault();
var fe = new FaultException<MyFault>(vfc);
var fault = fe.CreateMessageFault();
msg = Message.CreateMessage(version, fault, "http://ns");
}
}
}
的Web.Config
<system.serviceModel>
<services>
<service name="SQRT_WCF.SQRTREST" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="longTimeoutBinding" contract="SQRT_WCF.ISQRTREST" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<extensions>
<behaviorExtensions>
<add name="WcfAuditBehavior" type="SQRT_WCFAuditBehavior.WcfAuditBehaviorClass, SQRT_WCFAuditBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=acd8bac56d3776b8" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<WcfAuditBehavior />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>