65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF DataContract 与 FaultException 详细信息

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2009年6月24日

CPOL

2分钟阅读

viewsIcon

52598

downloadIcon

883

WCF DataContract

引言

这是一个基于 Microsoft Enterprise Library 4.1 和 FaultException 处理的简单 WCF 服务和客户端应用程序。此应用程序基于 Inventory.Core 对象,用于说明如何在 WCF 服务上使用 DataContract

我有两个方法,一个方法从 Products 表中返回所有产品作为数组输出,另一个方法在 WCF 客户端发送 Product ID 作为输入参数时返回 ProductName

背景

作为原生 ASP.NET 程序员,我们在开发 WCF Web 服务时必须考虑 SOA 方面。最初,我并不关心当 PHP、JSP 和 Perl 等非 Microsoft 技术实现客户端应用程序时,我的 WCF 服务将如何运行。

在设计 WCF 或 Web 服务 SOA 的架构时,一个好的做法是,开发人员必须充分注意到其他编程语言的数据类型及其类型和签名。

当我还是 WCF 服务的新手时,我犯了两个错误。我一直认为我的 WCF 服务只会由基于 ASP.NET 的应用程序使用。

简单来说,就是“广泛认可的数据类型”,这意味着通用数据类型,它为我的 WCF 和未知的客户端实现代码之间的顺畅协作铺平了道路。

第二个是异常处理部分。我将所有 WCF 相关的异常放在我的 WCF 服务应用程序中,例如 CommunicationExceptionTimeoutException 等。即使我在我的消费者应用程序上测试这个 WCF 服务时,尽管它是 WCF 的 ASP.NET 客户端实现,但异常也没有被彻底捕获。

我不知道当基于 JSP 或 PHP 的客户端应用程序在我的 WCF 服务运行时会抛出什么样的异常。

这两个因素在我的开发过程中一直困扰着我。我通过制作其他技术可以理解的自定义错误消息来纠正这些问题。

Using the Code

[FaultContractAttribute(typeof(FaultContractExceptionTest))]
// This will converts the system or application level exception into SOAP header format.
string[] AvailableProducts();   	//Instead of returning the CLR data type 
				//DataSet return the array type
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using System.Collections;
ArrayList al = new ArrayList();
string s = "";
Database db = DatabaseFactory.CreateDatabase();
DbCommand cmd = db.GetSqlStringCommand("SELECT * from Products");
DataSet ds = db.ExecuteDataSet(cmd);
foreach (DataRow dRow in ds.Tables[0].Rows)
{
 al.Add(dRow);
 }
foreach (Object row in al)
{
 s = s + ((DataRow)row)["ProductName"].ToString() + ",";

}
string rawString = s.TrimEnd(',').ToString();
string[] result = rawString.Split(',');
return result;

在我可用的 Products 实现中,我强制将 DataSet 转换为 ArrayList 类型,然后是 DataRowstring 数组。这是因为我的目的是让基于 JSP 和 PHP 的消费者应用程序应该了解将从 WCF 服务接收什么类型的数据。

第二个值得注意的代码片段如下

catch (FaultException<FaultContractExceptionTest> fx)
{
fx.Detail.ErrorMessage = "Internal Server Error " + fx.Reason.ToString();
throw new FaultException<FaultContractExceptionTest>
	(new FaultContractExceptionTest(fx.Detail.ErrorMessage));
}

对于 FaultException 类,使用此实现

[DataContractAttribute]
public class FaultContractExceptionTest
{
    private string Msg;
     public FaultContractExceptionTest(string msg)
    {
        this.Msg = msg;            
    }
    
    [DataMember]
    public string ErrorMessage
    {
        get { return this.Msg; }
        set { this.Msg = value; }
    }

对于 SOAP 标头消息级别的异常处理,我使用了 FaultContractExceptionTest 类作为 DataContract,正如你可以在我的 WSDL 代码段中看到的那样

<wsdl:operation name="AvailableProducts">
<soap12:operation soapAction=http://tempuri.org/IService/AvailableProducts 
	style="document" /> 
- <wsdl:input>
<wsp:PolicyReference URI="#WSHttpBinding_IService_AvailableProducts_Input_policy" /> 
<soap12:body use="literal" /> 
</wsdl:input>
- <wsdl:output>
<wsp:PolicyReference URI="#WSHttpBinding_IService_AvailableProducts_output_policy" /> 
<soap12:body use="literal" /> 
</wsdl:output>
- <wsdl:fault name="FaultContractExceptionTestFault">
<wsp:PolicyReference 
 URI="#WSHttpBinding_IService_AvailableProducts_FaultContractExceptionTestFault_Fault" /> 
<soap12:fault name="FaultContractExceptionTestFault" use="literal" /> 
</wsdl:fault>
</wsdl:operation> 

历史

  • 2009 年 6 月 24 日:初始发布
© . All rights reserved.