2017-02-20 64 views
0

我有一個類:JSON.NET串行不當序列化的字符串作爲布爾

[JsonObject(MemberSerialization.OptIn)] 
public class UserPreferenceDTO 
{ 
    [JsonProperty] 
    public string Name { get; set; } 

    [JsonProperty] 
    public string Value { get; set; } 

    public static explicit operator UserPreferenceDTO(UserPreference pref) 
    { 
     if (pref == null) return null; 
     return new UserPreferenceDTO 
     { 
      Name = pref.Name, 
      Value = pref.Value 
     }; 
    } 

    public static explicit operator UserPreference(UserPreferenceDTO pref) 
    { 
     if (pref == null) return null; 
     return new UserPreference 
     { 
      Name = pref.Name, 
      Value = pref.Value 
     }; 
    } 
} 

和控制器,例如:

public HttpResponseMessage Post(int caseid, Guid id, UserPreferenceDTO prefs) 
{ ... } 

:控制器類裝飾用一個[CamelCaseControllerConfig]屬性 它這樣做:

public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) 
{ 
    var formatter = controllerSettings.Formatters.OfType<JsonMediaTypeFormatter>().Single(); 
    controllerSettings.Formatters.Remove(formatter); 

    formatter = new JsonMediaTypeFormatter 
    { 
     SerializerSettings = { ContractResolver = new CamelCasePropertyNamesContractResolver() } 
    }; 

    controllerSettings.Formatters.Add(formatter); 

} 

在客戶端上我送過一個對象是這樣的:

{ name: "name", value: "Some value" } 

通常value是一個JS布爾值。問題是,當它到達控制器時,布爾值被轉換爲C#布爾值(True/False)並被串化。

例如,發送

'{ "name": "wantColFit", "value": "false" }' 

變爲:

The boolean in <code>Value</code> is a stringified C# boolean

在.NET控制器

如果你看模型(UserPreferenceDTO)定義Value需要string。那麼爲什麼序列化器將該值轉換爲布爾值?當它被保存(這將使它更容易解析返回給客戶端上的一個布爾值,因爲JSON.parse("true") === trueJSON.parse("True") !== true

我寧願有值保留爲"true"/"false"

+1

這有點令人困惑。你說的是發送類似'{name:'name',value:'value'}'的東西,但是你說你正在發送'{「wantColFit」:「false」}'。你真的發送該或「{」名稱「:」wantColFit「,」值「:false}'?後者會導致你所看到的,我期望。我不確定.NET如何將'{「wantColFit」:「false」}解析爲具有名稱和值屬性的對象... –

+0

@MikeMcCaughan您完全正確。 Editted。 – seebiscuit

回答

0

的Json布爾會映射到C#布爾。 由於您的字段名稱相同,並且在C#端,它是字符串,因此bool已轉換爲字符串。 根據.NEt的中間語言,布爾值「true」將在.Net中變爲「True」。

要解決此問題,無論您需要傳遞布爾值與引號或需要更改您的C#屬性。

string valueField = ""; 

[JsonProperty] 
public string Value 
{ 
    get{ 
     return valueField.ToLower(); 
    } 
    set{ 
     value = valueField; 
    } 
} 
+0

值可以是任何東西。就像一個字符串化的對象/數組等,所以我不能改變你的建議 – seebiscuit

+0

return valueField ==「True」|| valueField ==「False」?valueField.ToLower():valueField; – Kalyan

0

無法弄清楚如何(也不知道爲什麼)Json.Net被反序列化的字符串像"true"來,所以我只是借用了這個要點的C#布爾TrueBooleanConverter.js其中ReadJson作用:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var val = reader.Value.ToString().ToLower().Trim(); 

     if (val == "true" || val == "false") 
      return val; 

     // If we reach here, we're pretty much going to throw an error so let's let Json.NET throw it's pretty-fied error message. 
     return new JsonSerializer().Deserialize(reader, objectType); 
    } 

和我能夠序列化我的模型適當的"true""false"值(而不是"True""False"

如果任何人都可以回答Json.Net在內部做什麼來投出類似布爾的字符串"true"/"false"我會接受他們的答案。