Edit on GitHub

.NET Core Overview

Most of ServiceStack’s features are also available on .NET Core, where it’s all maintained within a single code-base enabling excellent source-code compatibility to maximize existing knowledge and code-reuse and reducing portability efforts, and released within the same suite of NuGet packages, all without breaking changes to existing .NET 4.5 Customers.

.NET Core - the future of .NET on Linux

.NET Core enables an exciting era of .NET Web and Server App development - the kind .NET hasn’t seen before. The existing Windows hosting and VS.NET restraints have been freed, now anyone can develop using .NET’s productive expertly-designed and statically-typed mainstream C#/F# languages in their preferred editor and host it on the most popular server Operating Systems, in either an all-Linux, all-Windows or mixed ecosystem. Not only does this flexibility increase the value of existing .NET investments but it also makes .NET appeal to the wider and highly productive developer ecosystem who’ve previously disregarded .NET as an option.

.NET Core offers significant performance and stability improvements over Mono that’s derived from a shared cross-platform code-base and supported by a well-resourced, active and responsive team. If you’re currently running ServiceStack on Mono, we strongly recommend upgrading to .NET Core to take advantage of its superior performance, stability and its top-to-bottom supported Technology Stack.

and with that let’s jump into seeing some ServiceStack Live Demos running on .NET Core in Linux…

ServiceStack .NET Core Apps running in Docker

Hosting .NET Core Apps immediately exposes us to the benefits of .NET Core. We’ve ported the Live Demos using the most productive IDE and tooling combination we’ve found for us - which is still VS.NET with ReSharper. But for deployments and hosting we now have an array of options at our disposal, including joining the thriving state-of-the-art ecosystem around building Linux Docker images and deploying them to the cloud.

For .NET Core Live Demos we’ve settled on the popular power combo of:

You can checkout our Deploy .NET Core with Docker to AWS ECS Guide for the details on how we’ve deployed the .NET Core Live Demos, but ultimately packaging .NET Core Apps inside Docker images enables a higher-level of abstraction letting you define your entire App Server Instance with a repeatable recipe that lets you treat and deploy instances like opaque self-contained units.

With our .NET 4.5 Windows Live Demos we’re effectively mutating a static Windows Server VM that required pre-configuring with IIS Virtual Hosts. Any infrastructure Servers each Live Demo needs, are set up out-of-band and to minimize the System administration burden, all Demos share the same Redis server instance.

Repeatable, Isolated, no-touch automated Deployments

But for our .NET Core Docker deployments we have proper isolation and repeatable no-touch deployments where any infrastructure services each App needs are declared in configuration and deployed in a separate Docker container along side each App to an ECS cluster - decoupling your deployments from static EC2 instances. This lets you treat your server infrastructure and deployment automation story like code, where it’s checked-in with your Repo and run with your CI who packages it in a Docker Container, publishes it as an opaque Image and deploys it to the AWS EC2 Container Service.

Linux Cost Savings

In addition to the thriving ecosystem and superior automation, another benefit of hosting .NET Core Apps on Linux is the considerable cost savings of hosting on a Linux infrastructure. Docker instances enable isolation with considerably more efficiency than VM’s allowing you to pack them with greater density. For .NET Core Live Demos the single T2 medium instance ($25 /month) is hosting 15 Docker Images whilst running at ~50% Memory Utilization and <1% CPU Utilization in its current idle state.

Exceptional Code reuse

Thanks to ServiceStack’s high-level host agnostic API and our approach to decouple from concrete HTTP abstractions behind lightweight IRequest interfaces, ServiceStack projects enjoy near perfect code reuse, which allows the same ServiceStack Services to be able to run on ASP.NET, HttpListener SelfHosts, SOAP Endpoints, multiple MQ Hosts and .NET Core Apps. The HelloMobile Server Hosts shows an example of this where the same AppHost Configuration and WebServices implementation is used in all:

The primary advantage of this is simplicity, in both effort and cognitive overhead for creating Services that target multiple platforms, reuse of existing knowledge and investments in using ServiceStack libraries and features as well as significantly reduced migration efforts for porting existing .NET Framework code-bases to run on .NET Core where it enjoys near perfect source code compatibility.

ServiceStack’s exceptional source compatibility is visible in our new .NET Core 2.1 and .NET Framework project templates where all templates utilize the same recommended Physical Project Structure, reference the same NuGet packages, share the same source code for its Server and Client App implementations as well as Client and Server Unit and Integration Tests.

