【问题标题】:Kentico Kontent runtime resolutionKentico Kontent 运行时解析
【发布时间】:2020-05-01 13:16:48
【问题描述】:

我对 kentico kontent 有点问题。基本上,当我调用_deliveryClient.GetItemsAsync<object> 时,即使下面的 json 被带回,我也会得到 null。

{
  "item": {
    "system": {
      "id": "0b9e6cf0-a9aa-422b-9e14-1576adfb6324",
      "name": "Home",
      "codename": "home",
      "language": "default",
      "type": "home",
      "sitemap_locations": [],
      "last_modified": "2020-04-30T17:16:48.706142Z"
    },
    "elements": {
      "header": {
        "type": "text",
        "name": "Header",
        "value": "This is my name"
      },
      "description": {
        "type": "text",
        "name": "Description",
        "value": ".net specialist"
      },
      "background": {
        "type": "modular_content",
        "name": "Background",
        "value": [
          "universe"
        ]
      }
    }
  },
  "modular_content": {
    "universe": {
      "system": {
        "id": "a8898eef-0f4b-4646-af72-c0a1e41ab165",
        "name": "Universe",
        "codename": "universe",
        "language": "default",
        "type": "background",
        "sitemap_locations": [],
        "last_modified": "2020-04-30T17:19:02.9586245Z"
      },
      "elements": {
        "user_vid_or_imag": {
          "type": "multiple_choice",
          "name": "User Vid or Imag",
          "value": [
            {
              "name": "Video",
              "codename": "video"
            }
          ]
        },
        "background_item": {
          "type": "asset",
          "name": "Background Item",
          "value": [
            {
              "name": "Time Lapse Video Of Night Sky.mp4",
              "description": null,
              "type": "video/mp4",
              "size": 2076845,
              "url": "https://preview-assets-us-01.kc-usercontent.com:443/..."
            }
          ]
        }
      }
    }
  }
}

但是,如果我使用凝固物,我会按预期恢复模型。即使对于班级成员来说,这也是一个问题,例如链接的项目。问题是我们有很多模型,所以我们选择使用 Kentico 提供的 ModelGenerator。问题是我们不能告诉生成器不要生成某些对象,因此即使我们只想更新一个模型,它也会覆盖所有内容。所以这意味着我不能进入每个模型并将其更改为某些具体内容,因为这将被覆盖。

文档说应该始终有效,所以这是一个错误吗?还是我在某处犯了错误。

【问题讨论】:

    标签: kentico-kontent


    【解决方案1】:

    您应该始终将model generatorpartial 类结合使用。要通过部分类启用自定义,请使用 --generatepartials true 开关。这将输出如下内容:

    • Article.Generated.cs(将始终重新生成)
        public partial class Article
        {
            public const string Codename = "article";
            public const string TitleCodename = "title";
            public const string BodyCopyCodename = "body_copy";
            public const string RelatedArticlesCodename = "related_articles";
    
            public string Title { get; set; }
            public IRichTextContent BodyCopy { get; set; }
            public IEnumerable<object> RelatedArticles { get; set; }
        }
    
    
    • Article.cs(不存在时生成,不会被生成器覆盖)
        public partial class Article
        {
            // Space for your customizations
            public IEnumerable<Article> ArticlesTyped => RelatedArticles.Cast<Article>();
        }
    

    请随时通过https://github.com/Kentico/kontent-generators-net/issues/new/choose提出代码生成器的改进建议

    您的代码目前无法运行的最可能原因是您尚未注册ITypeProvider 接口的实现。您可以通过将其添加到 DI 容器 (IServiceCollection) 来实现:

    services
        .AddSingleton<ITypeProvider, CustomTypeProvider>();
        .AddDeliveryClient(Configuration);
    

    或将其传递给DeliveryClientBuilder

    CustomTypeProvider customTypeProvider = new CustomTypeProvider();
    IDeliveryClient client = DeliveryClientBuilder
        .WithProjectId("975bf280-fd91-488c-994c-2f04416e5ee3")
        .WithTypeProvider(customTypeProvider)
        .Build();
    

    docs 中所述。您可以通过模型生成器实用程序生成CustomTypeProvider,也可以手动实现它。它应该看起来像这样:

    public class CustomTypeProvider : ITypeProvider
        {
            private static readonly Dictionary<Type, string> _codenames = new Dictionary<Type, string>
            {
                // <CLI type, model codename in Kontent>
                {typeof(Article), "article"}
            };
    
            public Type GetType(string contentType)
            {
                return _codenames.Keys.FirstOrDefault(type => GetCodename(type).Equals(contentType));
            }
    
            public string GetCodename(Type contentType)
            {
                return _codenames.TryGetValue(contentType, out var codename) ? codename : null;
            }
        }
    

    或者,您可以通过以下方式在调用GetItemsAsync() 时指定类型:_deliveryClient.GetItemsAsync&lt;Article&gt;(),但这只会解析第一级类型。任何嵌套模型都是null,因为SDK 不知道如何解决它们(这就是ITypeProvider 的用途)。所以我会避免这种情况。

    【讨论】:

    • 如果我使用 JsonProperty("kontent_field"),是否还需要 ITypeProvider。难道系统不能解决这个问题吗?
    • 是的,ITypeProvider 告诉系统哪种 CLI 类型应该用于哪种 Kentico Kontent 内容类型。 JsonPropertyAttribute 只是确定属性绑定到的 KK 中元素的名称。系统无法推断 CLI 类型,您必须给它一个提示 - 使用 ITypeProvider 或通过 &lt;T&gt; 类型参数。使用ITypeProvider
    • 好的,这就是我所困惑的。很抱歉很顽强:(。只需要理解。所以说我有这个模型类文章{ [JsonProperty("content_authors")] public IEnumarable Authors {get; set;} // is linked item in content } 这里我希望系统能够简单地知道我想要使用的类型是作者。基本上在这一点上我正在做提供者正在做的事情吗?将 CLR 类型(作者)映射到 kontent 代号(content_authors)。这是合乎逻辑吗?如果不支持,是否可以增强?
    • 哦,现在我明白你的意思了。是的,它应该已经以这种方式工作了。如果您查看ModelProvider,您会发现它总是尝试从泛型类型&lt;T&gt; 推断类型,如果不成功,它使用ITypeProvider
    • 好的。那讲得通。非常感谢你的帮助。我刚刚看到了 ModelProvider 代码。现在完全有意义
    猜你喜欢
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    相关资源
    最近更新 更多