Добавление пользовательской логики через фильтры запросов / ответов
См. Фильтры запросов и ответов , чтобы узнать, как добавить пользовательскую логику до и после вызова вашей службы.Лучше всего добавлять эти фильтры через атрибуты фильтра запросов / ответов , поскольку они позволяют помечать только те службы, которым нужны эти фильтры.
Проблема с фильтром запросовпроисходит ли это после десериализации в запрос DTO, что слишком поздно, чтобы добавить собственную логику десериализации.Чтобы обойти это, вы можете зарегистрировать настраиваемый механизм связывания запросов в вашем AppHost с помощью:
base.RegisterRequestBinder<MyRequest>(httpReq => ... requestDto);
Это дает вам доступ к объекту IHttpRequest и позволяет самостоятельно добавлять собственную логику десериализации.Другой вариант - указать ServiceStack не пытаться десериализовать сам запрос и вместо этого ввести HttpRequest InputStream, чтобы можно было самостоятельно десериализовать запрос:
public class Hello : IRequiresRequestStream {
Stream RequestStream { get; set; }
}
Оба эти примера объяснены в сериализации ServiceStack иДесериализация вики-страница.
Регистрация собственного пользовательского типа носителя
Еще один вариант, позволяющий возвращать DTO со строгим типом, но изменить вывод для определенных запросов можно сделать, добавивновый пользовательский тип носителя, как описано в примере Northwind VCard Custom типа носителя , например:
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));
}
}
}
Это хороший вариант, если вы можете подключить пользовательские ответы XML под другим контентомВведите, например, application / v-xml , чтобы он не конфликтовал с существующим форматом / конечной точкой XML.Используя ContentType выше, ваш HTTP-клиент может вызвать эту пользовательскую реализацию с ? Format = v-xml или с помощью заголовка HTTP: Accept: application / v-xml .
Если вы хотите переопределить встроенный XML ContentType, вы все еще можете, но я рекомендую вернуться к исходной реализации XmlSerializer для методов SerializeStream и DeserializeStream, если это не один из устаревших форматов, которые вы должны поддерживать.
Обход ServiceStack и выполнение с использованием собственного настраиваемого IHttpHandler
Другой вариант - полностью обойти ServiceStack и вместо этого обработать запрос в собственном настраиваемом обработчике IHttpRequest, зарегистрировав его в конфигурации ServiceStack в вашем AppHost:
SetConfig(new EndpointHostConfig {
RawHttpHandlers = {
httpReq => return IsLegacyMatch(httpReq) ? new LegacyXmlHandler() : null
}
});
Возвращение ненулевое (т. Е. Любой обработчик) обходит ServiceStack.