The primary difference between the .NET Core and .NET Framework project templates is how ServiceStack’s AppHost is initialized, in ASP.NET it’s done in Global.asax whilst for .NET Core it’s registered in .NET Core’s pipeline as standard. The .csproj are also different with .NET Core using MSBuild’s new and minimal human-friendly format and the ASP.NET Framework templates continuing to use VS.NET’s classic project format for compatibility with older VS .NET versions.

New .NET Core 2.1 Project Templates

There are 11 .NET Core 2.1 project templates for each of ServiceStack’s most popular starting templates. Each .NET Core 2.1 template has an equivalent .NET Framework template except for ServiceStack’s Templates WebApp which is itself a pre-built .NET Core 2.1 App that lets you develop Web Applications and HTTP APIs on-the-fly without any compilation.

All .NET Core 2.1 Templates can be developed using your preferred choice of either VS Code, VS.NET or JetBrains Project Rider on your preferred Desktop OS. Given the diverse ecosystem used to develop .NET Core Applications, the new Project Templates are being maintained on GitHub and made available via our new dotnet-new command-line utility, installable from npm with:

$ npm install -g @servicestack/cli

This makes the dotnet-new command globally available which can be run without arguments to view all templates available:

That can be used to create new projects with:

$ dotnet-new <template-name> <project-name>

Example of creating a new Vue SPA project called Acme:

$ dotnet-new vue-spa Acme

The resulting Acme.sln can be opened in VS 2017 which will automatically restore and install both the .NET and npm packages upon first load and build. This can take a while to install all client and server dependencies, once finished the wwwroot folder will be populated with your generated Webpack App contained within a /dist folder alongside a generated index.html page. After these are generated you can run your App with F5 to run your project as normal:

If using JetBrains Rider the npm packages can be installed by opening package.json and clicking on the “npm install” tooltip on the bottom right. In VS Code you’ll need to run npm install manually from the command-line.

.NET Core Live Demos

To showcase ServiceStack features running on .NET Core we’ve forked several of our existing Live Demos and ported them to .NET Core and listed them side-by-side with their original ASP.NET 4.5 code-bases so they can be easily compared.

The Live Demos cover a broad spectrum of ServiceStack features including:

Redis GEO - simple example showing how to make use of Redis 3.2.0 new GEO features
Features - Redis Client, ServiceStack.Redis GEO APIs
.NET Core
Live Demo: redisgeo.netcore.io
Github: github.com/NetCoreApps/redis-geo
ASP.NET 4.5
Live Demo: redisgeo.servicestack.net
Github: github.com/ServiceStackApps/redis-geo
Chat - Single Page Chat App with real-time Server Events + Simple OAuth in <190 lines of JavaScript
Features - Real-time Server Events and JavaScript Client, Twitter, Facebook and Github OAuth Providers
.NET Core
Live Demo: chat.netcore.io
Github: github.com/NetCoreApps/Chat
ASP.NET 4.5
Live Demo: chat.servicestack.net
Github: github.com/ServiceStackApps/Chat
SimpleAuth.Mvc - Simple demo showcasing integration and authentication with ServiceStack & .NET Core MVC
Features - Simple Auth and OAuth Providers, Role-based Security, MVC Integration, ss-utils.js
.NET Core
Live Demo: mvc.netcore.io
Github: github.com/NetCoreApps/SimpleAuth.Mvc
ASP.NET 4.5
Live Demo: mvc.servicestack.net
Github: github.com/ServiceStack/Test
Stack Apis - AngularJS Single Page App leveraging AutoQuery in <50 lines of JavaScript + 1 AutoQuery DTO
Features - Fully-queryable RDBMS AutoQuery Services, OrmLite.Sqlite, AutoQuery Viewer
.NET Core
Live Demo: stackapis.netcore.io
Github: github.com/NetCoreApps/StackApis
ASP.NET 4.5
Live Demo: stackapis.servicestack.net
Github: github.com/ServiceStackApps/StackApis
Imgur - Resize uploaded images in all iOS Resolutions in <30 lines of JavaScript + 1 ServiceStack ImageService
Features - File Uploads, HTTP Utils
.NET Core
Live Demo: imgur.netcore.io
Github: github.com/NetCoreApps/Imgur
ASP.NET 4.5
Live Demo: imgur.servicestack.net
Github: github.com/ServiceStackApps/Imgur
Todos - Backbone.js TODO App powered by a C# Redis Client back-end
Features - Redis Client
.NET Core
Live Demo: todos.netcore.io
Github: github.com/NetCoreApps/Todos
ASP.NET 4.5
Live Demo: todos.servicestack.net
Github: github.com/ServiceStackApps/Todos
Razor Rockstars - showcasing ServiceStack's Smart Razor Views and Pages support
Features - Smart Razor Pages, OrmLite.Sqlite, Markdown
.NET Core
Live Demo: razor.netcore.io
Github: github.com/NetCoreApps/RazorRockstars
ASP.NET 4.5
Live Demo: razor.servicestack.net
Github: github.com/ServiceStackApps/RazorRockstars
REST Files - GitHub-like browser with remote file management over REST APIs in 1 jQuery and 1 FileService.cs
Features - REST File Management and Virtual File System
.NET Core
Live Demo: restfiles.netcore.io
Github: github.com/NetCoreApps/RestFiles
ASP.NET 4.5
Live Demo: restfiles.servicestack.net
Github: github.com/ServiceStackApps/RestFiles
Northwind - database viewer, effortless data-driven, AutoQuery and Cached services with ServiceStack + OrmLite
Features - RDBMS AutoQuery Services, AutoQuery Viewer, HTTP Caching and CacheResponse attributes
.NET Core
Live Demo: northwind.netcore.io
Github: github.com/NetCoreApps/Northwind
ASP.NET 4.5
Live Demo: northwind.servicestack.net
Github: github.com/ServiceStackApps/Northwind
Redis StackOverflow - StackOverflow-like ajax website powered by ServiceStack and Redis
Features - Redis Client
.NET Core
Live Demo: redisstackoverflow.netcore.io
Github: github.com/NetCoreApps/RedisStackOverflow
ASP.NET 4.5
Live Demo: redisstackoverflow.servicestack.net
Github: github.com/ServiceStackApps/RedisStackOverflow

