2010-01-12 85 views
10

我有兩個使用VS2008構建的.NET 3.5 WCF服務。如何防止在WCF客戶端中生成「指定」屬性?

我在Silverlight中有兩個WCF客戶端來使用這些服務。客戶端通過「添加服務參考」生成。我正在使用Silverlight 4.

其中一個代理是使用Specified屬性爲每個屬性生成的。這是我的服務方法「消息,在」類:

// properties are generated for each of these fields 
    private long customerProfileIdField;   
    private bool customerProfileIdFieldSpecified;   
    private bool testEnvField;   
    private bool testEnvFieldSpecified; 

現在我的其他服務(仍與Silverlight客戶端)不會產生Specified性能。

現在我不在乎'良好SOA的原則'。我只是想擺脫這些該死的財產,因爲在我所做的事情背景下,我絕對討厭他們。

這兩項服務之間必定存在一些差異 - 但我不想完全撕裂它們以找出差異。

A similar question之前有答案'you cant do it' - 這絕對不是真的,因爲我擁有它 - 我只是不知道我做了什麼不同。

編輯:我現在處於一種情況,我重新生成我的Silverlight 4代理到我的3.5 WCF服務(全部在同一本地主機上),有時會得到'指定'屬性,有時我不會。我不再認爲(正如我原先所懷疑的),這僅僅是由於某些端點配置或服務級別[屬性]。在消息本身中導致指定被生成(或不)的某些觸發器。可能涉及很多因素,或者可能很簡單。

+0

我居然有3個服務未創建指定的屬性。只有第四個! – 2010-01-12 02:03:30

+0

添加'[XMLSerializerFormat]'到您的服務的屬性:檢查到這個[answer](http://stackoverflow.com/questions/13396190/wcf-service-method-arguments-bool-specified) – 2013-01-21 21:52:41

回答

11

嘗試這種在財產被宣佈

[DataMember(IsRequired=true)] 
public bool testEnvField { get; set; } 

IsRequired=true將否定的testEnvFieldSpecified財產需要WCF服務

+0

這是怎麼回事?現在我創建指定屬性的服務剛剛停止創建它們。我剛剛添加了第二個OperationContract與一個非常類似的消息 - 所以我仍然堅持知道什麼是觸發這種全局行爲 – 2010-01-13 22:07:03

+0

我明白爲什麼2代理將生成SpecifiedField而不是,因爲.n3.5客戶端應用程序的唯一原因不需要「IsRequired」屬性,它們默認爲true,在.net2.0應用程序需要該屬性的情況下,它們以不同的方式讀取wsdl。兩個應用程序都是SL4嗎? – Neil 2010-01-14 07:27:06

+0

@同一個應用程序!我現在已經到了重新編譯我的3.5應用程序併爲我的SL4客戶端重新生成代理的時間點,我有時會得到'指定',有時不會。它變得非常令人沮喪!數據模型中的某些東西導致這種行爲 – 2010-01-15 04:45:45

0

OK我發現一兩件事,到目前爲止,這將導致Specified屬性生成:

  • 消息中存在XTypedElement

這些被Linq2XSD使用。我從Linq2XSD模型返回一個元素。

這引發Specified屬性,在我所有的類中產生的一切:

public XTypedElement Foo { get; set; } 

然而,這並沒有:

public XElement Foo { get; set; } 

仍然好奇,爲什麼這是,如果有任何其他事情觸發這一點。

+0

我很突然雖然我沒有使用XTypedElement或Linq2XSD,但我使用的是.NET 4.0 – speckledcarp 2014-08-28 17:06:24

2

這些額外的指定屬性是爲在合同或屬性標記中被指定爲可選的值類型生成的。

由於值類型默認情況下有一個值,因此爲這些屬性添加額外的Specified標誌,以允許客戶端(和服務器)區分明確未指定或明確指定的內容 - 可以將其設置爲默認值。沒有它,即使你沒有在客戶端代碼中設置它們(因爲映射到int),整數總是最終爲0(並且被序列化)。所以當你這樣做的時候,你還需要確保你設置Specified標誌爲true,否則這些屬性將不會被序列化。

因此,爲了防止爲值類型生成這些標誌,您必須更改合同,以使這些值類型屬性爲強制性的,而不是可選的。

希望是有道理的。

+1

正確的使p除了值類型之外,我並不總是讓它們生成。目前,我所有的(甚至是不可空的)布爾值和'ints'都不會生成這些屬性,但偶爾我會在合約中無意中改變某些東西,導致它們生成(並且我絕對不是無意中添加了[DataMember(IsRequired = true) ])。我真的很想知道如何永久禁用它們,以便它們像「普通」對象那樣工作。 – 2010-01-22 06:23:57

+0

不可爲空的那個應該沒問題,它只是*可選的*值類型,會有這個。另一種方式是 – 2010-01-22 08:27:47

+0

。它的非空字段需要指定的屬性,否則你不知道默認值(false或0)是用戶實際需要的。可選的只是不存在,但他們是可選的事實表明,這是可以的。在任何一種情況下,我的所有屬性最終都會獲得指定的屬性,這些屬性基本上完全將我所有的代碼都擰緊。必須有一套規則來確定何時產生以及何時不產生。它不像可空性不幸(或幸運地取決於你如何看待它) – 2010-01-22 17:24:29

0

注:我意識到這是一個老問題。我在這裏添加了這個,因爲這個問題在Google上是最重要的結果,並且對於任何人來說,它都是有用的信息。

嘗試加入這一行到你的經營合同聲明:
[XmlSerializerFormat]

它應該是這個樣子:

namespace WebServiceContract 
{ 
    [ServiceContract(Namespace = "http://namespace")] 
    [XmlSerializerFormat] //This line here will cause it to serialize the "optional" parameters correctly, and not generate the extra 
    interface InterfaceName 
    { 
     /*...Your web service stuff here...*/ 
    } 
} 
+1

請注意,這完全改變了用於Web服務的XML序列化引擎。 (從DataContractSerializer更改爲XmlSerializer)。不同的引擎使用一組不同的屬性來控制串行器輸出,具有不同的兼容性限制和不同的性能特徵。這不是一個小小的改變。 – Hydrargyrum 2016-07-29 09:00:47

相關問題