首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Web将不使用ISerializable实现

Web将不使用ISerializable实现
EN

Stack Overflow用户
提问于 2017-03-08 16:22:35
回答 1查看 241关注 0票数 1

我以为我已经跳过了必要的循环,让我的JsonMediaTypeFormatter与自定义ISerializable实现一起工作,并通过了单元测试。但是,当我通过Swagger传递值时,我无法让它工作。

我的主要问题是:

  1. 我的单元测试做错了什么,导致它不同于Web所做的序列化/反序列化?
  2. 要使用Web的序列化/反序列化和Swagger/Swashbuckle,需要更改什么?

被序列化的类:(请注意,序列化然后反序列化会降低时间组件,只保留date组件。)用于测试/观察目的的帮助。

代码语言:javascript
运行
复制
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方法:(总是返回null)

代码语言:javascript
运行
复制
public class TestController : ApiController
{
    [Route("~/api/Pet")]
    public string Get([FromUri] Pet data)
    {
        return data.Dob.ToString();
    }
}

通过单元测试:(以及序列化助手来自MSDN文档)

代码语言:javascript
运行
复制
[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

代码语言:javascript
运行
复制
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 }
        );
    }
}

还有几个注意事项:

  1. 当我运行通过的单元测试时,Console.WriteLine输出是:

{“道布”:“2017年1月20日12时:00”}

这正是我所期望的。

  1. 我的Swagger看起来像这样,使用Nuget的默认Swashbuckle设置。注意,日期的值是默认构造函数中设置的值,这表明我的ISerializable实现被忽略了。

注意:我已经更改了问题以删除图片中的所有泛型。这个问题从根本上讲是关于ISerializable实现的,而不是泛型的。

EN

回答 1

Stack Overflow用户

发布于 2017-03-09 14:03:42

WebAPI api不知道如何反序列化这个通用对象。我在这里看到了一个类似的问题,但我没有亲自尝试/测试它。希望能有所帮助:通用Web Api方法

与其使用泛型方法,不如创建泛型控制器。因此,上面的代码将如下所示。

代码语言:javascript
运行
复制
public abstract class MyClass{ }

public class PersonDto: MyClass{}


public class TestController<T> : ApiController where T: MyClass
{
    public string Get([FromUri] T data)
    {
        ...
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42676585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档