Multi-stage Docker Builds

The .NET Core Apps deployed using Docker use ASP.NET Team’s recommended multi-stage Docker Builds where the App is built inside an aspnetcore-build Docker container with its published output copied inside a new aspnetcore runtime Docker container:

FROM microsoft/dotnet:2.1-sdk AS build-env
COPY src /app
WORKDIR /app

RUN dotnet restore --configfile NuGet.Config
RUN dotnet publish -c Release -o out

# Build runtime image
FROM microsoft/dotnet:2.1-aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/Chat/out .
ENV ASPNETCORE_URLS http://*:5000
ENTRYPOINT ["dotnet", "Chat.dll"]

The smaller footprint required by the aspnetcore runtime reduced the footprint of .NET Core Chat from 567MB to 126MB whilst continuing to run flawlessly in AWS ECS at chat.netcore.io.

.NET Core Web Apps

.NET Core 2.1 is also used to enable Web Apps which is a new approach to dramatically simplify .NET Wep App development and provide the most productive development experience possible whilst maximizing reuse and component sharing.

Web Apps let you develop dynamic websites without needing to write any C# code or perform any app builds which dramatically reduces the cognitive overhead and conceptual knowledge required for development where the only thing front-end Web developers need to know is ServiceStack Template’s Syntax and what filters are available to call. Because of Template’s high-fidelity with JavaScript, developing a Website with Templates will be instantly familiar to JavaScript devs despite calling and binding directly to .NET APIs behind the scenes.

Web App Examples

To illustrate the various features available we’ve developed a number of Web Apps examples to showcase the different kind of Apps that can easily be developed. The source code for each app is available from github.com/NetCoreWebApps. Each app runs the same unmodified Web App Binary that’s also used in the Bare Web App project above.

You can quickly get started by creating a Web App from the project template:

$ dotnet-new templates-webapp ProjectName

Run ASP.NET Core Apps on the .NET Framework

A primary use-case prevented from having unified NuGet packages containing both .NET Standard and .NET Framework builds is being able to run ASP.NET Core Apps on the .NET Framework which stems from:

Where the net45 builds always get used when they’re added to any .NET Framework project. To support running ASP.NET Core Apps on the .NET Framework you can use the .Core NuGet packages which contains only the .NET Standard 2.0 builds in order to force .NET Framework projects to use .NET Standard 2.0 builds. Currently the complete list of .Core packages which contains only .NET Standard 2.0 builds include:

Ultimately support for whether a .NET Standard 2.0 library will run on the .NET Framework depends on whether external dependencies also support this scenario which as it’s a more niche use-case, will be a less tested scenario.

Other issues from being a less popular scenario is not being able to reference the Microsoft.AspNetCore.All meta package which only supports .NET Core 2.1 projects, instead ASP.NET .NET Standard packages will need to be referenced individually.

