首页 > 解决方案 > servicestack 插件到将提供静态文件的 Windows 服务?

问题描述

我将 ServiceStack (V5.1.0) 作为 Windows 服务,提供 REST API,没有问题。我想创建一个插件,为任何以 /GUI 开头的路由提供来自特定物理目录的静态文件。

我在这里阅读了“Q: ServiceStack Razor with Multiple SPAs”带有多个 SPAs 的ServiceStack Razor

但这似乎只处理 index.html 之类的单个文件,而且我不仅需要提供物理路径根目录中的文件,还需要提供物理路径子目录中的文件。例如,路由 /GUI/css/site.css 应该为在根目录下的 css 子目录中找到的 site.css 文件提供服务。

我在这里查看了“在 ServiceStack 中映射静态文件目录” https://forums.servicestack.net/t/mapping-static-file-directories-in-servicestack/3377/1 并基于此,尝试覆盖GetVirtualFileSources

public class AppHost : AppSelfHostBase {
   ...
   // override GetVirtualFileSources to support multiple FileSystemMapping.
   // Allow plugins to add their own FileSystemMapping
   public override List<IVirtualPathProvider> GetVirtualFileSources()
   {
     var existingProviders = base.GetVirtualFileSources();
     // Hardcoded now, will use a IoC collection populated by plugins in the future. Paths will be either absolute, or relative to the location at which the Program assembly is located.
     existingProviders.Add(new FileSystemMapping("GUI",@"C:\Obfuscated\netstandard2.0\blazor"));
     return existingProviders;
   }
   ....
}

并在插件模型中使用 FallBackRoute,

[FallbackRoute("/GUI/{PathInfo*}")]
public class FallbackForUnmatchedGUIRoutes : IReturn<IHttpResult>
{
  public string PathInfo { get; set; }
}

但是我不知道如何获取接口方法来将 PathInfo 更改为实现 IVirtualFile 的对象。

public HttpResult Get(FallbackForUnmatchedGUIRoutes request)
{
  // If no file is requested, default to "index.html"" file name
  var cleanPathInfo = request.PathInfo ?? "index.html";

  // Somehow, need to convert the cleanPathInfo into an IVirtualFile, that specifies the correct VirtualPathProvider (indexed by "GUI"")
  // insert here the magic code to convert cleanPathInfo into an object that implements IVirtualFile
  // var cleanVirtualPathInfo = cleanPathInfo as IVirtualFile

  // to make use of ServiceStack enhanced functionality, wrap the cleanVirtualPathInfo in a HttpResult, 
  HttpResult httpresult = new HttpResult(cleanPathInfo,false); // this doesn't compile, because no overload with 2 parameters takes a string as the first parameter, but there is an overload that will take an IVirtualFile object
  return httpresult;
}

有什么建议可以让接口代码返回正确的文件吗?还是一种更好的方法来允许多个插件,每个插件都支持不同的 SPA,基于路由的第一部分?提示、链接、明确的说明 - 欢迎任何和所有!

标签: servicestack

解决方案


您只需要注册一个虚拟文件系统,您不需要创建自己的服务,因为 ServiceStack 的静态文件处理程序会自动返回它在注册的虚拟文件源列表中找到的第一个文件。

如果您希望能够在插件中注册文件映射,您可以将其添加到AddVirtualFileSources插件构造函数中的 AppHost 列表中,例如:

public class GuiPlugin : IPlugin, IPreInitPlugin
{
    public void Configure(IAppHost appHost)
    {
        appHost.AddVirtualFileSources.Add(
          new FileSystemMapping("GUI", appHost.MapProjectPath("~/blazor")));
    }
    public void Register(IAppHost appHost) {}
}

appHost.MapProjectPath()使您可以从 AppHost 的项目内容路径中解析物理文件。然后你可以在你的 AppHost 中注册插件:

public override void Configure(Container container)
{
    Plugins.Add(new GuiPlugin());
}

您的文件/blazor现在应该可以从您注册的路径映射中解析,例如:

/GUI/file.html -> C:\project\path\file.html

请注意,您不需要任何服务,ServiceStack 将自动返回已注册文件映射的静态文件,因此您需要删除[FallbackRoute]已添加的任何内容。


推荐阅读