我必须使用参数创建wcf服务。
我正在关注此http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/8f18aed8-8e34-48ea-b8be-6c29ac3b4f41
首先,我不知道如何在将托管它的ASP.NET MVC应用程序的Web.config中设置此自定义行为“MyServiceBehavior”。
据我所知,必须在wcf.config中的部分声明行为。 如何从服务程序集中将引用添加到我的行为类?
第二件事是,在下面的示例中,他们创建了本地主机(他们使用
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
在控制台应用程序中托管),但我如何添加标题
OperationContext.Current.OutgoingMessageHeaders.Add ...
用于在我的WPF客户端应用程序服务引用中使用时初始化构造函数,它已经创建了Web服务“client”类的实例
PBSDataCacheSyncContractClient client = new PBSDataCacheSyncContractClient();
是不是太迟了?或者当我有自己的自定义行为时,我可以这样做:
PBSDataCacheSyncContractClient client = new PBSDataCacheSyncContractClient(my var for service constructor) ?
此致 DanielSkowroński
编辑:31-05-2010
@manunt
我改进了第二个问题。
为了回答我的第一个问题,我设法创建了自定义扩展,但我无法注册。
我的情景:
在我的WCF库中,我有:
namespace PBS.SyncService
{
using System;
using System.Data;
using System.Collections.ObjectModel;
using System.ServiceModel;
using Microsoft.Synchronization.Data;
using System.ServiceModel.Activation;
using Microsoft.Synchronization.Data.Server;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Configuration;
[XmlSerializerFormat()]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public partial class PBSDataCacheSyncService : object, IPBSDataCacheSyncContract
{
private PBSDataCacheServerSyncProvider _serverSyncProvider;
public PBSDataCacheSyncService()
{
this._serverSyncProvider = new PBSDataCacheServerSyncProvider();
}
public PBSDataCacheSyncService(long doctorId)
{
this._serverSyncProvider = new PBSDataCacheServerSyncProvider();
this._serverSyncProvider.DoctorId = doctorId;
this._serverSyncProvider.InitializeCustomSyncProvider();
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public virtual SyncContext ApplyChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetadata, DataSet dataSet, Microsoft.Synchronization.Data.SyncSession syncSession)
{
return this._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public virtual SyncContext GetChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetadata, Microsoft.Synchronization.Data.SyncSession syncSession)
{
return this._serverSyncProvider.GetChanges(groupMetadata, syncSession);
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public virtual SyncSchema GetSchema(Collection<string> tableNames, Microsoft.Synchronization.Data.SyncSession syncSession)
{
return this._serverSyncProvider.GetSchema(tableNames, syncSession);
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public virtual SyncServerInfo GetServerInfo(Microsoft.Synchronization.Data.SyncSession syncSession)
{
return this._serverSyncProvider.GetServerInfo(syncSession);
}
public bool InitializeCustomSyncProvider(long doctorId)
{
this._serverSyncProvider.DoctorId = doctorId;
return this._serverSyncProvider.InitializeCustomSyncProvider();
}
}
[XmlSerializerFormat()]
[ServiceContractAttribute()]
public interface IPBSDataCacheSyncContract
{
[OperationContract()]
SyncContext ApplyChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetadata, DataSet dataSet, Microsoft.Synchronization.Data.SyncSession syncSession);
[OperationContract()]
SyncContext GetChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetadata, Microsoft.Synchronization.Data.SyncSession syncSession);
[OperationContract()]
SyncSchema GetSchema(Collection<string> tableNames, Microsoft.Synchronization.Data.SyncSession syncSession);
[OperationContract()]
SyncServerInfo GetServerInfo(Microsoft.Synchronization.Data.SyncSession syncSession);
[OperationContract()]
bool InitializeCustomSyncProvider(long doctorId);
[OperationContract()]
string[] GetSyncAdapterInfo();
}
public class PBSDataCacheSyncProvider : IInstanceProvider
{
public object GetInstance(InstanceContext instanceContext, Message message)
{
string doctorId = message.Headers.GetHeader<string>("DoctorId", "http://***/SyncService.svc");
if (doctorId != null)
{
return new PBSDataCacheSyncService(Convert.ToInt64(doctorId));
}
else
{
return new PBSDataCacheSyncService();
}
}
public object GetInstance(InstanceContext instanceContext)
{
return new PBSDataCacheSyncService();
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
public class PBSDataCacheSyncBehavior : BehaviorExtensionElement, IServiceBehavior
{
PBSDataCacheSyncProvider pbsProvider = new PBSDataCacheSyncProvider();
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { }
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider = this.pbsProvider;
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
public override Type BehaviorType
{
get { return typeof(PBSDataCacheSyncBehavior); }
}
protected override object CreateBehavior()
{
return new PBSDataCacheSyncBehavior();
}
}
}
我的WCF服务文件名称为:SyncService.svc,在我的makrup中我有:
<%@ ServiceHost Language="C#" Debug="true" Service="PBS.SyncService.PBSDataCacheSyncService" CodeBehind="PBS.SyncService.PBSDataCache.Server.SyncContract.cs" %>
我的web.config:
<service name="PBS.Web.SyncService" behaviorConfiguration="behPBSDataCacheSyncBehavior">
<host>
<baseAddresses>
<add baseAddress="http://***/SyncService.svc" />
</baseAddresses>
</host>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="" binding="basicHttpBinding" contract="PBS.SyncService.IPBSDataCacheSyncContract" />
</service>
<serviceBehaviors>
<behavior name="behPBSDataCacheSyncBehavior">
<PBSDataCacheSyncBehavior /> <!-- this element is being ignored -->
</behavior>
</serviceBehaviors>
<extensions>
<behaviorExtensions>
<add name="PBSDataCacheSyncBehavior" type="PBS.SyncService.PBSDataCacheSyncBehavior, PBS.SyncService,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
你能告诉我在这一点上我缺少什么吗? 为什么解析器会忽略我的自定义扩展声明?
我有以下错误:
配置错误 描述:处理为此请求提供服务所需的配置文件时发生错误。请查看下面的具体错误详细信息并相应地修改配置文件。
分析器错误消息:为system.serviceModel / behavior创建配置节处理程序时发生错误:无法将扩展元素“PBSDataCacheSyncBehavior”添加到此元素。验证扩展是否已在system.serviceModel / extensions / behaviorExtensions的扩展集合中注册。 参数名称:element
编辑:01-06-2010
通过在一行中键入所有声明来解析解析器的问题。
当我有服务参考时,我仍然不知道如何添加标题。
在我的WPF应用程序中,我只有客户端实例,它实现了由服务引用自动生成的IPBSDataCacheSyncContract。
当我初始化它时,它只有构造函数:
public PBSDataCacheSyncContractClient(){ }
public PBSDataCacheSyncContractClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public PBSDataCacheSyncContractClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public PBSDataCacheSyncContractClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public PBSDataCacheSyncContractClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
我可以在哪里添加标题?
“至于第二个问题 - 您应该在其中定义包含所需标题的邮件合约,并分别为每封邮件提供标题值。”你能更具体一点吗?
编辑:02-06-2010
我遇到了其他问题。
现在我的配置httpGetEnabled被忽略了......:
<serviceBehaviors>
<behavior name="behPBSDataCacheSyncBehavior">
<PBSDataCacheSyncBehavior />
<serviceMetadata httpGetEnabled="true" /><!-- ignored -->
<serviceDebug includeExceptionDetailInFaults="true" /><!-- ignored -->
</behavior>
</serviceBehaviors>
我该如何解决?
编辑:02-06-2010
好的,我已经找到了解决方法。它仍然很奇怪,但它确实有效!
我的问题在于web.config。并且没有任何名称行为输入条目被我的服务识别,而不是任何其他...所以我只是没有添加任何名称行为。
<serviceBehaviors>
<behavior name="">
<PBSDataCacheSyncBehavior />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="behPBSDataCacheSyncBehavior">
<PBSDataCacheSyncBehavior />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
我在代码中添加标题:
int doctorId = 2;
Sync.PBSDataCacheSyncContractClient client = new Sync.PBSDataCacheSyncContractClient();
new OperationContextScope (client.InnerChannel);
OperationContext.Current.OutgoingMessageHeaders.Add(
MessageHeader.CreateHeader("DoctorId", "http://***/SyncService.svc", doctorId));
我改变主题更有用。
HTH
此致 DanielSkowroński
答案 0 :(得分:2)
我知道没有找到行为的问题是什么,以及为什么你需要没有名字的行为的黑客攻击。
如果你在svc标记文件中查看这一行:
<%@ ServiceHost Language="C#" Debug="true" Service="PBS.SyncService.PBSDataCacheSyncService" CodeBehind="PBS.SyncService.PBSDataCache.Server.SyncContract.cs" %>
和你的web.Config中的这一行:
<service name="PBS.Web.SyncService" behaviorConfiguration="behPBSDataCacheSyncBehavior">
您会注意到服务标记中指定的名称与标记文件中Service属性中指定的Service类不同。
我认为它应该是这样的:
而不是
<service name="PBS.Web.SyncService" behaviorConfiguration="behPBSDataCacheSyncBehavior">
这个
<service name="PBS.SyncService.PBSDataCacheSyncService" behaviorConfiguration="behPBSDataCacheSyncBehavior">
我认为这两个值不一定不确定,但在我的情况下,这两个值是不同的,我不得不做空白服务名称hack。但是通过设置两个值相同,它起作用了。它找到了行为而不需要空白行为,我能够访问我的wsdl。
答案 1 :(得分:0)
回答您可以找到的第一个问题here。
关于你得到的错误 - 不要将扩展的定义分成两行,因为xml解析器无法处理。
如何在不指定消息合同的情况下定义自定义标头的示例:
var client = new Service1Client();
new OperationContextScope(client.InnerChannel);
MessageHeader<string> typedHeader = new MessageHeader<string>("headercontent");
MessageHeader header = typedHeader.GetUntypedHeader("myheader", "myns");
OperationContext.Current.OutgoingMessageHeaders.Add(header);