Html5 pushstate Urls на ServiceStack


В данный момент мы используем значение по умолчанию.cshtml вид в корне ServiceStack для обслуживания нашего AngularJS одностраничного приложения.

Что я хотел бы сделать, так это включить поддержку html5 pushstate (так что нет хэша в URL), но единственные примеры, которые я нашел до сих пор, включают зависимость от MVC с шаблонным маршрутом и перемещение инфраструктуры ServiceStack в /api-подпрограмму.

Мы не можем принять зависимость MVC, поэтому я думаю, что нам нужно для запросов accept:text/html нам нужно принять любой url и подавайте наше корневое приложение. Я был бы рад удалить расширение HtmlFormat по умолчанию или переопределить его (мы все еще могли бы использовать его тип контента JsonReport, который нам нужен).

Как мне лучше всего подойти к этому?

2 4

2 ответа:

Порядок операцийвики-страница показывает количество различных крючков, к которым вы можете подключиться, чтобы ввести свое собственное настроенное поведение, а также порядок, в котором они выполняются.

Запросы Hi-jacking с RawHttpHandlers

Вы можете полностью обойти ServiceStack, добавив a Config.RawHttpHandlers для возврата a IHttpHandler на запросы, которые вы хотите hi-jack, например, так встроенный мини-профилировщик hi-jacks выполняет все запросы для файлов, которые начинаются с 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;
    }
}

С помощью wild card эта служба вернет вид, например /View/App.cshtml на любом маршруте, начиная с которого с /app, например:

  • / app
  • / app / hello
  • / app / hello / my / name / is?foo=bar

Частичная поддержка страниц

Поскольку частичные перезагрузки связаны с pushstate, я также упомяну встроенную поддержку ServiceStack для частичных перезагрузок.

ServiceStack Docs-это демонстрационный пример, который использует pushstate в браузерах, поддерживающих его, в противном случае он возвращается к использованию полностраничных перезагрузок с браузерами, которые этого не делают.

Вы можете попросить частичная страница с ?format=text.bare param, например

Хотя для этого используется Markdown Razor. В последнем сервисном пакете.Поддержка Razor вы можете получить доступ к частичной странице с помощью всего лишь: ?format=bare

Расширяю свой комментарий. Это то, что я закончил с попыткой разместить приложение в /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)));
});