`Metadata Not Visible` after port to .Net Core

I have an existing ServiceStack project that I have ported to .Net Core - and the project works and runs mostly as expected, apart from the /metdata feature.

The /metdata returns a 403 Metadata Not Visible, but that doesn’t make any sense, as the configuration is

            self.SetConfig(new HostConfig
            {
                // Disable unused features, such as SOAP.
                EnableFeatures = Feature.All.Remove(Feature.Soap11 | Feature.Soap12),
                StrictMode = true,
                DebugMode = debugMode,
                AddRedirectParamsToQueryString = true,
                UseCamelCase = true,
                AdminAuthSecret = "xxxSecretxxx",
            });

When I’m looking at the ServiceStack source I see there is only one instance of that error message https://github.com/ServiceStack/ServiceStack/blob/79b972aa5509d77d2e770759d96e22a51f92a5e1/src/ServiceStack/ServiceStackHost.Runtime.cs#L430 and since I’ve not changed MetadataVisibility I don’t see why that code path should fail at all.

This is is consistent with .Net Core 2.0 and 2.1, on Linux (Ubuntu), macOs and Windows.

Notice that the metadata page works correctly on our .Net 4.6 branch.

The functionality of the backend apart from the /metdata page appears to work as expected.

The port to .Net Core was done by creating a new .Net Core solution, with the same projects, and then all files were moved over and packages added again in .Net Core.
This caused a diff of only the new .Net Core files, and all other files are unchanged,
and therefore allows us to keep the .Net Core branch in sync (rebase) from our develop branch. With this approach we also avoided keeping any cruft around from the old sln and csproj files that could possibly influence anything.

I’m a bit stumped on how to find the error, and what piece of the project/code that could possibly cause this behaviour, and would appreciate pointers.

I tried your config above in a .NET Core App and the /metadata page is working as expected so there must be something else causing it. Can you try adding ?debug=requestinfo to see if there’s any Startup Errors?

If there aren’t any I wont be able tell from here, you can try commenting out functionality to see if you can localize what’s causing it otherwise if you can send me a small stand-alone repro (e.g. on GitHub) I can check it out to identify the issue.

The output from ?debug=requestinfo did not reveal any startup errors as far as I can tell:

{
    "usage": "append '?debug=requestinfo' to any querystring. Optional params: virtualPathCount",
    "host": "_v5.02_TeTo",
    "hostType": "SelfHost (AppHostBase)",
    "startedAt": "2018-04-05 22:09:35",
    "date": "2018-04-06 08:34:13",
    "serviceName": "TeTo",
    "userHostAddress": "::1",
    "httpMethod": "GET",
    "pathInfo": "/metadata",
    "originalPathInfo": "/metadata",
    "stripApplicationVirtualPath": false,
    "getPathUrl": "http://localhost:5000/metadata",
    "absoluteUri": "http://localhost:5000/metadata?debug=requestinfo",
    "applicationBaseUrl": "http://localhost:5000",
    "resolveAbsoluteUrl": "http://localhost:5000/resolve",
    "rootDirectoryPath": "/Users/jhf/Projects/teto/TeTo.Web/wwwroot",
    "currentDirectory": "/Users/jhf/Projects/teto/TeTo.Web",
    "rawUrl": "/metadata?debug=requestinfo",
    "status": 0,
    "contentLength": 0,
    "headers": {
        "Connection": "keep-alive",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "nb-NO,nb;q=0.9,no;q=0.8,nn;q=0.7,en-US;q=0.6,en;q=0.5,da;q=0.4",
        "Cookie": "ss-id=w83mue7J8BjApVeEiuck; ss-pid=Pub6ENqi96KB2hRuFMBl",
        "Host": "localhost:5000",
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
        "Upgrade-Insecure-Requests": "1"
    },
    "queryString": {
        "debug": "requestinfo"
    },
    "formData": {},
    "acceptTypes": [
        "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
    ],
    "operationName": "metadata",
    "responseContentType": "text/html",
    "requestAttributes": "Localhost, InSecure, HttpGet",
    "ipv4Addresses": "127.0.0.1/255.0.0.0, 192.168.5.241/255.255.255.0, 192.168.5.131/255.255.255.0",
    "ipv6Addresses": "::1, fe80::1, fe80::1c45:4246:6fa4:e693, fe80::60d8:70ff:feeb:2b45, fe80::408e:5b00:c2b1:fcd8, fe80::dfb7:72c:653d:3c59, fe80::c62e:feb0:84eb:768b, fe80::94e9:2ff3:ad99:444d, fe80::425:dfe6:dc20:6455",
    "debugString": "",
    "pluginsLoaded": [
        "HtmlFormat",
        "CsvFormat",
        "PredefinedRoutesFeature",
        "MetadataFeature",
        "NativeTypesFeature",
        "HttpCacheFeature",
        "RequestInfoFeature",
        "ValidationFeature",
        "SessionFeature",
        "AuthFeature",
        "ElmNativeTypesFeature",
        "PostmanFeature",
        "CorsFeature",
        "RequestLogsFeature",
        "TemplatePagesFeature",
        "SwaggerFeature"
    ],
    "startUpErrors": [],
    "asyncErrors": [],
    "stats": {
        "RawHttpHandlers": "3",
        "PreRequestFilters": "1",
        "RequestBinders": "0",
        "GlobalRequestFilters": "1",
        "GlobalRequestFiltersAsync": "1",
        "GlobalResponseFilters": "1",
        "GlobalResponseFiltersAsync": "1",
        "CatchAllHandlers": "5",
        "Plugins": "16",
        "ViewEngines": "0",
        "RequestTypes": "55",
        "ResponseTypes": "35",
        "ServiceTypes": "20",
        "RestPaths": "57",
        "ContentTypes": "6",
        "EnableFeatures": "2147483455",
        "VirtualPathProvider": "[FileSystemVirtualFiles: /Users/jhf/Projects/teto/TeTo.Web/wwwroot], [ResourceVirtualFiles: TeTo.Web], [ResourceVirtualFiles: ServiceStack], [ResourceVirtualFiles: ServiceStack.Api.Swagger]"
    },
    "virtualPathProviderFiles": []
}

Next up is removing features to find a minimal reproducible case.

I turns out that this was caused by a version mismatch, as can be seen here:

There was multiple different projects, and the 5.0.3 to ServiceStack.Interfaces happened in another project that the main X.Web that had 5.0.2 of ServiceStack.Server.

The final reproduction was just to put them in the same minimal .Net Core instance.
While this was a unfortunate mistake, it would have been nice if there was a warning of some sorts instead of a breakdown of the /metadata page.
If such an error was caught by StrictMode that would have been great.

Installing the correct dependencies is a .NET infrastructure/project concern, it’s not the responsibility for each library themselves to check for specific versions of all its dependencies. The .NET Runtime loads assemblies according to the information in the Assembly manifest and your projects configured binding redirects, this functionality should not try to be replicated in each library.