To make it as easy as possible to get started you can use the NetFrameworkCoreTemplates containing popular starting templates for running ASP.NET Core Apps on .NET Framework (default v4.7) which as a convention all have the -corefx suffix:

This will let you create an ASP.NET Core App running on the .NET Framework v4.7 with:

$ npm install -g @servicestack/cli

$ dotnet-new web-corefx AcmeNetFx

Which can then be opened in your preferred VS.NET or Project Rider C# IDE.

ServiceStack features that won’t be supported in .NET Core

Whilst we were able to make most of ServiceStack’s features available in .NET Core there are a number of features that we’re not able to support, these include:

Whilst we lost our beloved ServiceStack.Razor support we developed a completely new implementation backed by .NET Core MVC where we were able to implement most of ServiceStack.Razor user-facing features so porting should still be relatively straightforward with some minor syntax and configuration changes needed. This new implementation is available in ServiceStack.Mvc.Core package and can be seen in action in the Razor Rockstars .NET Core demo.

AppSelfHostBase Source-compatible Self-Host

The ServiceStack.Kestrel NuGet package encapsulates .NET Core’s Kestrel HTTP Server dependency behind a source-compatible AppSelfHostBase which can be used to create source-compatible Self Hosted Apps and is what enables the exact same .NET Framework Template’s Integration Tests to be used in .NET Core Template’s Integration Tests.

AppHostBase .NET Core Module

Whilst AppSelfHostBase enables the same development experience for developing Self-Hosted ServiceStack Solutions, when developing .NET Core-only Web Apps we instead recommend inheriting from AppHostBase and registering ServiceStack as a .NET Core module in order to remain consistent with all other .NET Core solutions.

In ASP.NET 4.5, AppHostBase is used to create an ASP.NET ServiceStack Host, but in .NET Core all Web Apps are Console Apps, AppHostBase in this case just refers to a normal ServiceStack AppHost you’ll use to idiomatically register your ServiceStack AppHost into .NET Core’s IApplicationBuilder pipeline as a standard .NET Core Module.

Binding to .NET Core

To see how ServiceStack integrates with .NET Core we’ll walk through porting the stand-alone Todos Live Demo which contains the entire implementation of a functional Todos Web App back-end in a single Startup.cs that we created using the ASP.NET Core Web Application (.NET Core) Empty VS.NET Template.

The Program class remains unchanged from the template and defines the entry-point for your Console Application that just Configures and Starts a Kestrel HTTP Server behind an IIS Reverse Proxy via the AspNetCoreModule HTTP Handler configured in your web.config:

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

.NET Core Startup

The Startup class is what you’ll use to configure your .NET App. The only difference from the default VS.NET Template is the single line to Register your ServiceStack AppHost in .NET Core’s IApplicationBuilder pipeline:

public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration) => Configuration = configuration;

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        //Register your ServiceStack AppHost as a .NET Core module
        app.UseServiceStack(new AppHost { 
            AppSettings = new NetCoreAppSettings(Configuration) // Use **appsettings.json** and config sources
        }); 

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

This shows the minimum code required to configure ServiceStack to run in .NET Core. It works similarly to the Wildcard HttpHandler configuration in your ASP.NET Web.config telling ASP.NET to route all requests to ServiceStack. The difference here is that ServiceStack is registered in a pipeline and only receives requests that weren’t handled in any of the preceding modules. Likewise ServiceStack will just call the next Module in the pipeline for any Requests that it’s not configured to handle, this is in contrast to ASP.NET 4.5 where ServiceStack was designed to handle all requests it receives, so it instead returns a NotFoundHandler and responds with a 404 Response.

In the above configuration any Request that ServiceStack doesn’t handle gets passed on to the next module registered, which in this case will return a Hello World! plain text response.

.NET Core AppHost Integration

Once inside your AppHost you’re back in ServiceStack-land where it’s business as usual and your AppHost configuration remains the same as before. The only differences from .NET 4.5 Todos AppHost is that .NET Framework introduced source-incompatible breaking changes to its Reflection APIs where instead of resolving a Types Assembly with typeof(TodoService).Assembly you’re instead required to call typeof(TodoService).GetTypeInfo().Assembly.

To combat this unfortunate design decision we’ve added Platform Extension Methods providing unified Reflection APIs like Type.GetAssembly() allowing you to configure source-compatible AppHost’s that can be used in both .NET 4.5 and .NET Core platforms, e.g:

