原創(chuàng)地址:http://www.survivalescaperooms.com/jfzhu/p/4060666.html
轉(zhuǎn)載請(qǐng)注明出處
前面的文章《WCF服務(wù)的異常消息》中介紹過(guò),如果WCF Service發(fā)生異常時(shí),Service會(huì)將異常序列化為SOAP Fault并發(fā)送給客戶端。
默認(rèn)情況下,出于安全原因,WCF Service中未處理的異常的詳細(xì)信息不會(huì)包括在發(fā)送給客戶的SOAP Fault里,你只能看到一個(gè)通用的SOAP Fault(“The server was unable to PRocess the request due to an internal error.”)。在調(diào)試程序的時(shí)候,如果想在SOAP Fault中包含異常的詳細(xì)信息,可以修改服務(wù)器的配置文件。
<behaviors> <serviceBehaviors> <behavior name="includeExceptionDetails"> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors></behaviors>
SOAP Fault是xml格式,與平臺(tái)無(wú)關(guān)。通常一個(gè)SOAP Fault包含以下節(jié)點(diǎn)
(1) faultcode
(2) faultstring
(3) detail
Detail節(jié)點(diǎn)可以用來(lái)包括自定義XML信息。
WCF Service在發(fā)生異常時(shí)應(yīng)拋出FaultException或FaultException<T>,而不應(yīng)該拋出.NET Exception,出于以下兩個(gè)原因:
(1)未處理的.NET Exception會(huì)使服務(wù)器與客戶端之間的channel變?yōu)镕ault狀態(tài),繼而導(dǎo)致client proxy無(wú)法使用。
(2).NET Exception只能被.NET平臺(tái)理解,而FaultException與平臺(tái)無(wú)關(guān)。如果想跨平臺(tái)使用,需要使用FaultException。
下面還是以中《WCF服務(wù)的異常消息》的例子來(lái)分別演示如何拋出與處理FaultException與強(qiáng)類型的FaultException<T>。
IDemoService.cs:
using System.ServiceModel;namespace WCFDemo { [ServiceContract(Name = "IDemoService")] public interface IDemoService { [OperationContract] int Divide(int numerator, int denominator); } }
DemoService.cs:
using System; using System.ServiceModel; using System.ServiceModel.Activation;namespace WCFDemo { [aspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class DemoService : IDemoService { public int Divide(int numerator, int denominator) { if (denominator == 0) { throw new FaultException("Denominator cannot be ZERO!", new FaultCode("DivideByZeroFault")); } return numerator / denominator; } } }
client:
private void buttonCalculate_Click(object sender, EventArgs e) { try { textBoxResult.Text = demoServiceClient.Divide(Convert.ToInt32(textBoxNumerator.Text), Convert.ToInt32(textBoxDenominator.Text)).ToString(); } catch (FaultException fault) { MessageBox.Show(fault.Code + " - " + fault.Message); } }
SOAP Fault XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <s:Fault> <faultcode>s:DivideByZeroFault</faultcode> <faultstring xml:lang="en-US">Denominator cannot be ZERO!</faultstring> </s:Fault> </s:Body> </s:Envelope>
(1)創(chuàng)建一個(gè)自定義SOAP Fault類
DivideByZeroFault.cs:
using System.Runtime.Serialization;namespace WCFDemo { [DataContract] public class DivideByZeroFault { [DataMember] public string Error { get; set; } [DataMember] public string Detail { get; set; } } }
(2) 在Service方法上使用FaultContractAttribute來(lái)指示哪個(gè)操作可以使用哪個(gè)Fault
IDemoService.cs:
using System.ServiceModel;namespace WCFDemo { [ServiceContract(Name = "IDemoService")] public interface IDemoService { [FaultContract(typeof(DivideByZeroFault))] [OperationContract] int Divide(int numerator, int denominator); } }
DemoService.cs:
using System; using System.ServiceModel; using System.ServiceModel.Activation;namespace WCFDemo { [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class DemoService : IDemoService { public int Divide(int numerator, int denominator) { try { return numerator / denominator; } catch (DivideByZeroException ex) { DivideByZeroFault fault = new DivideByZeroFault(); fault.Error = ex.Message; fault.Detail = "Denominator cannot be ZERO!"; throw new FaultException<DivideByZeroFault>(fault); } } } }
client:
private void buttonCalculate_Click(object sender, EventArgs e) { try { textBoxResult.Text = demoServiceClient.Divide(Convert.ToInt32(textBoxNumerator.Text), Convert.ToInt32(textBoxDenominator.Text)).ToString(); } catch (FaultException<DemoServiceReference.DivideByZeroFault> fault) { MessageBox.Show(fault.Detail.Error + " - " + fault.Detail.Detail); } }
返回的SOAP Fault XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <s:Fault> <faultcode>s:Client</faultcode> <faultstring xml:lang="en-US">The creator of this fault did not specify a Reason.</faultstring> <detail> <DivideByZeroFault xmlns="http://schemas.datacontract.org/2004/07/WCFDemo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Detail>Denominator cannot be ZERO!</Detail> <Error>Attempted to divide by zero.</Error> </DivideByZeroFault> </detail> </s:Fault> </s:Body> </s:Envelope>
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注