Мне нужно создать службу wcf с параметром.
Я слежу за этим 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();
не слишком ли поздно?Или когда у меня есть свое собственное поведение, я могу сделать что-то вроде этого:
PBSDataCacheSyncContractClient client = new PBSDataCacheSyncContractClient(my var for service constructor) ?
С уважением, Даниэль Сковронски
РЕДАКТИРОВАТЬ: 31-05-2010
@ manunt
Я улучшил свой второй вопрос.
Для ответа на мой первый вопрос мне удалось создать собственное расширение, но я не могу его зарегистрировать.
Мой сценарий:
- У меня есть определения для моего веб-сервиса в библиотеке 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 и в моем макрокоманде:
<%@ 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 / поведение: произошла ошибка: элемент расширения 'PBSDataCacheSyncBehavior' не может быть добавлен к этому элементу.Убедитесь, что расширение зарегистрировано в коллекции расширений в system.serviceModel / extensions / поведениеExtensions.Имя параметра: элемент
РЕДАКТИРОВАТЬ: 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
С уважением, Даниэль Сковронски