【问题标题】:Restrict Metadata for Custom Content-Type in ServiceStack限制 ServiceStack 中自定义 Content-Type 的元数据
【发布时间】:2014-02-07 09:53:28
【问题描述】:

有一些通过

注册的自定义内容类型
ContentTypeFilters.Register(contentType, StreamSerializer, StreamDeserializer);

并希望限制元数据页面上路线的显示。这些内容类型仅适用于限制为InternalNetworkAccess 的请求 dto。只是希望不要用不必要的东西把面向公众的元数据页面弄得一团糟。

对于内置的 contentTypes,您只需将其添加到 RestrictAttribute 下。是否有类似的功能隐藏在其他地方但尚未记录在案的自定义类型?

看起来也许我可以自定义 MetadataFeature 插件,并可能限制哪些请求 dto 获取内容类型,哪些不获取。但我最近才注意到这一点,并且不确定结果会如何(也不知道如何删除 MetadataFeature 并安全地替换为我自己的)。

本质上,我只希望此自定义 contentType 在元数据页面上可见,用于限制为 InternalNetworkAccess 的 requestDtos。 有什么想法吗?

编辑:
我还在使用 ServiceStack v3,但仍然对 v4 的可能性感兴趣。

【问题讨论】:

  • 所以你不能在使用自定义 contentType 的方法上使用[Restrict(AccessTo = RequestAttributes.Localhost, VisibilityTo = RequestAttributes.Localhost)]
  • Dto 已经受到限制。因此,当我通过公共地址访问我的页面时,我只看到“外部”Dtos,而当我通过私有网络访问它时,我在元数据页面上看到“外部”+“内部网络访问”Dtos。当您注册显然出现在每个元数据页面上的自定义内容类型时。我真的只需要为 InternalNetworkAccess Dtos 显示自定义内容类型。就像我要关闭 ServiceStack 中的 SOAP 功能一样,任何 SOAP 内容都不会出现在元数据页面中。除了自定义类型,我也想做同样的事情。
  • 您使用的是 v3 还是 v4?
  • v3.它在 v4 中有能力吗?
  • 我已经在 v4 中测试过,它确实有效。

标签: c# servicestack metadata content-type


【解决方案1】:

您可以使用阻止您的自定义类型出现在元数据中。

如果您的内容类型是application/yourformat,您将使用:

SetConfig(new HostConfig {
    IgnoreFormatsInMetadata = new HashSet<string>{ "yourformat" }
});

【讨论】:

  • 这将部分解决问题,但随后会完全忽略它们。我想我会尝试使用生成 GetHandlerForPathParts 的 MetadataFeature 插件。似乎我应该能够让它在某些点忽略内容类型。
  • 在 v3 中也可以。
  • @Nicholi Cool,我不知道。您能否指出显示 v3 忽略格式的文档或源代码?
  • 我实际上只是注意到它正在通过 EndpointHostConfig 进行搜索。它也以相同的属性名称 IgnoreFormatsInMetadata 调用。 github.com/ServiceStack/ServiceStack/blob/v3/src/ServiceStack/…
  • 我发现您实际上可以在不重新编译所有 ServiceStack 的情况下更多地自定义元数据页面(耶),这样您就可以选择为哪些 RequestDTO 显示哪些自定义 ContentType。明天某个时候将其添加为答案。只需要从 ServiceStack 复制一些内部类。
【解决方案2】:

所以我发现处理元数据请求的初始类是ServiceStack.MetadataFeatureIPlugin。这实际上控制了底层示例请求/响应页面(针对每种内容类型)以及整个“/元数据”页面的布局。

从这个小片段

private IHttpHandler GetHandlerForPathParts(String[] pathParts)
{
    var pathController = string.Intern(pathParts[0].ToLower());
    if (pathParts.Length == 1)
    {
        if (pathController == "metadata")
            return new IndexMetadataHandler();

        return null;
    }
    ...
}

是发送实际“/元数据”页面的处理程序的位置。在方法中的IndexMetadataHandler 的父类BaseSoapMetadataHandler 内部,您不会找到每个请求的ContentTypes 的实际构造

protected override void RenderOperations(HtmlTextWriter writer, IHttpRequest httpReq, ServiceMetadata metadata)

创建了一个内部控制 (IndexOperationsControl),它有一个方法 RenderRow,这是所有魔法发生的地方。在这里,您会看到对“操作”(现在是 Dto 的另一个词)和 ContentType 之类的一些明显检查

if (this.MetadataConfig.IsVisible(this.HttpRequest, EndpointAttributesExtensions.ToFormat(config.Format), operation))

所以所有需要做的就是创建自己的IndexOperationsControl 类并在RenderRow 方法中处理config.Format。 config.Format 就是您注册的 ContentType 中正斜杠之后的所有内容,因此如果它是“application/x-my-type”,则 config.Format 字符串将为“x-my-type”。 Operation 就是 RequestDto 的类名。不幸的是,由于该类被标记为内部,这意味着您几乎必须完全复制它而不是使用继承。为了与默认生成页面的方式保持 1:1 的相似性,您还需要内部类 ListTemplateTableTemplateXsdTypes(用于构造 IndexOperationsControl)的副本。

在此之后,您只需要自己的IndexMetadataHandler 和重载RenderOperations(您可以使用继承)来创建新的IndexOperationsControl。我们还需要我们自己的MetadataFeature 等效IPlugin,但我们需要完全复制它并修改GetHandlerForPathParts 以返回我们的新IndexMetadataHandler。唯一要做的就是删除 MetadataFeature 并添加我们自己的插件。

    // removing default metadata feature
    Plugins.RemoveAll(x => x is MetadataFeature);
    // add our custom one
    Plugins.Add(new CustomMetadataFeature());

瞧,您可以按照 RequestDto 的要求准确显示自定义 ContentType。

【讨论】:

    猜你喜欢
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2011-09-10
    • 1970-01-01
    • 2013-06-13
    • 2020-09-18
    • 1970-01-01
    相关资源
    最近更新 更多