【问题标题】:servicestack plugin to a Windows Service that will serve static files?servicestack 插件到将提供静态文件的 Windows 服务?
【发布时间】:2018-05-18 12:28:07
【问题描述】:

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

我在这里 ServiceStack Razor with Multiple SPAs 阅读了“Q:ServiceStack Razor with Multiple SPAs”

但这似乎只处理像 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


    【解决方案1】:

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

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

    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]

    【讨论】:

    • 谢谢!这回答了我原来的问题。在实现它时,我发现提供的解决方案在路径的第一部分是区分大小写的。有没有办法添加一个对“GUI”字符串不区分大小写的新 FileSystemMapping。也就是说,它会用于/GUI、/gui、/Gui、/gUi 等?
    • @BillHertzing 我在this commit 中使 FileSystemMapping 别名不区分大小写,此更改可从 v5.1.1 开始,现在为 available on MyGet
    • 谢谢你,做得非常好。我将 ServiceStack MyGet 提要添加到我的 NuGet 包管理器中,VS 立即通知我的项目引用的所有四个 SS 程序集都有可用的更新。我通过点击几下更新了它们,重建并验证了 FileSystemMapping 别名现在确实不区分大小写。感谢您的响应远远超出平时。
    猜你喜欢
    • 2012-08-20
    • 2020-02-21
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多