21

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

4

3 回答 3

45

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

否则,如果您的 HttpClient 不发送 Accept 标头,您可以将 JSON 指定为 AppHost 中的默认内容类型:

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

ServiceStack 中的所有配置选项都在这里设置。

从 Web 浏览器调用 Web 服务时的问题是,它们通常要求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);
于 2012-04-25T16:41:35.327 回答
2

我使用 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();
        }
    });
于 2012-11-28T05:12:11.383 回答
2

这个问题迟到了,但由于我在任何地方都找不到答案,我终于从 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为预期的内容类型。

于 2015-07-26T23:20:54.840 回答