使用ServiceStack +自定义序列化替换旧系统并创建新的服务器代码

Mac*_*ska 4 c# servicestack

我们有一个遗留的服务器代码,我们想要放弃并使用ServiceStack开发新的代码.现有客户端不是用.Net编写的.我们根本不打算在客户端使用.Net.

客户端和服务器之间的数据正在使用XML和JSON进行交换 - 目前JSON仅用作响应的返回格式(仅适用于某些可用服务).XML格式是在几年前创建服务器解决方案的第一个版本时定义的.我们不想改变它.

我们如何使用ServiceStack构建新的RESTful Web服务,将数据序列化和反序列化为过去设计的格式(请注意,客户端不会用C#/ .Net编写).我们需要对两者进行控制:序列化和反序列化.是否可以使用DTO并仍然可以控制这些对象如何序列化/反序列化?

myt*_*thz 5

通过请求/响应过滤器添加自定义逻辑

请参阅请求和响应过滤器,了解如何在调用服务之前和之后添加自定义逻辑.最好通过Request/Response FilterAttributes添加这些过滤器,因为它允许您仅标记需要应用这些过滤器的服务.

请求过滤器的问题是在反序列化到请求DTO之后发生,这对于添加自定义反序列化逻辑来说为时已晚.要解决此问题,您可以在AppHost中注册自定义请求活页夹:

base.RegisterRequestBinder<MyRequest>(httpReq => ... requestDto);
Run Code Online (Sandbox Code Playgroud)

这使您可以访问IHttpRequest对象,并允许您自己添加自定义反序列化逻辑.另一个选择是告诉ServiceStack不要尝试反序列化请求本身,而是注入HttpRequest InputStream,以便您可以自己反序列化请求:

public class Hello : IRequiresRequestStream {
    Stream RequestStream { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这两个示例都在ServiceStack的序列化和反序列化维基页面上进行了解释.

注册您自己的自定义媒体类型

另一个能够返回强类型DTO但更改某些请求的输出的选项可以通过添加新的自定义媒体类型来完成,如Northwind VCard自定义媒体类型示例中所述,例如:

public static void Register(IAppHost appHost)
{
    appHost.ContentTypeFilters.Register( "text/x-vcard", SerializeToStream,  DeserializeFromStream);
}

...    

public static void SerializeToStream(IRequestContext requestContext, object response, Stream stream)
{
    var customerDetailsResponse = response as CustomerDetailsResponse;
    using (var sw = new StreamWriter(stream))
    {
        if (customerDetailsResponse != null)
        {
            WriteCustomer(sw, customerDetailsResponse.Customer);
        }
        var customers = response as CustomersResponse;
        if (customers != null)
        {
            customers.Customers.ForEach(x => WriteCustomer(sw, x));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您可以在不同的内容类型(例如application/v-xml)下挂载自定义XML响应,那么这是一个不错的选择,因此它不会与现有的XML格式/端点冲突.使用HTTP Client上方的ContentType可以使用?format = v-xml或使用HTTP标头调用此自定义实现:Accept:application/v-xml.

如果你想覆盖内置的XML ContentType,你仍然可以但我建议回到SerializeStream和DeserializeStream方法的原始XmlSerializer实现,如果它不是你必须支持的遗留格式之一.

绕过ServiceStack并使用您自己的Custom IHttpHandler执行

另一种选择是完全绕过ServiceStack,而是通过在AppHost的ServiceStack配置中注册请求,在您自己的自定义IHttpRequest处理程序中处理请求:

 SetConfig(new EndpointHostConfig { 
    RawHttpHandlers = {
      httpReq => return IsLegacyMatch(httpReq) ? new LegacyXmlHandler() : null 
    }
 });
Run Code Online (Sandbox Code Playgroud)

返回非null(即任何处理程序)绕过ServiceStack.