Kentico Kontent 运行时解析

Kentico Kontent runtime resolution

我对 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/..."
            }
          ]
        }
      }
    }
  }
}

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

文档说应该总是有效,所以这是一个错误吗?还是我哪里弄错了。

您应该始终将 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<Article>() 但这只会解析第一级类型。任何嵌套模型都将是 null,因为 SDK 不知道如何解析它们(这就是 ITypeProvider 的用途)。所以我会避免这种情况。