Подтвердить что ты не робот

Формат по умолчанию для ServiceStack

Я хотел бы установить формат по умолчанию для ServiceStack для JSON, в отличие от отформатированного ответа в формате HTML, который обычно возвращает, когда к службе обращаются из браузера. Я знаю, что это можно указать по каждому запросу, отправив параметр? Format = json или установив заголовок Accept в application/json. Есть ли способ изменить это, не полагаясь на эти подсказки из запроса?

4b9b3361

Ответ 1

В дополнение к указанию в QueryString с ? format = json, путем добавления формата .ext до конца маршрута, например: /rockstars.json, или указав заголовок HTTP (в вашем HttpClient): Accept: application/json.

В противном случае, если ваш HttpClient не отправляет заголовок Accept, вы можете указать JSON в качестве типа содержимого по умолчанию в своем AppHost с помощью:

SetConfig(new HostConfig {
     DefaultContentType = MimeTypes.Json 
});

Здесь перечислены все параметры конфигурации в ServiceStack.

Проблема при вызове веб-служб из веб-браузера заключается в том, что они обычно запрашивают Accept: text/html, а не JSON, который по контракту ServiceStack обязывает, возвращая HTML-код, если он включен.

Чтобы вернуть JSON, вы также можете отключить функцию HTML:

SetConfig(new HostConfig {
    EnableFeatures = Feature.All.Remove(Feature.Html),
});

Различные способы указания типа содержимого ответа

В противном случае, если вы хотите переопределить заголовок Accept, вы можете заставить службу всегда возвращать json любым из этих способов: Настроить HTTP-ответ, например:

Использование фильтра (встроенный AddHeader):

[AddHeader(ContentType=MimeTypes.Json)]
public object Any(Request request) { ... }

Установка ответа в службе:

public object Any(Request request) 
{ 
    base.Response.ContentType = MimeTypes.Json;
    return dto;
}

Возвращение оформленного ответа:

return new HttpResult(dto, MimeTypes.Json);

Ответ 2

Я использую PreRequestFilter для принудительного ответа JSON на браузер. Вы все еще видите? Format = json в querystring, но это полезно, если вы отключили html и xml.

this.PreRequestFilters.Add( (req, res) =>
    {
        const string queryString = "format=json"; 
        var jsonAccepted = req.AcceptTypes.Any(t => t.Equals(ContentType.Json, StringComparison.InvariantCultureIgnoreCase));
        var jsonSpecifiedOnQuerystring = !string.IsNullOrEmpty(req.QueryString["format"]) && req.QueryString["format"].Equals("json", StringComparison.InvariantCultureIgnoreCase);
        if (!jsonAccepted && !jsonSpecifiedOnQuerystring)
        {
            var sb = new StringBuilder(req.AbsoluteUri);
            sb.Append(req.AbsoluteUri.Contains("?") ? "&" : "?");
            sb.Append(queryString);
            res.RedirectToUrl(sb.ToString(), HttpStatusCode.SeeOther);
            res.Close();
        }
    });

Ответ 3

Поздно к вопросу, но поскольку я не мог найти ответ нигде, я, наконец, понял его из исходного кода ServiceStack:)

Самый простой способ, которым я нашел по умолчанию Json вместо Html из браузера, был следующим:

HttpRequestExtensions.PreferredContentTypes = new[] { MimeTypes.Json, MimeTypes.Xml };

Вызовите это при запуске своего приложения, и оно переопределит стандартные типы сервисов ServiceStack и начнет с json (который будет работать с вашими запросами браузера, так как/будет соответствовать ему).

Обратите внимание, что вы все равно должны отключить Html и сделать Json типом mime по умолчанию:

SetConfig(new HostConfig {
     DefaultContentType = MimeTypes.Json 
     EnableFeatures = Feature.All.Remove(Feature.Html),
});

Для любопытных: ServiceStack использует внутренне HttpRequestExtensions.GetResponseContentType (см. HttpRequestExtensions.cs), который перебирает предпочтительные типы контента. Поскольку он содержит MimeTypes.Html, он будет захватывать первый тип accept из браузера (text/html) и игнорировать все, что происходит. Переопределяя это, text/html не рассматривается как предпочтительный тип содержимого, а затем переходит к */*, который по умолчанию соответствует json, как ожидалось.