我以爲我已經跳過了必要的環節,讓我的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