在Orchard CMS中区分内容部件驱动程序中的创建和更新

时间:2014-02-13 06:15:03

标签: c# asp.net-mvc orchardcms-1.7

我想根据Actions使用不同的ViewModel对象提供不同的视图。这可以在传统的ASP.NET MVC范例中实现。

[HttpGet]
public ActionResult Create() {
    return View(new CreateViewModel()); //this serves Create.cshtml View
}

[HttpGet, ActionName("Create")]
public ActionResult CreatePOST(CreateViewModel viewModel) {
    if (!ModelState.IsValid) {
        return View(viewModel); //if error, re-serve Create.cshtml View
    }

    // Create new model into database

    return RedirectToAction("Index");
}

[HttpGet]
public ActionResult Edit(int Id) {
    var model = RetriveModel(Id);
    var viewModel = new EditViewModel { Id = model.Id, Name = model.Name };
    return View(viewModel); //this serves Edit.cshtml
}

[HttpPost, ActionName("Edit")]
public ActionResult EditPOST(EditViewModel viewModel) {
    if (!ModelState.IsValid) {
        return View(viewModel); //if error, re-serve Edit.cshtml View
    }

    // Update model in database

    return RedirectToAction("Index");
}

如何对Orchard内容部分执行相同的操作?似乎 ContentPartDriver 中可覆盖的编辑器方法将创建和更新操作融合在一起。如何判断方法是创建还是更新?像

这样的东西
// GET
protected override DriverResult Editor(CustomContentPart part, dynamic shapeHelper) {
    if (IsNewRecord) {
        return ContentShape("Parts_CustomContentPart_Create" () =>
            shapeHelper.EditorTemplate(TemplateName: "Parts/CreateTemplate", Model: new CreateViewModel(), Prefix: Prefix)
        );
    } else {
        return ContentShape("Parts_CustomContentPart_Edit" () =>
            shapeHelper.EditorTemplate(TemplateName: "Parts/EditTemplate", Model: BuildEditViewModel(part), Prefix: Prefix)
        );
    }
}

// POST
protected override DriverResult Editor(CustomContentPart part, IUpdateModel updater, dynamic shapeHelper) {
    object viewModel;
    if (IsNewRecord) {
        viewModel = new CreateViewModel();
    } else {
        viewModel = new EditViewModel();
    }

    update.TryUpdateModel(viewModel, Prefix, null, null);
    return Editor(part, shapeHelper);
}

我是Orchard的初学者,仍在学习如何处理Orchard的事情。请原谅我,如果我的问题太微不足道了。

2 个答案:

答案 0 :(得分:1)

检查内容项ID,如果它为null,或者可能为0,我忘了,那么您正在创建内容项。如果它确实有值,则表示您正在编辑。您也可以在视图中使用它,非常方便。

如果您需要在创建/更新时调用自定义功能,那么您可以考虑使用处理程序方法吗?

因此在您的零件处理程序中添加类似

的内容
OnCreated<MyPart>((ctx, part) => CreateItems(part));

其中CreateItems是一个以零件作为参数的方法。您可以加入大量内容项目事件,文档中有一个整齐的列表:http://docs.orchardproject.net/Documentation/Understanding-content-handlers

与往常一样,请查看源代码以获取其使用的良好示例。

修改

显然检查null id不起作用,我检查了一些我使用过的模块,并使用了以下检查:

Model.ContentItem.VersionRecord == null || !Model.ContentItem.VersionRecord.Published

答案 1 :(得分:1)

虽然已经提出并回答了这个问题,但只是考虑发布我的发现,以便我以后可以找到它。

当内容项尚未创建时,

ContentItem.Id确实为0。例如,当您即将创建新的页面时,ContentItem.Id == 0。现在只需点击保存按钮而不填写表单,验证将失败,因为未提供必填字段标题,我们将返回相同的视图有错误。由于验证失败,从技术上讲,我们还没有考虑要创建的内容项。但是,此时Orchard已将其视为现有内容项。 Orchard甚至从数据库中获取并增加了内容项记录表(Orchard_Framework_ContentItemRecord)的Identity计数器,并将其作为Id分配给内容项。

Orchard甚至连接了所有版本记录,使其成为一个完整的内容项目。所有这些都是在创建过程中验证失败并且面临被完全丢弃的可能性的内容项。 Orchard唯一没有做的就是将它插入数据库(此时它只驻留在内存中)。因此,除了在数据库中检查内容项并查看内容项是否真的存在之外,实际上没有其他方法可以判断内容项是否是现有的一个或一个内容项。

var contentItemRepository = _workContext.Resolve<IRepository<ContentItemRecord>>();
var contentItemRecord = contentItemRepository.Get(Model.ContentItem.Id);

if (contentItemRecord == null) {
    isNew = true;
}

或者我们也可以使用IContentManager做同样的事情

var contentManager = Model.ContentItem.ContentManager;
var contentItem = contentManager.Get(Model.ContentItem.Id, VersionOptions.AllVersions);

if (contentItem == null) {
    isNew = true;
}

<小时/> 修改

显然我说得太早了。当我在上面说过Orchard还没有将内容项插入到数据库中并且它仍然驻留在内存中时,它实际上已经在数据库中,在一个尚未提交的事务中。在上面验证失败的情况下,事务将在最后回滚。上述代码的正确性取决于它的执行时间。如果在取消并回滚事务之前执行该事务,则内容项仍在数据库中,并且不会产生准确的结果。如果它是在事务回滚后执行的(例如在视图中),那么它将按预期运行。

Orchard如何处理内容项创建可以在Orchard.Core.Contents.Controllers.AdminController.CreatePOST(string, string, Action<ContentItem>)

中看到
_contentManager.Create(contentItem, VersionOptions.Draft);

var model = _contentManager.UpdateEditor(contentItem, this);

if (!ModelState.IsValid) {
    _transactionManager.Cancel();
    return View(model);
}

在将内容项送入IContentManager.UpdateEditor()进行验证之前,首先创建了内容项。

<小时/> 的更新

提起了一个错误 https://github.com/OrchardCMS/Orchard/issues/6534