反序列化媒体字段在 Piranha CMS 中失败

Deserializing Media field fails in Piranha CMS

为 'headless' 场景修改 Piranha:我将 api 分离到它自己的 REST API 中,并将 MVC 分离到它自己的 UI 中调用 REST API。大多数情况下它运作良好,但现在是一个障碍。我的 REST API 序列化来自 Piranha api 的结果,而我的 MVC web 将其反序列化为 Piranha StandardPage 类型。这适用于除 Media 之外的所有字段,它始终为空。使用 newtonsoft.Json.

Media 属性 在 Piranha.Extend.Fields.MediaFieldBase 中用 内部设置 定义,这解释了为什么我不能' t反序列化到它。所以我在 Media 属性 中添加了一个 [JsonProperty] 属性。一旦我这样做了,媒体字段就被 MVC 正确地反序列化了,并且图像出现了。

但后来我发现这破坏了其他东西:在管理器中,当我尝试保存带有英雄图像的页面时,保存按钮旋转,停止,就好像它成功了,但吐司从未出现说成功。我为 Microsoft.AspNetCore.Mvc.Infrastructure 设置了调试日志记录,发现发生这种情况时出现模型状态错误:

dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
      Executed controller factory for controller Piranha.JA.Manager.Controllers.PageApiController (Piranha.JA.Manager)
dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter[1]
      The request has model state errors, returning an error response.
dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
      Request was short circuited at action filter 'Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter'.

对于大多数操作,我可以调试到 PageApiController,但是当 Save 执行 none 时,断点被命中。

我也试过只从集合中删除内部访问器(并删除 [JsonProperty])并得到相同的行为:可以反序列化 Media ok 但试图用英雄保存页面来自经理的模型状态错误。

如果我们能解决这个问题,很想写一些关于如何无头的文档。

我们已经调试了几天了,有人可以帮忙吗?

我在 Piranha CMS github 上发布了这篇文章,其中一位作者 Hakan Edling 在短短几个小时内做出了回复:

"The root issue is that when a new item is selected in the manager in the media picker, the media model that is assigned contains a formatted string size "xxx kb”。当 ASP.NET 试图将其反序列化为 long 时失败。 因此,为基于媒体的字段更改 .vue 组件中的以下行:

this.model.media = media;

this.model.media = {
    id: media.id,
    folderId: media.folderId,
    type: media.type,
    filename: media.filename,
    contentType: media.contentType,
    publicUrl: media.publicUrl,
};

解决了 Media 属性 为 public 时管理器中的序列化错误。我会将此修复推送到新分支,以便您进行测试。"

不久之后, "Please test with the branch https://github.com/PiranhaCMS/piranha.core/tree/features/make-mediafield-media-public"

我仍然必须将 [JsonProperty] 属性添加到 MediaFieldBase class 中的媒体字段,这样我的解串器才能访问内部设置方法。 Hakan 的修复使得此属性不会破坏管理器。

感谢您的快速回复哈坎,你太棒了!

在我推送的分支中,我实际上将访问器更改为 public,因此您不需要额外的属性。这个也合并到master,8.3发布。

此致