如何将所有对象属性传递给WCF服务?

问题描述:

我必须承认我对WCF更复杂的能力的把握让我感到困惑,所以这可能是一个愚蠢的问题。我有一组类,像这样:如何将所有对象属性传递给WCF服务?

[DataContract] 
public class InvoiceItem 
{ 
    #region Properties 
    public bool Submittable { get; set; } 
    public string InvoiceID { get; set; } 
    public string VendorId { get; set; } 
    public string BatchId { get; set; } 
    /// <summary> 
    /// Marked as "Not Used", but explicitly set to 176. 
    /// </summary> 
    [ForFutureUse("Not used at this time", "176")] 
    public string LocationCode { get; set; } 
    public string VendorDocNumber { get; set; } 
    public string Description { get; set; } 
    public DateTime DocumentDate { get; set; } 
    public decimal PurchaseInvoiceAmount { get; set; } 
    public decimal TaxForm1099Amount { get; set; } 
    [ForFutureUse("Not used at this time")] 
    public string PayNumber { get; set; } 
    /// <summary> 
    /// Not marked as "Not Used", but not used. 
    /// </summary> 
    public string PaymentTerms { get; set; } 
    [ForFutureUse("Not used at this time")] 
    public decimal PurchaseAmount { get; set; } 
    [ForFutureUse("Not used at this time")] 
    public DateTime PayDate { get; set; } 
    [ForFutureUse("Not used at this time")] 
    public string DocumentID { get; set; } 
    public string DocumentType { get; set; } 
    public IList<InvoiceDetail> InvoiceDetails { get; set; } 
    /// <summary> 
    /// If the invoice is marked as not submittable, this should be set to explain why. 
    /// </summary> 
    public TroubleClasses TroubleClass { get; set; } 
    #endregion 

    #region Constructors 
    public InvoiceItem() { } 
    public InvoiceItem(XmlNode invoiceNode) 
    { 
     //collect the invoice data 
     this.InvoiceID = invoiceNode.SelectSingleNode("INVOICEHEADER/VOUCHERID").InnerText.Trim(); 
     this.VendorId = invoiceNode.SelectSingleNode("INVOICEHEADER/SUPPLIER.CODE").InnerText.Trim(); 
     this.BatchId = string.Format("D{0}", DateTime.UtcNow.ToShortDateString()); 
     this.LocationCode = "176"; 
     this.VendorDocNumber = invoiceNode.SelectSingleNode("INVOICEHEADER/SUPPLIERREF").InnerText.Trim(); 
     this.Description = invoiceNode.SelectSingleNode("INVOICEHEADER/ARRIVAL").InnerText.TrimEnd() + " " + invoiceNode.SelectSingleNode("ACCOUNTLINES/ACCOUNTLINE/DIMENSION.D2.CODE").InnerText.TrimEnd(); 
     this.DocumentDate = DateTime.ParseExact(
      invoiceNode.SelectSingleNode("INVOICEHEADER/INVOICEDATE").InnerText.Trim(), 
      "YYYYMMdd", CultureInfo.InvariantCulture); 
     this.PurchaseInvoiceAmount = Math.Abs(decimal.Parse(invoiceNode.SelectSingleNode("INVOICEHEADER/AMOUNT").InnerText.Trim())); 
     this.TaxForm1099Amount = decimal.Parse(invoiceNode.SelectSingleNode("INVOICEHEADER/SUPPLIER.CODE").InnerText.Trim()); 
     this.PayNumber = string.Empty; 
     this.PaymentTerms = string.Empty; 
     this.PurchaseAmount = 0.0M; 
     this.PayDate = DateTime.MinValue; 
     this.DocumentID = string.Empty; 
     this.DocumentType = invoiceNode.SelectSingleNode("INVOICEHEADER/CATEGORY").InnerText.Trim(); 

     //collect the detail data 
     this.InvoiceDetails = new List<InvoiceDetail>(); 
     var rowNumber = 0; 
     foreach (XmlNode detail in invoiceNode.SelectNodes("ACCOUNTLINES/ACCOUNTLINE")) 
     { 
      var newDetail = new InvoiceDetail(detail, this); 
      newDetail.RowNumber = ++rowNumber; 
      this.InvoiceDetails.Add(newDetail); 
     } 
     //all done! 
    } 
    #endregion 
} 

[DataContract] 
public class InvoiceDetail 
{ 
    #region Properties 
    public string Account { get; set; } 
    /// <summary> 
    /// This number must be unique and sequential in a given invoice. 
    /// </summary> 
    public int RowNumber { get; set; } 
    /// <summary> 
    /// Always set to "6". 
    /// </summary> 
    public int PayType { get; set; } 
    public decimal Debit { get; set; } 
    public decimal Credit { get; set; } 
    #endregion 

    #region Constructors 
    public InvoiceDetail() { } 
    public InvoiceDetail(XmlNode line, InvoiceItem invoiceItem) 
    { 
     var amount = Math.Abs(decimal.Parse(line.SelectSingleNode("AMOUNT").InnerText.Trim())); 
     this.Account = string.Format("{0}-{1}-{2}-{3}-{4}", 
      line.SelectSingleNode("ACCOUNTLINK.CODE").InnerText.TrimEnd(), 
      line.SelectSingleNode("DIMENSION.D1.CODE").InnerText.TrimEnd(), 
      line.SelectSingleNode("DIMENSION.D2.CODE").InnerText.TrimEnd(), 
      line.SelectSingleNode("DIMENSION.D3.CODE").InnerText.TrimEnd(), 
      line.SelectSingleNode("DIMENSION.D4.CODE").InnerText.TrimEnd()); 
     switch (invoiceItem.DocumentType) 
     { 
      case "2": 
       this.Credit = amount; 
       this.Debit = 0M; 
       break; 
      default: 
       this.Credit = 0M; 
       this.Debit = amount; 
       break; 
     } 
     this.PayType = 6; //no idea what this is. 
    } 
    #endregion 
} 

我想通过发送WCF的Web服务这InvoiceItem对象。我希望在客户端做这样的事情:

var invoice = new InvoiceItem(someXmlNode); 
using (var WebService = new WCFWebServices.WCFWebService()) 
{ 
    WebService.SubmitPayableTransaction(invoice); 
} 

同样我希望有在服务这样的事情:

public class WCFWebService:IWCFWebService 
{ 
    public void SubmitPayableTransaction(InvoiceItem invoice) 
    { 
     ... 
    } 
} 

这显然并非如此。即使我将InvoiceItem类移入其自己的库中,并且两个项目都引用它,客户端也有一个非常不同的外观对象作为其Web服务定义的一部分,并且也有一个不同的名称空间。

我该怎么做?

+2

我想你应该为每个你想要包含在你的数据合同(web服务使用的每个字段)中的字段添加[DataMember]属性。看看这个链接:http://msdn.microsoft.com/en-us/library/aa480190.aspx#introt_topic4。 – 2012-01-31 20:27:24

你需要的数据成员属性添加到所有你想传达给客户

但请记住你是不是坚持本身的对象,但定义数据传递对象的数据项的服务之间传递和客户端

+0

我不会认为像这样简单的事情会是问题,但它似乎已经解决了这个问题。 – 2012-01-31 20:46:16

+0

假设你使用的是.NET 3.5 SP1或更高版本,如果这些类是公共的,那么你需要一个公共的默认ctor,并且你省略了'[DataContract]'属性。如果您使用'[DataContract]',您还必须使用'[DataMember]' - 使用这些属性可以更好地控制序列化,并且始终应该是我的首选 – 2012-02-01 08:28:51