我以为我已经跳过了必要的环节,让我的JsonMediaTypeFormatter
与定制ISerializable
实现一起工作,并通过了单元测试。但是,当我通过Swagger UI传入值时,我无法使其工作。Web API将不会使用ISerializable实现
我的关键问题是:
- 我在做什么毛病我的单元测试使其序列化/反序列化从什么是Web API是做不同?
- 为了使Web API的序列化/反序列化和Swagger/Swashbuckle能够正常工作,需要做些什么?
类被序列:(请注意,序列化,然后反序列化脱落时间部分,只保留日期组件的测试/观察的目的的帮助。)
public class Pet : ISerializable
{
public DateTime Dob { get; set; }
public Pet()
{
Dob = DateTime.Parse("1500-12-25 07:59:59");
}
public Pet(SerializationInfo info, StreamingContext context)
{
Dob = DateTime.Parse(info.GetString("Dob"));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Dob", Dob.Date.ToString());
}
}
的Web API方法:(始终返回null)
public class TestController : ApiController
{
[Route("~/api/Pet")]
public string Get([FromUri] Pet data)
{
return data.Dob.ToString();
}
}
通过单元测试:(和序列化助手from MSDN文档)
[TestFixture]
public class SerializationTests
{
[Test]
public void PetTest()
{
var date = new DateTime(2017, 1, 20, 5, 0, 0);
var foo = new Pet { Dob = date };
var jsonFormatter = new JsonMediaTypeFormatter { SerializerSettings = new JsonSerializerSettings { ContractResolver = new DefaultContractResolver { IgnoreSerializableInterface = false } } };
var serialized = SerializationHelpers.Serialize(jsonFormatter, foo);
Console.WriteLine(serialized);
var deserialized = SerializationHelpers.Deserialize<Pet>(jsonFormatter, serialized);
Assert.That(foo.Dob, Is.Not.EqualTo(date.Date));
Assert.That(deserialized.Dob, Is.EqualTo(date.Date));
}
}
public static class SerializationHelpers
{
public static string Serialize<T>(MediaTypeFormatter formatter, T value)
{
// Create a dummy HTTP Content.
Stream stream = new MemoryStream();
var content = new StreamContent(stream);
// Serialize the object.
formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait();
// Read the serialized string.
stream.Position = 0;
return content.ReadAsStringAsync().Result;
}
public static T Deserialize<T>(MediaTypeFormatter formatter, string str) where T : class
{
// Write the serialized string to a memory stream.
Stream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(str);
writer.Flush();
stream.Position = 0;
// Deserialize to an object of type T
return formatter.ReadFromStreamAsync(typeof(T), stream, null, null).Result as T;
}
}
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.Clear();
var jsonFormatter = new JsonMediaTypeFormatter { SerializerSettings = new JsonSerializerSettings { ContractResolver = new DefaultContractResolver { IgnoreSerializableInterface = false } } };
config.Formatters.Add(jsonFormatter);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
一些其它注释:
- 当运行通过单元测试中,
Console.WriteLine
输出是:
{ “多波”: “2017年1月20日12:00:00 AM”}
这正是我想要的/期望。
- 我的Swagger UI看起来像这样使用Nuget的默认Swashbuckle设置。请注意,日期的值是在默认构造函数中设置的值,表明我的
ISerializable
实现被忽略。
注: 我已经改变了问题,从图片中删除所有的仿制药。这个问题现在基本上是关于ISerializable
的实现,而不是关于泛型。
我觉得这里的问题是与你的GET请求模型使用泛型 - '公共字符串获取([FromUri] MyClass的数据)'。 MyClass模型不能是通用的。尝试将该参数设置为具体类型。 –
alltej
@alltej我可以肯定地得到简单的POCO类来正确序列化。为什么泛型是一个问题?我曾尝试使用自定义的'JsonMediaTypeFormatter'(它在单元测试中工作),但当Web API调用它时,完全相同的'JsonMediaTypeFormatter'失败。为什么我不能使用自定义序列化?所有的博客和MSDN文档都说我可以使用自定义序列化。 – Jaxidian