2017-07-26 114 views
0

我使用的是內置DataContractJsonSerializer來準備用於傳輸數據。C#JSON序列必填項

我從一個業務對象使用以下代碼序列化:

private string SerialiseRequest(RegistrationRequest request) 
     { 
      string strRequest = string.Empty; 

      try 
      { 
       DataContractJsonSerializer serializer = new DataContractJsonSerializer(request.GetType()); 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        serializer.WriteObject(ms, request); 
        strRequest = Encoding.Default.GetString(ms.ToArray()); 
       } 
      } 
      catch 
      { 
       return string.Empty; 
      } 

      return strRequest; 
     } 

當數據被序列化,它似乎被忽略的設置,最重要的設置是IsRequired,因爲我不希望如果不包含數據,則傳輸一個字段。這裏是我有業務對象定義:

[DataContract] 
    public sealed class RegistrationRequest 
    { 
     [DataMember(Order = 0, IsRequired = true)] 
     public Registration_Header registration_header { get; set; } 

     [DataMember(Order = 1, IsRequired = true)] 
     public Customer_Details primary_user { get; set; } 

     [DataMember(Order = 2, IsRequired = true)] 
     public StaffDetails partner_attributes { get; set; } 

     [DataMember(Order = 3, IsRequired = true)] 
     public CustomerAddress primary_residential_address { get; set; }  

     public class Registration_Header 
     { 
      [DataMember(Order = 0, IsRequired = true)] 
      public string services_required { get; set; } 

      [DataMember(Order = 1, IsRequired = true)] 
      public string account_type { get; set; } 

      [DataMember(Order = 2, IsRequired = true)] 
      public string affiliate_number { get; set; } 
     } 

     public class Customer_Details 
     { 
      [DataMember(IsRequired = true)] 
      public string title { get; set; } 

      [DataMember(IsRequired = true)] 
      public string first_name { get; set; } 

      [DataMember(IsRequired = false)] 
      public string middle_name { get; set; } 

      [DataMember(IsRequired = true)] 
      public string last_name { get; set; } 

      [DataMember(IsRequired = true)] 
      public string email { get; set; } 

      [DataMember(IsRequired = true)] 
      public string nationality { get; set; } 

      [DataMember(IsRequired = true)] 
      public string dob { get; set; } 

      [DataMember(IsRequired = true)] 
      public string occupation { get; set; } 

      [DataMember(IsRequired = true)] 
      public string residence_country { get; set; } 

      [DataMember(IsRequired = true)] 
      public string mobile_number { get; set; } 

      [DataMember(IsRequired = false)] 
      public string landline_number { get; set; } 

      [DataMember(IsRequired = true)] 
      public string source { get; set; } 
     } 

     public class StaffDetails 
     { 
      [DataMember(IsRequired = true)] 
      public string reps_name { get; set; } 

      [DataMember(IsRequired = true)] 
      public string reps_location { get; set; } 

      [DataMember(IsRequired = true)] 
      public string customer_id { get; set; } 
     } 

     public class CustomerAddress 
     { 
      [DataMember(IsRequired = true)] 
      public string postcode { get; set; } 

      [DataMember(IsRequired = true)] 
      public string street_or_address { get; set; } 

      [DataMember(Name = "city", IsRequired = true)] 
      public string city { get; set; } 

      [DataMember(Name = "country", IsRequired = true)] 
      public string country { get; set; } 
     } 

下面是我從「SerialiseRequest」方法取回的序列化數據的樣本:

{「registration_header」:{「ACCOUNT_TYPE 「:」 單」, 「affiliate_number」: 「A061535」, 「services_required」: 「傳輸」}, 「primary_user」:{ 「出生日期」: 「23-10-1989」, 「電子郵件」: 「K @大風」 「FIRST_NAME」: 「凱西」, 「landline_number」: 「」, 「姓氏」: 「大風」, 「middle_name」: 「」, 「MOBILE_NUMBER」: 「+ 44-79879879879」, 「國籍」: 「英國」, 「職業」:「農夫」,「residence_country」:「英國」,「來源」:「其他」,「標題」:「小姐」}, 「partner_attributes」: { 「CUSTOMER_ID」: 「273098」, 「reps_location」: 「斯托克頓北 東英」, 「reps_name」: 「理查德·蓋爾-551」}, 「primary_residential_address」:{ 「城市」: 「拉克霍爾」,「國家「:」 英國」, 「郵政編碼」: 「ML9 2LS」, 「street_or_address」: 「1街」}}

+0

哪個字段是必填項,並且在提交的json中爲null? –

+0

'try ... catch ... return string.Empty'。我的天啊! –

+0

@JhonatasKleinkauff不需要的2個字段是middle_name和landline_number。 正如你在上面的輸出中看到的那樣,它們包含一個空字符串,但是我希望它們在沒有數據的情況下省略。 –

回答

1

可以使用[DataMember(EmitDefaultValue = false)]attribute

[DataContract] 
public sealed class RegistrationRequest 
{ 
    [DataMember(Order = 0, IsRequired = true)] 
    public Registration_Header registration_header { get; set; } 

    [DataMember(Order = 1, IsRequired = true)] 
    public Customer_Details primary_user { get; set; } 

    [DataMember(Order = 2, IsRequired = true)] 
    public StaffDetails partner_attributes { get; set; } 

    [DataMember(Order = 3, IsRequired = true)] 
    public CustomerAddress primary_residential_address { get; set; } 

    public class Registration_Header 
    { 
     [DataMember(Order = 0, IsRequired = true)] 
     public string services_required { get; set; } 

     [DataMember(Order = 1, IsRequired = true)] 
     public string account_type { get; set; } 

     [DataMember(Order = 2, IsRequired = true)] 
     public string affiliate_number { get; set; } 
    } 

    [DataContract] 
    public class Customer_Details 
    { 
     [DataMember(IsRequired = true)] 
     public string title { get; set; } 

     [DataMember(IsRequired = true)] 
     public string first_name { get; set; } 

     [DataMember(EmitDefaultValue = false)] 
     public string middle_name { get; set; }  

     [DataMember(IsRequired = true)] 
     public string last_name { get; set; } 

     [DataMember(IsRequired = true)] 
     public string email { get; set; } 

     [DataMember(IsRequired = true)] 
     public string nationality { get; set; } 

     [DataMember(IsRequired = true)] 
     public string dob { get; set; } 

     [DataMember(IsRequired = true)] 
     public string occupation { get; set; } 

     [DataMember(IsRequired = true)] 
     public string residence_country { get; set; } 

     [DataMember(IsRequired = true)] 
     public string mobile_number { get; set; } 

     [DataMember(EmitDefaultValue = false)] 
     public string landline_number { get; set; } 

     [DataMember(IsRequired = true)] 
     public string source { get; set; } 
    } 

    public class StaffDetails 
    { 
     [DataMember(IsRequired = true)] 
     public string reps_name { get; set; } 

     [DataMember(IsRequired = true)] 
     public string reps_location { get; set; } 

     [DataMember(IsRequired = true)] 
     public string customer_id { get; set; } 
    } 

    public class CustomerAddress 
    { 
     [DataMember(IsRequired = true)] 
     public string postcode { get; set; } 

     [DataMember(IsRequired = true)] 
     public string street_or_address { get; set; } 

     [DataMember(Name = "city", IsRequired = true)] 
     public string city { get; set; } 

     [DataMember(Name = "country", IsRequired = true)] 
     public string country { get; set; } 
    } 
} 

還要注意,你必須來裝點Customer_Details[DataContract]它才能生效。

+0

謝謝埃裏克,我會給你一個旋轉。它確實提出了問題,我是否真的需要爲所有其他元素包含(IsRequired = true)? –

+1

從我可以從[MSDN文檔]告訴(https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.isrequired(V = vs.110)的.aspx),它會在讀取或反序列化時檢查並相應地拋出錯誤。取決於你想要在客戶端實施什麼樣的行爲。而另一[鏈接](https://docs.microsoft.com/en-us/dotnet/framework/wcf/best-practices-data-contract-versioning)關於爲datacontracts- –

+1

@Richard最佳實踐。大風個人而言,我不會使用'IsRequired = true',除非我真的想強制這個屬性總是在那裏。這意味着從JSON到C#對象的每個反序列化。 –

0

的串行只會序列化對象中的數據。它不會在課堂上進行裝飾。當DataContract被髮送回服務時,IsRequired屬性將被觸發。

+0

那麼你是說這不是正確的方法來省略沒有數據的字段嗎? –

+0

啊!請原諒我。我錯過了他說他不想傳輸沒有數據的字段的部分。我認爲Erik有最好的答案。 – padotj