У меня есть необходимость создания службы wcf с параметром.WCF Constructor с параметром/пользовательским поведением, созданным в коде
Я после этого http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/8f18aed8-8e34-48ea-b8be-6c29ac3b4f41
Во-первых, это, что я не знаю, как я могу установить это пользовательское поведение «MyServiceBehavior» в моем Web.config в ASP.NET MVC приложение, которое будет принимать его.
Насколько я знаю, поведение должно быть объявлено в разделе в wcf.config. Как добавить ссылку на мой класс поведения из сборки сервиса?
второе дело, что в следующем примере они создали локальный хост (они используют
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
для размещения в консольное приложение), но как я могу добавить заголовки
OperationContext.Current.OutgoingMessageHeaders.Add ...
, используемые для инициализировать конструктор, когда я использую ссылку в моей службе WPF-клиента, и она уже создаст экземпляр веб-сервиса «клиент» класса
PBSDataCacheSyncContractClient client = new PBSDataCacheSyncContractClient();
is't это слишком поздно? Или когда у меня есть свое собственное поведение я могу сделать что-то вроде этого:
PBSDataCacheSyncContractClient client = new PBSDataCacheSyncContractClient(my var for service constructor) ?
С уважением, Daniel Skowronski
EDIT: 31.05.2010
@manunt
Я улучшил мой второй вопрос.
Для ответа на мой первый вопрос мне удалось создать пользовательский extenstion, но я не могу его зарегистрировать.
Мой сценарий:
- У меня есть определения для моего веб-службы в библиотеке WCF (интерфейс, контракт, реализация IInstanceProvider, BehaviorExtensionElement)
- я ссылаться на него в другой проект приложения ASP.NET
- внутри приложения ASP.NET У меня есть файл службы WCF, и он указывает на мой класс из библиотеки WCF
- вся моя конфигурация объявлена в web.config
В моей библиотеке 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>
Можете ли вы рассказать мне, что мне не хватает в этом пункте? Почему парсер игнорирует мою декларацию расширения?
Я следующее сообщение об ошибке:
Configuration Error Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: An error occurred creating the configuration section handler for system.serviceModel/behaviors: Extension element 'PBSDataCacheSyncBehavior' cannot be added to this element. Verify that the extension is registered in the extension collection at system.serviceModel/extensions/behaviorExtensions. Parameter name: element
EDIT: 01-06-2010
Проблема с анализатором решена, набрав все декларации в одной строке.
Я до сих пор не знаю, как добавить заголовок, когда у меня есть служебная ссылка.
В моем приложении WPF у меня есть только экземпляр экземпляра клиента, который реализует мой IPBSDataCacheSyncContract, автогенерируемый Service Reference.
И когда я инициализировать его имеет только конструкторы:
общественного 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) {
}
Где я могу добавить заголовки?
«Что касается второго вопроса - вы должны определить договор сообщения с необходимыми заголовками в нем и предоставить значения заголовка для каждого сообщения отдельно». Не могли бы Вы уточнить?
EDIT: 02.06.2010
я столкнулся с другой проблемой.
Когда я теперь моя конфигурация httpGetEnabled игнорируется ...:
<serviceBehaviors>
<behavior name="behPBSDataCacheSyncBehavior">
<PBSDataCacheSyncBehavior />
<serviceMetadata httpGetEnabled="true" /><!-- ignored -->
<serviceDebug includeExceptionDetailInFaults="true" /><!-- ignored -->
</behavior>
</serviceBehaviors>
Как я могу это исправить?
EDIT: 02.06.2010
OK Я фигурный обходной путь. Тем не менее это странно, но это работает!
Моя проблема была в 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
С уважением, Daniel Skowronski
Пожалуйста, ответьте на мои последние изменения. Спасибо, Daniel –
И снова, я буду признателен, если вы ответите. Спасибо, Daniel –
Черт ... еще одна проблема с httpGetEnabled ... –