服务堆栈默认格式

本文关键字:格式 默认 堆栈 服务 | 更新日期: 2023-09-27 18:32:08

我想将ServiceStack的默认格式设置为JSON,而不是从浏览器访问服务时通常返回的HTML格式响应。 我知道可以通过发送 ?format=json 参数或将 Accept 标头设置为 application/json 来在每个请求上指定这一点。 有没有办法在不依赖请求中的这些提示的情况下更改这一点?

服务堆栈默认格式

除了使用 ?format=json 在 QueryString 上指定它之外,还可以通过将格式 .ext 附加到路由的末尾,例如:/rockstars.json,或者指定 HTTP 标头(在 HttpClient 中):Accept: application/json

否则,如果您的 HttpClient 未发送接受标头,则可以使用以下方法将 JSON 指定为 AppHost 中的默认内容类型:

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

服务堆栈中的所有配置选项都在此处设置。

从 Web 浏览器调用 Web 服务时的问题在于,它们通常要求Accept: text/html而不是 JSON,根据合同,ServiceStack 通过返回 HTML 来强制要求 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);

我使用 PreRequestFilter 强制对浏览器做出 JSON 响应。 您仍然可以在查询字符串上看到 ?format=json,但如果您禁用了 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();
        }
    });

这个问题很晚,但由于我在任何地方都找不到答案,我终于从ServiceStack的源代码:)中找到了答案。

我发现从浏览器中默认为 Json 而不是 Html 的最简单方法是:

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

在应用程序启动时调用它,它将覆盖默认的 ServiceStack mime 类型并以 json 开头(这将适用于浏览器的请求,因为 / 将匹配它)。

请注意,您仍应禁用 Html 并将 Json 设置为默认 mime 类型:

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

好奇的人:ServiceStack使用内部HttpRequestExtensions.GetResponseContentType(请参阅HttpRequestExtensions.cs),它循环访问首选内容类型。因为它包含MimeTypes.Html,它将从浏览器(text/html)捕获第一个接受类型,并忽略后面的任何内容。通过重写此内容类型,text/html不会被视为首选内容类型,然后跳到默认为按预期json */*