31

I'm evaluating ServiceStack for use in a Windows Service to host REST services. So far, it's excellent and way outperforms WCF. Not to mention its much easier to use.

The Windows Services mentioned above need to be able to provide a simple HTML page to serve as a "dashboard". ServiceStack would of course be used to provide json data for the dashboard, but what about serving the dashboard page, along with images and js? Would this be possible? I would rather not host full-blown ASP.Net and have a strict limitation that IIS will never run on these servers. Scalability shouldnt be a requirement either, since only a single admin machine would ever be displaying the dashboard.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Kilhoffer
  • 32,375
  • 22
  • 97
  • 124

2 Answers2

55

Using only ServiceStack for web and web services

ServiceStack's new Razor View Engine support

A significant improvement to ServiceStack's HTML story was added in v3.9.11 in the ServiceStack.Razor NuGet package. With this support ServiceStack now graduates to a full Website and Web Services framework that offers a much simpler replacement to WCF, MVC and WebApi.

Full documentation explaining ServiceStack's new HTML story with Razor Support is maintained in the Razor Rockstars demo website:

Full Documentation explaining Razor support and describing its Features is explained in the links above.

Just a REST Service framework with HTML Format

The HTML Content-Type has been added to ServiceStack just as you would expect from a true REST Service framework, i.e. you can simply add Razor Views to enhance your existing services which will only get used when the client requests for the text/html Content-Type (with no effect on the existing registered formats). E.g. this /rockstars REST service can still be accessed in all the other Content-Types:

In addition if your services has the [ClientCanSwapTemplates] attribute, the client can swap the Views and Templates of pages at runtime, e.g. here's the same above page with:

ServiceStack's natural adoption of the HTML format in this way, makes it trivial to develop 1 set of services that can serve both HTML and rich native mobile and desktop clients.

Other ways to serve HTML

Before Razor support was added there are a couple of strategies of serving HTML pages with ServiceStack:

Use a static html page with ajax calls

If you make a web request for an existing file, it gets returned with the Static File Handler. You can then simply make ajax json calls back to your web services to dynamically generate a page.

The TODO Backbone application in the Windows Service AppHost Starter Template works this way. (as well as most other example projects in ServiceStack :-)

Return a string

Any string returned from your web services gets directly written to the response stream 'as-is', so you can simply return html using your own html templating solution.

Here's a list of other possible return types in ServiceStack and how they're treated.

Using Markdown Razor

The view-engine built into ServiceStack is Markdown Razor - Which was inspired by MVC's Razor but using Markdown syntax. It's quite extensible supporting custom base class and extension methods/utils.

A nice feature of using Markdown Razor is your same web service that returns json,xml, etc can also be a view model for a dynamically generated html page at the same url.

An example of this is the category web service which you can see the results of here: http://www.servicestack.net/docs/category/Framework

and the same service again in JSON, XML, etc. You can also retrieve the partially generated html page (without the template) as well the dynamically generated markdown.

The page was created using the web services DTO/view model which was sent to this MarkdownRazor View https://raw.github.com/ServiceStack/ServiceStack.Examples/master/src/Docs/Views/Category.md

If you have specified a Markdown Razor page for your web service, it is used over the default HTML5 JSON Report that you see now.

The resolution order ServiceStack's uses to resolve the appropriate Markdown template to use for rendering HTML output is:

  • If the Web Service specifies a template (via a customized IHttpResult.TemplateName response) - then a View with that name.
  • A view with the same name as the Response DTO, looking first in /Views then in /Views/Shared
  • A view with the same name as the Request DTO, looking first in /Views then in /Views/Shared

Host ServiceStack at a /custompath

ServiceStack can be used together with or without an existing ASP.NET web application. If your application is HTML-heavy and REST-Services-light a common approach is to host ServiceStack at a /custompath (e.g. /api) so you can use ASP.NET for all HTML page generation.

If using ASP.NET MVC instead, you need to ignore the route in MVC's Global.asax RegisterRoutes():

routes.IgnoreRoute ("servicestack/{*pathInfo}");
Community
  • 1
  • 1