// Create your ServiceStack Web Service with a singleton AppHost
public class AppHost : AppHostBase
{
    // Initializes your AppHost Instance, with the Service Name and assembly containing the Services
    public AppHost() : base("Backbone.js TODO", typeof(TodoService).Assembly) { }

    // Configure your AppHost with the necessary configuration and dependencies your App needs
    public override void Configure(Container container)
    {
        //Register Redis Client Manager singleton in ServiceStack's built-in Func IOC
        container.Register<IRedisClientsManager>(new BasicRedisClientManager("localhost"));
    }
}

This minor change was all it took to port the Todos back-end Services to run on .NET Core which was able to reuse the entire existing Service implementation as-is.

The other change needed outside the Todos ServiceStack implementation was to match .NET Core’s default convention of serving static files from the WebRootPath which just required moving all static resources into the /wwwroot folder.

And with that the Todos port was complete, which you can view from the deployed locations below:

Seamless Integration with .NET Core

In addition to running flawlessly on .NET Core we’re also actively striving to find how we can best integrate with and leverage the surrounding .NET Core ecosystem and have made several changes to that end:

CamelCase

The JSON and JSV Text serializers are following .NET Core’s default convention to use camelCase properties by default. This can be reverted back to PascalCase with:

SetConfig(new HostConfig { UseCamelCase = false })

We also agree with this default, .NET Core seems to be centered around embracing the surrounding developer ecosystem where .NET’s default PascalCase protrudes in a sea of camelCase and snake_case JSON APIs. This won’t have an impact on .NET Service Clients or Text Serialization which supports case-insensitive properties, however Ajax and JS clients will need to be updated to use matching properties. You can use ss-utils normalize() methods to help with handling both conventions by recursively normalizing and converting all properties to lowercase.

.NET Core Container Adapter

Like ServiceStack, .NET Core now has a built-in IOC where you can register any dependencies you need in your Startup ConfigureServices(), e.g:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IFoo, Foo>()
                .AddScoped<IScoped, Scoped>()
                .AddSingleton<IBar>(c => new Bar { Name = "bar" });
    }
}

In .NET Core ServiceStack is pre-configured to use a NetCoreContainerAdapter where it will also resolve any dependencies declared in your .NET Core Startup using app.ApplicationServices. One side-effect of this is that when resolving Scoped dependencies it resolves them in a Singleton scope instead of the Request Scope had they instead been resolved from context.RequestServices.GetService<T>().

If you need to resolve Request Scoped .NET Core dependencies you can resolve them from IRequest, e.g:

public object Any(MyRequest request)
{
    var requestScope = base.Request.TryResolve<IScoped>();
}

Alternatively you can just register the dependencies in ServiceStack’s IOC instead, e.g:

public override void Configure(Container container)
{
    services.RegisterAutoWiredAs<Scoped,IScoped>()
        .ReusedWithin(ReuseScope.Request);
}

Note: any dependencies registered .NET Core Startup are also available to ServiceStack but dependencies registered in ServiceStack’s IOC are only visible to ServiceStack.

.NET Core IAppSettings Adapter

Most .NET Core Templates are also configured to use the new NetCoreAppSettings adapter to utilize .NET Core’s new IConfiguration config model in ServiceStack by initializing the AppHost with .NET Core’s pre-configured IConfiguration that’s injected into the Startup.cs constructor, e.g:

public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration) => Configuration = configuration;

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseServiceStack(new AppHost {
            AppSettings = new NetCoreAppSettings(Configuration)
        });
    }
}

This lets you use appsettings.json and .NET Core’s other Configuration Sources from ServiceStack’s IAppSettings API where it continues to resolve both primitive values and complex Types, e.g:

bool debug = AppSettings.Get<bool>("DebugMode", false);
MyConfig myConfig = AppSettings.Get<MyConfig>();
List<string>  ghScopes = AppSettings.Get<List<string>>("oauth.github.Scopes");
IList<string> fbScopes = AppSettings.GetList("oauth.facebook.Permissions");

But instead of a single JSV string value, you’ll need to use the appropriate JSON data type, e.g:

{
    "DebugMode": true,    
    "MyConfig": {
        "Name": "Kurt",
        "Age": 27
    },
    "oauth.facebook.Permissions": ["email"],
    "oauth.github.Scopes": ["user"]
}

Consistent Registration APIs

To retain the same nomenclature that .NET Core uses to register dependencies we’ve added several Overloads to ServiceStack’s IOC letting you use a single consistent API to register dependencies in both ServiceStack and .NET Core IOC’s making it easy to move registrations between the two, e.g:

