Replacing an outdated system and creating new server code using standard ServiceStack + serialization

We have the old server code that we want to leave and develop new with ServiceStack. Existing clients are not written to .Net. We do not plan to use .Net on the client side at all.

The data exchange between the client and the server is carried out using XML and JSON - at the moment JSON is used only as a return format for the response (only for some available services). The XML format was defined when the first version of the server solution was created a couple of years ago. We do not want to change it.

How we use ServiceStack to create new RESTful web services that will serialize and deserialize data in a format that was developed in the past (note that clients will not be written to C # /. Net). We need to consult: serialization and deserialization. Is it possible to use DTO and still have control over how these objects are serialized / deserialized?

+4
source share
1 answer

Adding custom logic using Request / Response filters

See Request and response filters for how to add custom logic before and after a service call. It’s best to add these filters using the Request / Response FilterAttributes , since it allows you to mark only the services that need these filters attached.

The problem with the query filter occurs after deserializing the DTO request, which is too late to add custom de-serialization logic. To get around this, you can register a custom mediation ad in your AppHost with:

base.RegisterRequestBinder<MyRequest>(httpReq => ... requestDto); 

This gives you access to the IHttpRequest object and allows you to add custom deserialization logic yourself. Another option is to tell ServiceStack not to try to deserialize the request itself and instead enter the HttpRequest InputStream so that you can deserialize the request yourself:

 public class Hello : IRequiresRequestStream { Stream RequestStream { get; set; } } 

Both of these examples are explained on the ServiceStack serialization and de-serialization wiki page.

Register your own custom media type

Another option, in order to be able to return strongly typed DTOs, but change the output for certain requests, can be done by adding a new custom media type, as described in the Northwind VCard Virtual Media Example , for example:

 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)); } } } 

This is a good option if you can mount custom XML responses under a different type of content, for example. application / v-xml so that it does not contradict the existing XML format / endpoint. Using ContentType over your HTTP client can trigger this custom implementation with ? Format = v-xml or using the HTTP header: Accept: application / v-xml .

If you want to override the embedded XML ContentType, you can still, but I recommend that you abandon the original implementation of the XmlSerializer for the SerializeStream and DeserializeStream methods, if this is not one of the legacy formats that you must support.

By-pass ServiceStack and execute using your own custom IHttpHandler

Another option is to completely bypass ServiceStack and instead process the request in your own IHttpRequest handler, registering it in the ServiceStack configuration in AppHost:

  SetConfig(new EndpointHostConfig { RawHttpHandlers = { httpReq => return IsLegacyMatch(httpReq) ? new LegacyXmlHandler() : null } }); 

A non-zero return (i.e., any handler) bypasses the ServiceStack.

+5
source

Source: https://habr.com/ru/post/1401162/


All Articles