Pregunta

I would like to use ServiceStack as a pure AppHost implementation without using MVC. I want to use it to drive a Single Page App.

Serving the SPA's single HTML shell page is straightforward enough and I've found plenty of examples on doing that. However, I also need to serve a number of JavaScript files and I'm assessing the best way of doing this. I can simply put script tags in the HTML shell page but then I don't get the benefits of bundling and minification, and I would have to maintain this every time I add a new JavaScript file.

All these problems are solved with bundling solutions such as Cassette or ASP.NET MVC4 Bundles. But how would I use these with ServiceStack AppHost?

The ServiceStack.Bundler project is great but it seems to have dependencies on ASP.NET MVC, e.g. as a base for the HTML Helpers which render the JavaScript tags in the HTML.

I'd like to be able to do this without any dependency on MVC, if possible.

¿Fue útil?

Solución 3

It seems neither Cassette nor Microsoft.AspNet.Web.Optimization (the bundling solution included with MVC4 projects by default) have dependencies on ASP.NET MVC. Therefore either solution can be made to work with an AppHost implementation of ServiceStack.

For Cassette:

It all works just fine if, from NuGet, you install:

ServiceStack.Host.AspNet

ServiceStack.Razor

Cassette.Aspnet

... and then use Cassette from a Razor 'cshtml' file as usual.

One small gotcha which did cause me to scratch my head for a few minutes:

The order in which the HttpHandlers are listed in your web.config is important. The ServiceStack.Host.AspNet package adds an HttpHandler path which uses a wildcard meaning any further HttpHandlers, such as that for Cassette.axd, are never reached.

Simply changing the order in my web.config from:

<httpHandlers>
  <add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
  <add path="cassette.axd" verb="*" type="Cassette.Aspnet.CassetteHttpHandler, Cassette.Aspnet" />
</httpHandlers>

to:

<httpHandlers>
  <add path="cassette.axd" verb="*" type="Cassette.Aspnet.CassetteHttpHandler, Cassette.Aspnet" />
  <add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
</httpHandlers>

fixed the problem. I don't know if installing Cassette.Aspnet from Nuget first would have prevented this issue from occurring in the first place.

For Microsoft.AspNet.Web.Optimization:

From NuGet, you install:

ServiceStack.Host.AspNet

ServiceStack.Razor

Microsoft.AspNet.Web.Optimization

Having done this, you can use Microsoft.AspNet.Web.Optimization bundling and minification as normal.

I added a BundleConfig.cs file, followng the convention you'd find in a default MVC4 project. I then call BundleConfig.RegisterBundles(BundleTable.Bundles); from the ServiceStack AppHost file.

Thereafter, all @Scripts.Render() statements in Razor files work just fine.

Otros consejos

If you haven't taken a look at GruntJS yet, it's worth a look (http://gruntjs.com/). By creating some simple tasks, it can combine & minify your HTML, JS, and CSS and has no dependency on .NET. There are a lot of other really useful tasks available to GruntJS as well (js lint checks, JS unit test running, and tons more). You can easily setup different tasks for your environments as well (ie, don't combine/minify when deploying to dev server).

What it allows you to do is create a purely static HTML, CSS, and JS SPA, and you can manage that in a completely different solution/project than your ServiceStack AppHost.

So in your example, you'd just reference the scripts in your index.html file like you normally would and when you're ready to deploy to staging/production you'd run your grunt task which would bundle/minify your code for you and output the static html, min.css, and min.js files for you to some deployment directory. It's really powerful and flexible.

I used to use Bundler and I recently made the switch to GruntJS and I haven't looked back.

So, I don' think there is anything to need to do within ServiceStack's AppHost to use a 'bundling-and-minification' solution. To simplify the 'Bundling' process...

1 - 'Bundle' files from a folder(s) creating a new file(s)
2 - Reference the 'Bundled' file(s) from a View/Html

How to 'Bundle' files from a folder(s) creating a new file(s)

Cassette

  • Cassette seems to handle this process with 'some magic' (see web.config modifications for insight) that calls the Configure method of the CassetteBundleConfiguration class. Installing the Nuget package takes care of 'setup' for you.

ServiceStack.Bundler

Reference the 'Bundled' file(s)

You can do this however you like as long as you know the path of the file(s)

<link href="/Content/some.css" rel="stylesheet" type="text/css" />
<script src='some.js'></script>

Cassette offers some convenient rendering features

@Bundles.Reference('yourbundle')
@Bundles.RenderStylesheets()
@Bundles.RenderScripts()

ServiceStack.Bundler offers some as well (I think this is the code the depends on System.Web.MVC)

@Html.RenderJsBundle()
@Html.RenderCssBundle() 

Note: These are just writing out the <link> and <script> HTML tags.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top