Разрешение во время выполнения Kentico Kontent - PullRequest
0 голосов
/ 01 мая 2020

У меня проблемы с Кентико Контентом. В основном, когда я звоню _deliveryClient.GetItemsAsync<object>, я получаю нулевое значение, даже если приведенное ниже значение json возвращается.

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

Однако, если я использую конкремент, я получаю модель обратно, как и ожидалось. Это проблема даже для членов класса, например связанных элементов. Проблема в том, что у нас много моделей, поэтому мы решили использовать предоставляемый ModelGenerator kentico. Дело в том, что мы не можем сказать Генератору не генерировать некоторые объекты, поэтому он будет перезаписывать все, даже если мы хотим обновить только одну модель. Таким образом, это означает, что я не могу go войти в каждую модель и изменить ее на какой-то конкретный, потому что он будет перезаписан.

В документации сказано, что это должно работать всегда, так что это ошибка? или я где-то ошибаюсь.

1 Ответ

2 голосов
/ 03 мая 2020

Вы всегда должны использовать генератор моделей в сочетании с классами partial. Чтобы включить настройку с помощью частичных классов, используйте переключатель --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();

, как описано в документы . Вы можете сгенерировать 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>(), но это разрешит только тип 1-го уровня. Любые вложенные модели будут null, потому что SDK не будет знать, как их разрешать (для этого ITypeProvider). Так что я бы избежал этого.

...