私は次のモデルを持っています:
public class Resource
{
[DataMember(IsRequired = true)]
[Required]
public bool IsPublic { get; set; }
[DataMember(IsRequired = true)]
[Required]
public ResourceKey ResourceKey { get; set; }
}
public class ResourceKey
{
[StringLength(50, MinimumLength = 1)]
[Required]
public string SystemId { get; set; }
[StringLength(50, MinimumLength = 1)]
[Required]
public string SystemDataIdType { get; set; }
[StringLength(50, MinimumLength = 1)]
[Required]
public string SystemEntityType { get; set; }
[StringLength(50, MinimumLength = 1)]
[Required]
public string SystemDataId { get; set; }
}
次のアクション メソッド シグネチャがあります。
public HttpResponseMessage PostResource(Resource resource)
本文に JSON を含む次のリクエストを送信します (プロパティ「IsPublic」の意図的に無効な値)。
Request Method:POST
Host: localhost:63307
Connection: keep-alive
Content-Length: 477
User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
{
"IsPublic": invalidvalue,
"ResourceKey":{
"SystemId": "asdf",
"SystemDataIdType": "int",
"SystemDataId": "Lorem ipsum",
"SystemEntityType":"EntityType"
},
}
これは無効な JSON です。JSONLint で実行すると、次のように表示されます。
2 行目の解析エラー:
{ "IsPublic": 無効な値,
...................^ 'STRING'、'NUMBER'、'NULL'、'TRUE'、'FALSE'、'{'、'[' が必要です
ModelState.IsValid プロパティは「true」です - なぜですか???
また、検証エラーをスローする代わりに、フォーマッタは逆シリアル化をあきらめて、'resource' 引数を単に null としてアクション メソッドに渡しているようです!
これは、他のプロパティに無効な値を入力した場合にも発生することに注意してください。たとえば、次のように置き換えます。
"SystemId": notAnObjectOrLiteralOrArray
ただし、 「SystemId」プロパティに特別な未定義の値を指定して次の JSON を送信すると、次のようになります。
{
"IsPublic": true,
ResourceKey:{
"SystemId": undefined,
"SystemDataIdType": "int",
"SystemDataId": "Lorem ipsum",
"SystemEntityType":"EntityType"
},
}
次に、次の合理的な例外がスローされます。
Exception Type: Newtonsoft.Json.JsonReaderException
Message: "Error reading string. Unexpected token: Undefined. Path 'ResourceKey.SystemId', line 4, position 24."
Stack Trace: " at Newtonsoft.Json.JsonReader.ReadAsStringInternal()
at Newtonsoft.Json.JsonTextReader.ReadAsString()
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)"
SO: Newtonsoft.Json ライブラリで何が起こっており、部分的な JSON 検証のように見えるのですか?
PS: 名前を引用符で囲まずに、JSON の名前と値のペアを Web API に投稿することは可能です...
{
IsPublic: true,
ResourceKey:{
SystemId: "123",
SystemDataIdType: "int",
SystemDataId: "Lorem ipsum",
SystemEntityType:"EntityType"
},
}
これも無効な JSON です。