4

目前,我们在 ServiceStack 的根目录中使用 default.cshtml 视图来为我们的 AngularJS 单页应用程序提供服务。

我想做的是启用对 html5 pushstate 的支持(因此 URL 中没有哈希),但到目前为止我发现的唯一示例涉及对带有通配符路由的 MVC 的依赖,并将 ServiceStack 基础架构推送到 / api 子路由。

我们不能接受 MVC 依赖,所以我认为我们需要 accept:text/html 请求,我们需要接受任何 url 并提供我们的根应用程序。我很乐意删除默认的 HtmlFormat 扩展名或覆盖它(我们仍然可以使用我们需要的 JsonReport 内容类型)。

我怎样才能最好地解决这个问题?

4

2 回答 2

5

Order of Operations wiki 页面显示了您可以利用的不同钩子的数量来注入您自己的自定义行为以及它们的运行顺序。

使用 RawHttpHandlers 劫持请求

您可以通过添加 aConfig.RawHttpHandlers来完全绕过 ServiceStack,以在您想要劫持的请求上返回 a IHttpHandler,例如,这是内置的迷你分析器劫持所有以文件开头ssr-并返回物理文件的请求的方式:

config.RawHttpHandlers.Add((IHttpRequest request) => {
    var file = GetFileNameWithoutExtension(request.PathInfo);
    return file != null && file.StartsWith("ssr-")
        ? new MiniProfilerHandler()
        : null;
}

为不匹配的路由提供回退处理程序

如果您想为不匹配的路由提供默认处理程序,您可以在插件中或插件中注册CatchAllHandlers :AppHost.Configure()

appHost.CatchAllHandlers.Add((string method, string pathInfo, string filepath) =>
{
    return ShouldProvideDefaultPage(pathInfo) 
        ? new RazorHandler("/defaultpage.cshtml")
        : null;
});

使用通配符接受服务中的任何 url

您可以创建一个虚拟服务并简单地返回相同的单个视图,例如:

[Route("/app/{PathInfo*}")]
public class App {
    public string PathInfo { get; set; }
}

public class MyService : Service 
{
    public object Any(App request)
    {
        return request;
    }
}

使用通配符,此服务将返回视图,例如/View/App.cshtml以 开头的任何路线/app,例如:

  • /应用程序
  • /应用程序/你好
  • /app/hello/my/name/is?foo=bar

部分页面支持

由于部分重载与 pushstate 相关,我还将提到 ServiceStack 对部分重载的内置支持。

ServiceStack Docs是一个示例演示,它在支持它的浏览器上使用 pushstate,否则它会退回到对不支持它的浏览器使用全页重新加载。

您可以使用参数请求部分页面?format=text.bare,例如

虽然这使用Markdown Razor。在最新的 ServiceStack.Razor 支持中,您可以通过以下方式访问部分页面:?format=bare

于 2013-05-22T23:19:07.233 回答
1

扩展我的评论。这就是我最终尝试在 /app 中托管应用程序同时还支持虚拟文件系统的结果。

host.CatchAllHandlers.Add((string method, string pathInfo, string filepath) =>
{
    if (!Regex.IsMatch(pathInfo, "^/app([/?]|$)"))
        return null;

    // Serve valid requests as is
    var vFile = HostContext.ResolveVirtualFile(pathInfo, null);
    if (vFile != null)
        return null;

    var vDir = HostContext.ResolveVirtualDirectory(pathInfo, null);
    if (vDir != null && vDir.GetDefaultDocument() != null)
        return null;

    // Fallback to default document
    var vDef = HostContext.ResolveVirtualDirectory("/app/", null).GetDefaultDocument();
    return new CustomResponseHandler((req, res) =>
        new HttpResult(vDef.OpenRead(), MimeTypes.GetMimeType(vDef.Name)));
});
于 2015-05-21T16:28:41.897 回答