public void Configure(Container container)
{
    container.AddTransient<IFoo, Foo>()
             .AddScoped<IScoped, Scoped>()
             .AddSingleton<IBar>(c => new Bar { Name = "bar" });
}

ServiceStack’s Container also implements .NET Core’s IServiceProvider interface giving it access to .NET Core’s convenience extension methods for resolving dependencies, e.g:

var foo = container.GetService<IFoo>();

ServiceStack.Logging Adapters

The default Logging is an example of an abstraction which didn’t make sense to maintain a separate implementation as any adapter would only be able to support logging within ServiceStack. With logging you’ll want to configure it one place and have it apply to your whole application, so we’ve instead pre-configured ServiceStack.Logging to proxy all messages to .NET Core’s logging abstraction where you’ll only need to configure logging once in Startup and have it handle all logging solution-wide.

.NET Standard 2.0 Logging Providers

Whilst our recommendation is to use .NET Core’s Logging Abstraction, if you prefer you can avoid this abstraction and configure logging with ServiceStack directly with the logging providers below which maintains .NET Standard 2.0 versions:

Support for NLog will be added once their stable NuGet release contains .NET Standard builds.

WebRootPath and ContentRootPath

Classic ASP.NET serves static resources from your Host project’s folder but in .NET Core this has been moved to your App’s /wwwroot folder, separated from your App’s non-public assets which remain in your projects root folder.

To match this convention we’ve configured the read-only VirtualFileSources to point to the /wwwroot WebRootPath whilst the read/write IVirtualFiles is configured to your projects ContentRootPath folder.

MapProjectPath

As ServiceStack can be hosted in variety of different platforms encompassing several AppHost’s, we’ve added a new IAppHost.MapProjectPath() API that can be used to consistently resolve an absolute file path using a virtualPath from your Host Project root folder, e.g:

var filePath = appHost.MapProjectPath("~/path/to/settings.txt");

HostContext.TryGetCurrentRequest()

ASP.NET Web Applications let you resolve the IRequest of the current executing HTTP Request with:

IRequest req = HostContext.TryGetCurrentRequest();

Which is a wrapper over accessing the HttpContext.Current singleton but as there’s no equivalent in HttpListener self hosts this returns null. .NET Core also doesn’t enable singleton access to the current HttpRequest by default but can be enabled by registering:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

Although this should only be registered if needed as it has non-trivial performance costs.

OrmLite LIKE Queries

One of our primary goals with ServiceStack providers is compatibility which lets you easily switch providers without having to change any call-site logic using the abstraction.

One case where this has an impact on performance is in OrmLite LIKE queries where some RDBMS providers will perform case-sensitive LIKE queries so in order to retain consistent behavior across all RDBMS providers OrmLite generates queries using UPPER(Field) to ensure case-insensitive searches.

However given .NET Core’s strong focus on performance we’ve removed this feature and reverted to the behavior of the underlying RDBMS so it no longer invalidates any DB Indexes on Fields. A more efficient alternative to get case-insensitive LIKE queries (where it’s not the default) is to use a case-insensitive collation.

This behavior also applies to AutoQuery LIKE queries and can be reverted with:

OrmLiteConfig.StripUpperInLike = false;

Register ServiceStack HttpHandlers as .NET Core Modules

Under the hood ServiceStack’s functionality is split into different HTTP Handlers that implements ASP.NET’s IHttpAsyncHandler and is also adapted to support HttpListener self-hosts behind ServiceStack’s IRequest abstractions.

We’re happy to report that ServiceStack’s HTTP Handlers can also be registered as a .NET Core module in the IApplicationBuilder pipeline. This lets you for instance return the same information as ServiceStack’s ?debug=requestinfo route for any unhandled requests by registering the RequestInfoHandler as the last module in .NET Core’s IApplicationBuilder pipeline, e.g:

public class Startup
{
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseServiceStack(new AppHost());

        app.Use(new RequestInfoHandler());
    }
}

Some other examples of HTTP Handlers you could use is returning an image by registering a StaticFileHandler configured with the virtualPath of the image (from ContentRootPath):

app.Use(new StaticFileHandler("wwwroot/img/404.png"));

Or you can even render an MVC Razor View by returning it in a RazorHandler, e.g:

app.Use(new RazorHandler("/login"));

Which will render the /wwwroot/login.cshtml Razor Page using the MVC Smart Razor Pages support

Community Resources