我想将 ServiceStack 的默认格式设置为 JSON,而不是从浏览器访问服务时通常返回的 HTML 格式响应。我知道这可以通过发送 ?format=json 参数或将 Accept 标头设置为 application/json 来在每个请求上指定。有没有办法改变这种情况而不必依赖请求中的这些提示?
3 回答
除了使用?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);
我使用 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
为预期的内容类型。