簡體   English   中英

ASP.NET MVC - 模型的WCF類

[英]ASP.NET MVC - WCF Classes for Models

ASP.NET | MVC 4 | C#| WCF

我使用WCF Web服務作為從表示層(MVC)到數據層(實體)的中介。 為了簡化將數據模型數據從MVC移動到Web服務,我想我會在WCF中使用代理類,因此會有一個集中式類。 不幸的是,這導致模型中屬性上的MVC裝飾丟失。 有沒有一種好方法可以創建一個集中式類用於MVC視圖的模型,還可以作為WCF服務的傳輸方法?

作為一種選擇,我想到了自動化,但我認為這需要兩個相同的類。 一個在MVC端,一個在WCF端。 如果某個類中的屬性發生變化,那么仍需要我對雙方進行更改。

任何其他建議將不勝感激。 謝謝!

編輯::示例

這是包含記錄表的頁面的模型

public class ReconcileModel
{
    #region PROPERTIES

    public List<ReconcileItem> ReconcileItems { get; set;}

    #endregion

    #region CONSTRUCTORS

    public ReconcileModel()
    {
        ReconcileItems = new List<ReconcileItem>();
    }

    #endregion
}

這是一個表示該表中每條記錄的類。

public class ReconcileItem
{
    #region PROPERTIES

    public int ID { get; set; }
    public string Description { get; set; }
    public string LastLocation { get; set; }
    public string LastRead { get; set; }
    public string IntendenLocation { get; set; }
    public string PickId { get; set; }
    public string OEM { get; set; }
    public string LotNumber { get; set; }
    public string SerialNumber { get; set; }
    public DateTime ExpirationDate { get; set; }
    public string ReconcileReason { get; set; }
    public string RemoveReason { get; set; }


    #endregion

    #region CONSTRUCTORS

    public ReconcileItem()
    {
    }

    #endregion
}

上面類的WCF合同表示將是

[DataContract]
public class ReconcileItem
{
    [DataMemeber]
    public int ID { get; set; }
    [DataMember]
    public string Description { get; set; }
    [DataMember]
    public string LastLocation { get; set; }
    [DataMember]
    public string LastRead { get; set; }
    [DataMember]
    public string IntendenLocation { get; set; }
    [DataMemeber]
    public string PickId { get; set; }
    [DataMember]
    public string OEM { get; set; }
    [DataMember]
    public string LotNumber { get; set; }
    [DataMember]
    public string SerialNumber { get; set; }
    [DataMember]
    public DateTime ExpirationDate { get; set; }
    [DataMember]
    public string ReconcileReason { get; set; }
    [DataMember]
    public string RemoveReason { get; set; }
}

如果我想更新此記錄,則將該類發送到WCF服務,映射到適當的實體框架類,並保存到數據庫。 為了簡化傳輸,我想我會把這個類放在WCF項目中並在MVC項目中引用它。 然后我可以在WCF和MVC之間傳回這個類。 此外,如果我在WCF中更新了類,那么它將反映在MVC中。 這就是集中化的意思。

您可以使用您的實體,但創建視圖模型並將數據注釋放在這些上。 有很多關於將驗證放在項目中的討論。 一般來說,它幾乎總是給定的,它需要在UI上發生,然后通常在其他地方發生。 我會避免試圖集中它,因為這永遠不會成功(一種尺寸很少適合所有)。

在您的解決方案楔入WCF層,除非有很好的理由為它的主題,我會不惜一切代價避免這樣做。 我已經多次看到這種事情出了問題。 它帶來了很多負面影響。 在我處理的兩個商業案例中,你最終會得到太多的端點和太多的煩惱。 它削弱了能夠將業務邏輯放在您的實體中並在線上使用這些方法,使維護成為一場噩夢而沒有足夠的硬件和精心設計,如果托管在單個服務器上,您可能最終不得不使用命名管道獲得您所需的速度,這將抵消您使用WCF獲得的任何分布式優勢。

您最好將繁重的處理任務外部化為可以在其他地方托管的組件,並通過更小,更簡潔的界面進行通信。 實際上,除了圖像處理,數學和科學應用之外,不會出現繁重的數據處理。

我們以您在當前雇主的帖子中描述的方式使用WCF。 我們最終讓WCF和MVC的DTO類與MVC應用程序中的ViewModels進行通信,以便在UI中進行模型綁定和驗證。

我同意,擁有幾乎相互重復的類並在它們之間進行映射是一種痛苦,在某種程度上似乎是錯誤的。 從我過去所讀到的,我們所做的以及你可能被迫做的事情,是最好的做法。

Adrian在上面提到的關於WCF只進行大量處理的建議也是有道理的。 在開始我目前的工作之前,我做到了這一點。 大多數業務邏輯都放在由MVC應用程序直接引用的業務層程序集中。 對於少數可能長時間運行的進程,我創建了單獨托管的MVC應用程序與之通信的WCF服務。

最后,您可以使用Web API與WCF嗎? Web API是輕量級的,並且利用HTTP來消除WCF綁定等所帶來的所有開銷。此外,使用Web API,您可以使用MVC應用程序使用的相同類,甚至可以在Web API中使用模型驗證。 這是我一直在努力並變得越來越普遍的事情。

希望有所幫助!

就像Adrian一樣,我懷疑你是否真的需要在你的數據庫和MVC服務之間使用WCF服務。 對於與數據庫進行通信的客戶端應用程序(Win Forms,WPF),這種情況更為可能。 我目前正在開發一個Win Forms項目,我們使用WCF作為中間層,我們執行以下操作:

  • 我們有一個在客戶端和WCF / BL之間共享的程序集(稱為“契約”)。
  • 此“合同”程序集包含由WCF通過線路發送的所有DTO。
  • 我們通過在“服務引用設置”中設置“在指定引用程序集中重用類型”,將WCF客戶端代理配置為使用合同程序集(而不是讓WCF重新生成所有DTO)。
  • 我們使用DataAnnotations屬性(和其他元數據)來裝飾這些DTO。
  • 我們不會使用WCF屬性裝飾這些DTO。 WCF不需要它們來序列化DTO。 它們是可選的 如果可以,請將它們留下。 它只是使你的代碼混亂。
  • 由於客戶端使用相同的程序集,因此我們可以在客戶端上使用DataAnnotations。
  • 我們也在服務器上驗證。
  • 我們使用AutoMapper來完成從實體到DTO的大部分樣板映射(但從來沒有相反)。
  • 坦率地說,你甚至不讓WCF序列化我們的DTO,但是使用JSON.NET和WCF只發送和接收(純文本)JSON,因為JSON.NET在序列化和反序列化數據方面簡單得多了結構。 例如,我們使用JSON.NET(de)序列化不可變對象結構。 嘗試使用WCF。 那將是悲慘的失敗。

最重要的是我們做:

  • 使用View Model類添加客戶端功能。
  • 在合同程序集中添加自定義DataAnnotation驗證,以允許在客戶端和服務器上運行驗證。
  • 添加IValidator<T>抽象(某種)以允許服務器或客戶端特定的驗證(通過在企業層或客戶端應用程序中放置實現)。
  • 使用異常將服務器特定的驗證錯誤傳回客戶端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM