Orchardcms Orchard CMS:从外部数据源创建内容项

Orchardcms Orchard CMS:从外部数据源创建内容项,orchardcms,orchardcms-1.9,Orchardcms,Orchardcms 1.9,在Orchard CMS中,我有一个从外部数据源提取数据并将数据加载到Orchard内容部分的服务。该部件有一个迁移,将其与标题部件焊接在一起,我有一个路由,以便通过URL命中我的控制器: 我使用一个控制器通过一个URL访问该项目,很像博客部分控制器。但是我不能表演我的角色。。。 博客控制器执行以下类似操作: var asset = _assetService.Get(1234); if (asset == null) return HttpNotFound(); va

在Orchard CMS中,我有一个从外部数据源提取数据并将数据加载到Orchard内容部分的服务。该部件有一个迁移,将其与标题部件焊接在一起,我有一个路由,以便通过URL命中我的控制器:

我使用一个控制器通过一个URL访问该项目,很像博客部分控制器。但是我不能表演我的角色。。。 博客控制器执行以下类似操作:

    var asset = _assetService.Get(1234);
    if (asset == null) return HttpNotFound();

    var model = _services.ContentManager.BuildDisplay(asset); 

    return new ShapeResult(this, model);
private readonly IAssetService _assetService;

public MyController(IShapeFactory shapeFactory, IAssetService assetService) {
    _assetService = assetService;
    Shape = shapeFactory;
}

public dynamic Shape { get; set; }

public ActionResult MyAction(int assetId) {
    var asset = _assetService.Get(1234);
    if (asset == null) return HttpNotFound();

    // the shape factory can call any shape (.cshtml) that is defined
    // this method assumes you have a view called SomeShapeName.cshtml
    var model = Shape.SomeShapeName(asset);

    return new ShapeResult(this, model);
}
但如果我这样做,“BuildDisplay”方法将查找asset.ContentItem,但这是空的,尽管我的部件是从“ContentPart”派生的


我需要做什么才能显示我的数据

如果我理解正确,您试图只显示一部分内容,而不是整个内容项

要显示单个形状,可以执行以下操作:

    var asset = _assetService.Get(1234);
    if (asset == null) return HttpNotFound();

    var model = _services.ContentManager.BuildDisplay(asset); 

    return new ShapeResult(this, model);
private readonly IAssetService _assetService;

public MyController(IShapeFactory shapeFactory, IAssetService assetService) {
    _assetService = assetService;
    Shape = shapeFactory;
}

public dynamic Shape { get; set; }

public ActionResult MyAction(int assetId) {
    var asset = _assetService.Get(1234);
    if (asset == null) return HttpNotFound();

    // the shape factory can call any shape (.cshtml) that is defined
    // this method assumes you have a view called SomeShapeName.cshtml
    var model = Shape.SomeShapeName(asset);

    return new ShapeResult(this, model);
}
!!注:
这不会触发部件的(显示)驱动程序,它只返回具有给定模型的.cshtml

,通过让我的部件从ContentPart派生,我可以使用以下控制器方法:

private readonly IAssetService _assetService;
private readonly IOrchardServices _services;

public MyController(IShapeFactory shapeFactory, IAssetService assetService, IOrchardServices services) {
    _assetService = assetService;
    _services = services;
    Shape = shapeFactory;
}

public dynamic Shape { get; set; }

public ActionResult MyAction(int assetId) {
    var asset = _assetService.Get(1234);
    if (asset == null) return HttpNotFound();

    // this method assumes you have a view called Parts.Asset.cshtml (see the AssetPartDriver)
    var model = _services.ContentManager.New("Asset");
    var item = contentItem.As<AssetPart>();
    item.Populate(asset) // Method that just populates the service loaded object into the ContentPart

    return new ShapeResult(this, _services.ContentManager.BuildDisplay(item));
}
这些附加零件尚未使用,但可以在创建过程中填充,并使用放置文件单独显示。
这是我努力实现的第一步

你的_assetService.Get()做什么?您的资产是内容类型吗?该资产源自ContentPart。(理论上,我可以创建一个ContentItem,它使用这个部分和其他部分焊接在一起)。第一个阶段是获取一个ContentPart(从外部源填充)以显示在页面上……然后添加其他部分(在代码中),使其成为Orchard内容项,我不确定你是否可以在一个单独的部分上使用
BuildDisplay
,这是一个问题-从内容部分获得内容的正确方式是什么-到成形展示?你为什么坚持要把它作为一部分?零件不得在内容项之外使用。使用形状不需要零件。它看起来像你d通过控制器的动作创建一个形状,让你的生活轻松多了。这很好,理想情况下是的,我想把它作为一个内容项-基本上我只想把它作为一个部分-但它的数据来自外部来源。就功能而言,我希望它是一个部分-可以焊接到其他部分(预连接到代码中,例如到标题,自动路由部分)以生成内容项尝试此方法-查找Id属性(从ContentPart派生的属性)-它没有,也没有setter…它在哪里搜索Id?我假设您的_assetService是您自己的实现:var model=Shape.Parts\u Assets\u Asset(Asset);它调用ShapeFactory.Create并遍历所有属性——因为我的部件是从ContentPart派生的,所以它会查找ContentPart.Id(DefaultShapeFactory第108行)Ahh。如果我的部分不是从ContentPart派生的,那么它就可以工作!这是一个好的开始。但这也意味着我不能从它和任何其他ContentPart创建ContentItem。。。
public class Migrations : DataMigrationImpl
    {
        public int Create()
        {
            ContentDefinitionManager.AlterTypeDefinition("Asset", cfg => cfg
                .WithPart("AssetPart")
                .WithPart("AutoroutePart", builder => builder
                    .WithSetting("AutorouteSettings.AllowCustomPattern", "True"))
                .Listable()
                .Securable()
                .Creatable(false));

            ContentDefinitionManager.AlterPartDefinition("AssetPart", part => part
                .WithDescription("A part that contains details of an individual Web Service loaded asset."));
            return 1;
        }
    }