Hataları Gönderme ve Alma
SOAP hataları, bir hizmetten istemciye ve çift yönlü durumda istemciden hizmete birlikte çalışabilir bir şekilde hata durumu bilgilerini aktarır. Genellikle bir hizmet özel hata içeriğini tanımlar ve bunları döndürebilecek işlemleri belirtir. (Daha fazla bilgi için bkz. Hataları Tanımlama ve Belirtme.) Bu konuda, ilgili hata koşulu oluştuğunda bir hizmet veya çift yönlü istemcinin bu hataları nasıl gönderebileceği ve bir istemci veya hizmet uygulamasının bu hataları nasıl işlediği açıklanır. Windows Communication Foundation (WCF) uygulamalarında hata işlemeye genel bakış için bkz . Sözleşmelerde ve Hizmetlerde Hataları Belirtme ve İşleme.
SOAP Hataları Gönderme
Bildirilen SOAP hataları, bir işlemin özel SOAP hata türünü belirten bir System.ServiceModel.FaultContractAttribute işlemi olan hatalardır. Bildirilmemiş SOAP hataları, bir işlem için sözleşmede belirtilmeyen hatalardır.
Bildirilen Hataları Gönderme
Bildirilen bir SOAP hatası göndermek için, SOAP hatasının uygun olduğu hata koşulunu algılayın ve type parametresinin bu işlem için içinde belirtilen FaultContractAttribute türde yeni bir nesne olduğu yeni bir nesne oluştururSystem.ServiceModel.FaultException<TDetail>. Aşağıdaki kod örneği, işleminin ayrıntı türüne sahip bir SOAP hatası döndürebileceğini belirtmek SampleMethod
için komutunun GreetingFault
kullanımını FaultContractAttribute gösterir.
[OperationContract]
[FaultContractAttribute(
typeof(GreetingFault),
Action="http://www.contoso.com/GreetingFault",
ProtectionLevel=ProtectionLevel.EncryptAndSign
)]
string SampleMethod(string msg);
<OperationContract, FaultContractAttribute(GetType(GreetingFault), Action:="http://www.contoso.com/GreetingFault", ProtectionLevel:=ProtectionLevel.EncryptAndSign)> _
Function SampleMethod(ByVal msg As String) As String
Hata bilgilerini istemciye iletmek GreetingFault
için, uygun hata koşulunu yakalayın ve aşağıdaki kod örneğinde olduğu gibi bağımsız değişken olarak yeni bir nesneyle yeni GreetingFault
bir tür GreetingFault
oluşturunSystem.ServiceModel.FaultException<TDetail>. İstemci bir WCF istemci uygulamasıysa, türünün türünde GreetingFault
olduğu System.ServiceModel.FaultException<TDetail> yönetilen bir özel durum olarak bu durumla karşılaşır.
throw new FaultException<GreetingFault>(new GreetingFault("A Greeting error occurred. You said: " + msg));
Throw New FaultException(Of GreetingFault)(New GreetingFault("A Greeting error occurred. You said: " & msg))
End If
Bildirilmemiş Hatalar Gönderme
Bildirilmemiş hatalar göndermek, WCF uygulamalarında sorunları hızla tanılamak ve hatalarını ayıklamak için çok yararlı olabilir, ancak hata ayıklama aracı olarak kullanışlılığı sınırlıdır. Daha genel olarak, hata ayıklarken özelliğini kullanmanız ServiceDebugBehavior.IncludeExceptionDetailInFaults önerilir. Bu değeri true olarak ayarladığınızda, istemciler türünde ExceptionDetailözel durumlar gibi FaultException<TDetail> hatalarla karşılaşır.
Önemli
Yönetilen özel durumlar iç uygulama bilgilerini açığa çıkarabileceğinden, veya ServiceBehaviorAttribute.IncludeExceptionDetailInFaultsServiceDebugBehavior.IncludeExceptionDetailInFaults ayarı true
, WCF istemcilerinin kişisel veya diğer hassas bilgiler de dahil olmak üzere iç hizmet işlemi özel durumları hakkında bilgi almasına izin verebilir.
Bu nedenle, veya ServiceDebugBehavior.IncludeExceptionDetailInFaults ayarının true
ServiceBehaviorAttribute.IncludeExceptionDetailInFaults yalnızca bir hizmet uygulamasında geçici olarak hata ayıklama yöntemi olarak kullanılması önerilir. Ayrıca, bu şekilde işlenmeyen yönetilen özel durumlar döndüren bir yöntemin WSDL'sinde türü ExceptionDetailiçin FaultException<TDetail> sözleşme bulunmaz. İstemciler, hata ayıklama bilgilerini düzgün bir şekilde almak için bilinmeyen bir SOAP hatası (WCF istemcilerine nesne olarak System.ServiceModel.FaultException döndürülür) olasılığını beklemelidir.
Bildirilmemiş bir SOAP hatası göndermek için bir System.ServiceModel.FaultException nesne (genel tür FaultException<TDetail>değil) oluşturun ve dizeyi oluşturucuya geçirin. Bu, WCF istemci uygulamalarına, yöntemini çağırarak FaultException<TDetail>.ToString dizenin kullanılabilir olduğu bir özel System.ServiceModel.FaultException durum olarak sunulur.
Not
Dize türünde bir SOAP hatası bildirir ve sonra bunu hizmetinize tür parametresinin dize değeri olduğu bir System.String dize değeri FaultException<TDetail>.Detail olarak FaultException<TDetail> atarsanız ve özelliğinden FaultException<TDetail>.ToStringkullanılamaz.
Hataları İşleme
WCF istemcilerinde, istemci uygulamalarının ilgilendiği iletişim sırasında oluşan SOAP hataları yönetilen özel durumlar olarak oluşturulur. Herhangi bir programın yürütülmesi sırasında ortaya çıkabilecek birçok özel durum olsa da, WCF istemci programlama modelini kullanan uygulamalar iletişim sonucunda aşağıdaki iki türün özel durumlarını işlemeyi bekleyebilir.
TimeoutException bir işlem belirtilen zaman aşımı süresini aştığında nesneler oluşturulur.
CommunicationException nesneleri, hizmette veya istemcide kurtarılabilir bir iletişim hatası koşulu olduğunda oluşturulur.
sınıfı, CommunicationException türetilmiş iki önemli türe FaultException ve genel FaultException<TDetail> türe sahiptir.
FaultException özel durumlar, bir dinleyici işlem sözleşmesinde beklenmeyen veya belirtilmeyen bir hata aldığında oluşur; genellikle uygulama hata ayıklanırken ve hizmet ServiceDebugBehavior.IncludeExceptionDetailInFaults özelliği olarak true
ayarlandığında bu durum oluşur.
FaultException<TDetail>özel durumlar, işlem sözleşmesinde belirtilen bir hata iki yönlü bir işleme (yani, değerine ayarlanmış özniteliği IsOneWay olan bir OperationContractAttribute yöntem) yanıt olarak alındığında istemcide false
oluşturulur.
Not
Bir WCF hizmetinin ServiceBehaviorAttribute.IncludeExceptionDetailInFaults veya ServiceDebugBehavior.IncludeExceptionDetailInFaults özelliği istemciye true
ayarlandığında, bunu türü ExceptionDetailbildirilmemiş FaultException<TDetail> olarak yaşar. İstemciler bu özel hatayı yakalayabilir veya için FaultExceptionbir catch bloğundaki hatayı işleyebilir.
Genellikle yalnızca FaultException<TDetail>, TimeoutExceptionve özel durumları istemcileri ve CommunicationException hizmetleri ilgi alanına alır.
Not
Tabii ki diğer özel durumlar oluşur. Beklenmeyen özel durumlar; gibi System.OutOfMemoryExceptionyıkıcı hataları içerir; genellikle uygulamalar bu tür yöntemleri yakalamamalıdır.
Hata Özel Durumlarını Doğru Sırada Yakalayın
' FaultException<TDetail> den türetildiğinden ve FaultException 'den CommunicationExceptionFaultExceptiontüretildiğinden, bu özel durumları uygun sırada yakalamak önemlidir. Örneğin, ilk yakaladığınız CommunicationExceptionbir try/catch bloğunuz varsa, tüm belirtilen ve belirtilmeyen SOAP hataları orada işlenir; özel FaultException<TDetail> özel durumu işlemek için sonraki yakalama blokları hiçbir zaman çağrılmaz.
Bir işlemin belirtilen sayıda hata döndürebileceğini unutmayın. Her hata benzersiz bir türdür ve ayrı ayrı işlenmelidir.
Kanalı Kapatırken Özel Durumları İşleme
Yukarıdaki tartışmaların çoğunun uygulama iletilerini işleme sırasında gönderilen hatalarla, yani istemci uygulaması WCF istemci nesnesindeki işlemleri çağırdığında açıkça istemci tarafından gönderilen iletilerle ilgili olması gerekir.
Nesnenin atılması yerel nesnelerde bile geri dönüşüm işlemi sırasında oluşan özel durumları tetikleyebilir veya maskeleyebilir. WCF istemci nesnelerini kullandığınızda benzer bir şey oluşabilir. İşlemleri çağırdığınızda, kurulan bir bağlantı üzerinden ileti gönderirsiniz. Tüm işlemler düzgün döndürülse bile bağlantı temiz bir şekilde kapatılamıyorsa veya zaten kapalıysa kanalın kapatılması özel durumlar oluşturabilir.
İstemci nesne kanalları genellikle aşağıdaki yollardan biriyle kapatılır:
WCF istemci nesnesi geri dönüştürüldiğinde.
İstemci uygulaması çağırdığında ClientBase<TChannel>.Close.
İstemci uygulaması çağırdığında ICommunicationObject.Close.
İstemci uygulaması bir oturum için sonlandırıcı işlem olan bir işlemi çağırdığında.
Her durumda, kanalı kapatmak, kanala uygulama düzeyinde karmaşık işlevleri desteklemek üzere ileti gönderebilecek temel kanalları kapatmaya başlamasını ister. Örneğin, bir sözleşme oturum gerektirdiğinde bağlama, bir oturum kurulana kadar hizmet kanalıyla ileti alışverişi yaparak oturum oluşturmaya çalışır. Kanal kapatıldığında, temel alınan oturum kanalı hizmete oturumun sonlandırıldığını bildirir. Bu durumda, kanal zaten durdurulduysa, kapatıldıysa veya başka bir şekilde kullanılamıyorsa (örneğin, bir ağ kablosu takılı olmadığında), istemci kanalı hizmet kanalına oturumun sonlandırıldığını ve bir özel durumun neden olabileceğini bildiremez.
Gerekirse Kanalı Durdur
Kanalın kapatılması özel durumlar da oluşturabileceğinden, hata özel durumlarını doğru sırada yakalamaya ek olarak, yakalama bloğunda çağrı yaparken kullanılan kanalın durdurulmasının da önemli olması önerilir.
Hata bir işleme özgü hata bilgilerini iletirse ve başkalarının bunu kullanabilmesi mümkün olmaya devam ederse, kanalı durdurmanız gerekmez (bu durumlar nadir olsa da). Diğer tüm durumlarda, kanalı durdurmanız önerilir. Bu noktaların tümünü gösteren bir örnek için bkz . Beklenen Özel Durumlar.
Aşağıdaki kod örneğinde, bildirilen bir hata ve bildirilmemiş hata dahil olmak üzere temel bir istemci uygulamasında SOAP hata özel durumlarının nasıl işlendiği gösterilmektedir.
Not
Bu örnek kod yapısını kullanmaz using
. Kapatma kanalları özel durumlar oluşturabileceğinden, uygulamaların önce bir WCF istemcisi oluşturması ve ardından aynı deneme bloğunda WCF istemcisini açması, kullanması ve kapatması önerilir. Ayrıntılar için bkz . WCF İstemcisine Genel Bakış ve WCF istemci kaynaklarını serbest bırakmak için Kapat ve Durdur'u kullanma.
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;
public class Client
{
public static void Main()
{
// Picks up configuration from the config file.
SampleServiceClient wcfClient = new SampleServiceClient();
try
{
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));
Console.WriteLine("Press ENTER to exit:");
Console.ReadLine();
// Done with service.
wcfClient.Close();
Console.WriteLine("Done!");
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException<GreetingFault> greetingFault)
{
Console.WriteLine(greetingFault.Detail.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException unknownFault)
{
Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
Console.ReadLine();
wcfClient.Abort();
}
}
}
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation
Public Class Client
Public Shared Sub Main()
' Picks up configuration from the config file.
Dim wcfClient As New SampleServiceClient()
Try
' Making calls.
Console.WriteLine("Enter the greeting to send: ")
Dim greeting As String = Console.ReadLine()
Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))
Console.WriteLine("Press ENTER to exit:")
Console.ReadLine()
' Done with service.
wcfClient.Close()
Console.WriteLine("Done!")
Catch timeProblem As TimeoutException
Console.WriteLine("The service operation timed out. " & timeProblem.Message)
Console.ReadLine()
wcfClient.Abort()
Catch greetingFault As FaultException(Of GreetingFault)
Console.WriteLine(greetingFault.Detail.Message)
Console.ReadLine()
wcfClient.Abort()
Catch unknownFault As FaultException
Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
Console.ReadLine()
wcfClient.Abort()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
Console.ReadLine()
wcfClient.Abort()
End Try
End Sub
End Class