gpt4 book ai didi

c# - WebApi 无法遵守 JsonObjectAttribute 设置

转载 作者:太空宇宙 更新时间:2023-11-03 13:18:59 25 4
gpt4 key购买 nike

所以我有一个 ApiController...

public class MetaDataController : ApiController
{
[HttpPost]
public HttpResponseMessage Test(TestModel model)
{
//Do Stuff
return new HttpResponseMessage(HttpStatusCode.OK);
}
}

接受模型...

[JsonObject(ItemRequired = Required.Always)]
public class TestModel
{
public int Id { get; set; }
public IEnumerable<SubModel> List { get; set; }
}

public class SubModel
{
public int Id { get; set; }
}

以Json的形式...

{  "Id": 1,  "List": [{ "Id": 11 }, { "Id": 12 } ] }

当发布到此 Controller 操作时,TestModel 上的属性应该使 Json.Net 在 Json 缺少属性时抛出 JsonSerializationException。我围绕确保此行为按预期工作编写了单元测试。

[Test]
public void Test()
{
var goodJson = @"{ 'Id': 1,
'List': [ {'Id': 11}, {'Id': 12} ]
}";

Assert.DoesNotThrow(() => JsonConvert.DeserializeObject<TestModel>(goodJson));

var badJson = @"{ 'Id': 1 }";

Assert.That(()=>JsonConvert.DeserializeObject<TestModel>(badJson),
Throws.InstanceOf<JsonSerializationException>().
And.Message.Contains("Required property 'List' not found in JSON."));
}

将格式良好的 Json 发布到 controlr 操作时,一切正常。但是,如果该 json 缺少必需的属性,则不会抛出异常。映射到缺失属性的 TestModel 成员为空。

为什么 JsonConvert 按预期工作,但通过 WebApiController 自动 Json 反序列化无法遵守 TestModel 上的属性?

最佳答案

对于咯咯笑声,我决定额外确保我的应用程序使用 Json.Net 进行 json 反序列化。所以我写了一个 MediaTypeFormatter

public class JsonTextFormatter : MediaTypeFormatter
{
public readonly JsonSerializerSettings JsonSerializerSettings;
private readonly UTF8Encoding _encoding;

public JsonTextFormatter(JsonSerializerSettings jsonSerializerSettings = null)
{
JsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();

SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
_encoding = new UTF8Encoding(false, true);
SupportedEncodings.Add(_encoding);
}

public override bool CanReadType(Type type)
{
if (type == null)
{
throw new ArgumentNullException();
}

return true;
}

public override bool CanWriteType(Type type)
{
return true;
}

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var serializer = JsonSerializer.Create(JsonSerializerSettings);

return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(readStream, _encoding))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}

public override Task WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var serializer = JsonSerializer.Create(JsonSerializerSettings);
return Task.Factory.StartNew(() =>
{
using (
var jsonTextWriter = new JsonTextWriter(new StreamWriter(writeStream, _encoding))
{
CloseOutput = false
})
{
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
}
});
}
}

并修改了我的 WebApiConfig 以使用它而不是默认值。

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new HandleSerializationErrorAttribute());

config.Formatters.RemoveAt(0);
var serializerSettings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Error
};
config.Formatters.Insert(0, new JsonTextFormatter(serializerSettings));

}
}

我还添加了一个 ExceptionFilterAttribute 来捕获序列化错误并返回有关错误的相关信息。

public class HandleSerializationErrorAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is JsonSerializationException)
{
var responseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
responseMessage.Content = new StringContent(JsonConvert.SerializeObject(context.Exception.Message));

context.Response = responseMessage;
}
}
}

所以它是:.net MVC 4 WebApi 说它使用 Json.Net,但默认的 JsonFormatter 拒绝遵守装饰我的模型的 Json 属性。手动明确设置格式化程序可解决此问题。

关于c# - WebApi 无法遵守 JsonObjectAttribute 设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25026336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com