mythz
  • 141,670
  • 29
  • 246
  • 390
  • This is excellent info. Not sure which direction I'm going to take just yet, but looking over the examples you linked to, they all look pretty easy. – Kilhoffer Nov 20 '11 at 15:10
  • An interesting problem I've witnessed when using the same static html method used in the Windows Service Starter Template, is that the initial request serves up the page, but subsequent requests never load. The browser just "spins" and states that it's "loading localhost". I've tried this in all three major browsers with the same result. Any ideas what would cause that? – Kilhoffer Nov 20 '11 at 16:01
  • In addition, I see ObjectDisposedException messages showing up in the Output window when serving pages up through a console host. Again, the first request is good, subsequent requests never come through. – Kilhoffer Nov 20 '11 at 16:08
  • 1
    k just had a look, the ObjectDisposedException was being thrown by the NotFoundExceptionHandler (when requesting fav.ico) and it seems the hanging was because the responses weren't being closed (was prev doign some work in this area) - Should now be fixed now in v3.07 on GitHub or NuGet. – mythz Nov 20 '11 at 22:56
  • Was it really necessary to introduce yet another view engine? I wish more developers would realize that syntax isn't the problem, it's too many syntactical choices that is. – ATL_DEV Aug 15 '12 at 22:09
  • Note: As of v3.9.17 ServiceStack's new HTML Story now also includes the MVC Razor ViewEngine: http://razor.servicestack.net – mythz Oct 10 '12 at 04:11
  • 2
    If I could I would vote you up twice. I am loving this. Good post. – LCarter Apr 05 '13 at 00:04
0

If you are trying this in .net core with latest ServiceStack(5.8.0) with a self hosted kestrel implementation with ServiceStack.Kestrel, like I was, the provided answer will not work. The Razor package does not like this version of ServiceStack and requires 5.0.0 binaries.

However the routing page provides an answer : https://docs.servicestack.net/routing

Example :


[Route("/hello/world","GET")]
public class HelloWorld{}

public class GreetingService : Service {
     public HttpResult Get(HelloWorld request)
        {
            return new HttpResult(VirtualFileSources.GetFile("HelloWorld.html"));
        }
  }

This took me far to long to find out so hopefully this response will save someone the pain.

Please note, this only will allow you to return html page, not Razor pages, like the original poster required.

Baz G
  • 154
  • 5
  • If you use [ServiceStack.Razor](https://docs.servicestack.net/netcore-razor) it has the behavior described in [Add HTML views to existing services](http://razor.netcore.io/#unified-stack) where it will render [View Pages](https://docs.servicestack.net/razor-views-vs-content-pages) with the same name as the Request or Response DTO, e.g. you can could render the response of this Service with `/Views/HelloWorld.cshtml`. If you use MVC Razor, it's completely unrelated, a more flexible option is [#Script Pages](https://sharpscript.net/docs/sharp-pages) which lets you render dynamic HTML. – mythz May 10 '20 at 07:56
  • I missed some information, apologies. I am using a self host ServiceStack.Kestrel implementation where I was having this issue. I have edited my comment to reflect as such. It would not allow inclusion of RazorFormat() due to IPlugin reference being in 5.0.0 assembly: https://raw.githubusercontent.com/bazpublic/servicestack-kestral-razor/master/src/Console.Razor.Example/error.png I have span up an example project showing this issue, should you care to have a look at the possible bug: https://github.com/bazpublic/servicestack-kestral-razor – Baz G May 10 '20 at 18:52
  • The issue you're running into is trying to reference the .NET Framework ServiceStack.Razor project instead of [ServiceStack.Mvc required by .NET Core](https://docs.servicestack.net/netcore-razor). Also I'd avoid using `AppSelfHostBase`, it's a compatibility layer so the same integration tests can be run on .NETFX/.NET Core, but all .NET Core Apps are Console Apps so it's recommended to just start with a [razor](https://github.com/NetCoreTemplates/razor) project if you want to use Razor, although for a lighterweight option check out [script](https://github.com/NetCoreTemplates/script). – mythz May 11 '20 at 02:26