Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ukázka AdvancedDispatchByBody ukazuje, jak implementovat alternativní algoritmus pro přiřazování příchozích zpráv k operacím.
Ve výchozím nastavení vybere dispečer modelu služby odpovídající metodu zpracování příchozí zprávy na základě WS-Addressing hlavičky "Akce" nebo ekvivalentních informací v požadavku HTTP SOAP.
Některé zásobníky webových služeb SOAP 1.1, které nedodržují pokyny pro základní profil 1.1 WS-I, neodesílají zprávy založené na identifikátoru URI akce, ale spíše na základě kvalifikovaného názvu XML prvního prvku uvnitř těla SOAP. Podobně může klientská strana těchto zásobníků odesílat zprávy s prázdnou nebo libovolnou hlavičkou HTTP SoapAction, která byla povolena specifikací SOAP 1.1.
Pokud chcete změnit způsob odesílání zpráv do metod, ukázka implementuje IDispatchOperationSelector rozhraní rozšiřitelnosti na rozhraní DispatchByBodyElementOperationSelector. Tato třída vybere operace na základě prvního prvku textu zprávy.
Konstruktor třídy očekává slovník naplněný dvojicemi XmlQualifiedName a řetězci, přičemž kvalifikované názvy představují název prvního podřízeného elementu SOAP a řetězce představují odpovídající název operace. Je defaultOperationName název operace, která přijímá všechny zprávy, které nelze spárovat s tímto slovníkem:
class DispatchByBodyElementOperationSelector : IDispatchOperationSelector
{
Dictionary<XmlQualifiedName, string> dispatchDictionary;
string defaultOperationName;
public DispatchByBodyElementOperationSelector(Dictionary<XmlQualifiedName,string> dispatchDictionary, string defaultOperationName)
{
this.dispatchDictionary = dispatchDictionary;
this.defaultOperationName = defaultOperationName;
}
}
IDispatchOperationSelector implementace jsou velmi jednoduché k sestavení, protože existuje pouze jedna metoda v rozhraní: SelectOperation. Úkolem této metody je zkontrolovat příchozí zprávu a vrátit řetězec, který odpovídá názvu metody na kontraktu služby pro aktuální koncový bod.
V této ukázce získá selektor XmlDictionaryReader operace text příchozí zprávy pomocí GetReaderAtBodyContents. Tato metoda již umístí čtenáře na prvního podřízeného prvku těla zprávy, aby bylo dostačující získat název aktuálního prvku a URI oboru názvů a zkombinovat je do XmlQualifiedName, který je pak použit k vyhledání odpovídající operace ze slovníku, který je uložen v voliči operace.
public string SelectOperation(ref System.ServiceModel.Channels.Message message)
{
XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();
XmlQualifiedName lookupQName = new
XmlQualifiedName(bodyReader.LocalName, bodyReader.NamespaceURI);
message = CreateMessageCopy(message,bodyReader);
if (dispatchDictionary.ContainsKey(lookupQName))
{
return dispatchDictionary[lookupQName];
}
else
{
return defaultOperationName;
}
}
Přístup k textu zprávy s jinými metodami GetReaderAtBodyContents , které poskytují přístup k obsahu textu zprávy, způsobí, že zpráva bude označena jako "přečtená", což znamená, že zpráva je neplatná pro jakékoli další zpracování. Proto selektor operace vytvoří kopii příchozí zprávy s metodou zobrazenou v následujícím kódu. Vzhledem k tomu, že se pozice čtenáře během kontroly nezměnila, může na ni odkazovat nově vytvořená zpráva, na kterou se také zkopírují vlastnosti zprávy a záhlaví zprávy, což vede k přesnému klonování původní zprávy:
private Message CreateMessageCopy(Message message,
XmlDictionaryReader body)
{
Message copy = Message.CreateMessage(message.Version,message.Headers.Action,body);
copy.Headers.CopyHeaderFrom(message,0);
copy.Properties.CopyProperties(message.Properties);
return copy;
}
Přidání selektoru operace do služby
Selektory operací odeslání služby jsou rozšíření dispečeru WCF (Windows Communication Foundation). Pro výběr metod v kanálu zpětného volání duplexních kontraktů existují také selektory operací klienta, které fungují velmi podobně jako selektory operací odeslání popsané zde, ale které nejsou výslovně popsány v této ukázce.
Stejně jako většina rozšíření modelu služby se do dispečera přidávají selektory operací dispečinku pomocí chování objektů. Chování je objekt konfigurace, který buď přidá jedno nebo více rozšíření do modulu runtime dispatch (nebo do modulu runtime klienta), nebo jinak změní jeho nastavení.
Vzhledem k tomu, že selektory operací mají rozsah kontraktu, vhodné chování, které zde má být implementováno, je IContractBehavior. Vzhledem k tomu, že rozhraní je implementováno v Attribute odvozené třídě, jak je znázorněno v následujícím kódu, chování lze deklarativním způsobem přidat do libovolného kontraktu služby. ServiceHost Při každém otevření a sestavení modulu runtime dispečera se všechna chování nalezená buď jako atributy u kontraktů, operací a implementací služeb, nebo jako element v konfiguraci služby se automaticky přidají a následně se zobrazí výzva k přispívání rozšíření nebo úpravě výchozí konfigurace.
Pro stručnost ukazuje následující výňatek kódu pouze implementaci metody ApplyDispatchBehavior, což má vliv na změny konfigurace dispečera v této ukázce. Ostatní metody se nezobrazují, protože se vrátí volajícímu, aniž by prováděly žádnou práci.
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface)]
class DispatchByBodyElementBehaviorAttribute : Attribute, IContractBehavior
{
// public void AddBindingParameters(...)
// public void ApplyClientBehavior(...)
// public void Validate(...)
Nejprve implementace nastaví vyhledávací slovník pro selektor operace iterací prvků ApplyDispatchBehavior v OperationDescription koncovém bodu služby. Popis každé operace se pak zkontroluje pro přítomnost chování DispatchBodyElementAttribute, což je implementace IOperationBehavior, která je také definována v této ukázce. Ačkoli je tato třída také chování, je pasivní a aktivně neprovádí žádné změny konfigurace do běhového prostředí dispečinku. Všechny jeho metody se vrátí volajícímu, aniž by provedly jakoukoli akci. Chování operace existuje pouze tak, aby metadata požadovaná pro nový mechanismus odeslání, konkrétně kvalifikovaný název prvku těla, na jehož výskytu je vybrána operace, mohou být přidružena k příslušným operacím.
Pokud se takové chování najde, přidá se do slovníku pár hodnot vytvořený z kvalifikovaného názvu XML (QName vlastnosti) a název operace (Name vlastnost).
Po naplnění slovníku se vytvoří nový DispatchByBodyElementOperationSelector obsahující tyto informace a nastaví se jako výběr operace běhového prostředí dispečingu.
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
Dictionary<XmlQualifiedName,string> dispatchDictionary =
new Dictionary<XmlQualifiedName,string>();
foreach( OperationDescription operationDescription in
contractDescription.Operations )
{
DispatchBodyElementAttribute dispatchBodyElement =
operationDescription.Behaviors.Find<DispatchBodyElementAttribute>();
if ( dispatchBodyElement != null )
{
dispatchDictionary.Add(dispatchBodyElement.QName,
operationDescription.Name);
}
}
dispatchRuntime.OperationSelector =
new DispatchByBodyElementOperationSelector(
dispatchDictionary,
dispatchRuntime.UnhandledDispatchOperation.Name);
}
}
Implementace služby
Chování implementované v této ukázce přímo ovlivňuje, jak se interpretují a odesílají zprávy z drátu, což je funkce kontraktu služby. V důsledku toho by mělo být chování deklarováno na úrovni kontraktu služby v jakékoli implementaci služby, která se rozhodne ji použít.
Ukázková projektová služba aplikuje chování kontraktu DispatchByBodyElementBehaviorAttribute na kontrakt služby IDispatchedByBody a označí každou ze dvou operací OperationForBodyA() a OperationForBodyB() chováním operace DispatchBodyElementAttribute. Při otevření hostitele služby pro službu, která implementuje tuto smlouvu, metadata zpracovává konstruktér dispečera, jak bylo popsáno dříve.
Vzhledem k tomu, že selektor operace distribuuje výhradně na základě prvku těla zprávy a ignoruje "Action", je nutné, aby modul runtime nekontroloval hlavičku 'Action' u vrácených odpovědí přiřazením zástupného znaku "*" vlastnosti ReplyActionOperationContractAttribute. Kromě toho je nutné mít výchozí operaci, která má vlastnost "Action" nastavenou na zástupný znak "*". Výchozí operace přijímá všechny zprávy, které nelze odeslat a nemá DispatchBodyElementAttribute:
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples"),
DispatchByBodyElementBehavior]
public interface IDispatchedByBody
{
[OperationContract(ReplyAction="*"),
DispatchBodyElement("bodyA","http://tempuri.org")]
Message OperationForBodyA(Message msg);
[OperationContract(ReplyAction = "*"),
DispatchBodyElement("bodyB", "http://tempuri.org")]
Message OperationForBodyB(Message msg);
[OperationContract(Action="*", ReplyAction="*")]
Message DefaultOperation(Message msg);
}
Implementace ukázkové služby je jednoduchá. Každá metoda zabalí přijatou zprávu do zprávy odpovědi a vrátí ji zpět klientovi.
Spuštění a sestavení ukázky
Při spuštění ukázky se základní obsah odpovědí operace zobrazí v okně konzoly klienta podobně jako následující (formátovaný) výstup.
Klient odešle do služby tři zprávy, jejichž základní prvek obsahu je pojmenován bodyA, bodyBa bodyX, v uvedeném pořadí. Jak lze odvodit z předchozího popisu a zobrazeného kontraktu služby, příchozí zpráva s prvkem bodyA je zaslána do metody OperationForBodyA(). Vzhledem k tomu, že neexistuje žádný explicitní cíl odeslání zprávy s bodyX základním prvkem, zpráva je odeslána do objektu DefaultOperation(). Každá z operací služby zabalí přijatý text zprávy do prvku specifického pro metodu a vrátí ho, což se provádí ke korelaci vstupních a výstupních zpráv jasně pro tuto ukázku:
<?xml version="1.0" encoding="IBM437"?>
<replyBodyA xmlns="http://tempuri.org">
<q:bodyA xmlns:q="http://tempuri.org">test</q:bodyA>
</replyBodyA>
<?xml version="1.0" encoding="IBM437"?>
<replyBodyB xmlns="http://tempuri.org">
<q:bodyB xmlns:q="http://tempuri.org">test</q:bodyB>
</replyBodyB>
<?xml version="1.0" encoding="IBM437"?>
<replyDefault xmlns="http://tempuri.org">
<q:bodyX xmlns:q="http://tempuri.org">test</q:bodyX>
</replyDefault>
Jak nastavit, sestavit a spustit ukázku
Ujistěte se, že jste provedli instalační proceduru One-Time pro ukázky Windows Communication Foundation.
Pro sestavení řešení postupujte podle pokynů v Sestavení ukázek Windows Communication Foundation.
Pokud chcete spustit ukázku v konfiguraci pro jeden počítač nebo pro více počítačů, postupujte podle pokynů v Spuštění ukázek Windows Communication Foundation.