我正在创建一个模块,以便我的客户可以将自己的公司电子邮件作为内容进行管理。
我们的想法是避免将人们的真实电子邮件地址放在公共网站上,因此对于网站用户发送电子邮件,我会让Orchard显示表单。没问题。我的问题(见下文)与Orchard如何在信息中心中显示内容项目有关,而不是网站的公共对象部分。
继续前进:
我创建了一个名为EmailAddress的内容类型(请参阅下面的migration.cs)。它基本上只是一个名为CorporateEmailPart的内容部分的内容类型包装器。
我的设置的另一个相关位是驱动程序(请参阅下面的CorporateEmailPartDriver.cs)。我在PluralSight.com上关注了Kevin Kuebler的视频来编写驱动程序。调试显示它工作正常。
使用我模块中的Placement.info文件放置形状。
所以,如果不是......那么一切都会正常工作。
驱动程序正确允许我为我的内容类型的编辑器创建形状,显示正常。
或者更确切地说,显示正常以允许我创建新的EmailAddress。我可以将CorporateEmailPart保存到数据库中。
但是,当我保存新的EmailAddress内容类型或尝试编辑现有内容时,我的EmailAddress编辑器上根本不会显示CorporateEmailPart的字段。
即,在我的POST DriverResult Editor方法中,我返回GET编辑器ContentShape,只显示我的内容类型的CommonPart(即ContentItem的所有者字段)。不显示CorporateEmailPart数据。甚至不是空文本框。
我必须遗漏一些简单的东西,因为其他一切都有效。
但我看不出是什么......!
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents.Extensions;
using Orchard.Data;
using Orchard.Data.Migration;
using Wingspan.CorporateEmails.Models;
namespace Wingspan.CorporateEmails {
public class Migrations : DataMigrationImpl {
public int Create() {
ContentDefinitionManager.AlterTypeDefinition("EmailAddress", builder =>
builder
.WithPart("CommonPart")
.Creatable());
SchemaBuilder.CreateTable("CorporateEmailPartRecord", table =>
table.ContentPartRecord()
.Column<string>("Alias")
.Column<string>("EmailAddress")
.Column<int>("DisplayOrder")
.Column<string>("DisplayTitle")
.Column<bool>("IsDefault"));
ContentDefinitionManager.AlterPartDefinition(typeof(CorporateEmailPart).Name, p => p.Attachable());
ContentDefinitionManager.AlterTypeDefinition("EmailAddress", builder =>
builder
.WithPart(typeof(CorporateEmailPart).Name));
SchemaBuilder.CreateTable("EmailMessageRecord", table =>
table
.Column<int>("Id", col => col.PrimaryKey().Identity())
.Column<int>("CorporateEmailPartRecord_Id")
.Column<string>("Sender")
.Column<string>("Recipient")
.Column<string>("Subject")
.Column<string>("Body")
.Column<string>("TitleAndName")
.Column<string>("Address")
.Column<string>("Telephones"));
return 1;
}
}
}
using System.Collections.Generic;
using System.Web.Routing;
using Orchard;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Data;
using Orchard.Services;
using Wingspan.CorporateEmails.Models;
using Wingspan.CorporateEmails.ViewModels;
using System.Linq;
namespace Wingspan.CorporateEmails.Drivers {
public class CorporateEmailPartDriver : ContentPartDriver<CorporateEmailPart>{
private readonly IRepository<EmailMessageRecord> _repositoryEmailMessage;
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
private readonly RequestContext _requestContext;
private const string TemplateName = "Parts/CorporateEmail";
protected override string Prefix
{
get
{
{ return "CorporateEmail"; }
}
}
public IOrchardServices Services { get; set; }
public CorporateEmailPartDriver(IRepository<EmailMessageRecord> repositoryEmailMessage)
{
_repositoryEmailMessage = repositoryEmailMessage;
}
public CorporateEmailPartDriver(IOrchardServices services, IEnumerable<IHtmlFilter> htmlFilters, RequestContext requestContext) {
_htmlFilters = htmlFilters;
Services = services;
_requestContext = requestContext;
}
protected override DriverResult Display(CorporateEmailPart part, string displayType, dynamic shapeHelper)
{
return ContentShape(TemplateName, () => shapeHelper.Parts_CorporateEmail(CorporateEmailPart: part));
}
//GET
protected override DriverResult Editor(CorporateEmailPart part, dynamic shapeHelper)
{
var model = BuildEditorViewModel(part);
return ContentShape("Parts_CorporateEmail_Edit", () =>
shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
}
//POST
protected override DriverResult Editor(CorporateEmailPart part, IUpdateModel updater, dynamic shapeHelper)
{
updater.TryUpdateModel(part, Prefix, null, null);
var model = BuildEditorViewModel(part);
return ContentShape("Parts_CorporateEmail_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
}
#region Private Utilities
private CorporateEmailEditorViewModel BuildEditorViewModel(CorporateEmailPart part)
{
return new CorporateEmailEditorViewModel
{
Alias = part.Alias,
EmailAddress = part.EmailAddress,
DisplayOrder = part.DisplayOrder,
DisplayTitle = part.DisplayTitle,
IsDefault = part.IsDefault,
EmailMessageSummaries = part.EmailMessages.Select(ue => ue.Summary).ToList()
};
}
#endregion
}
}
任何建议都非常感谢。
答案 0 :(得分:3)
好的,一个头脑清醒的更仔细的调试会话,我发现了这个问题:
在我的驱动程序中构建viewmodel时导致错误:
private CorporateEmailEditorViewModel BuildEditorViewModel(CorporateEmailPart part)
{
return new CorporateEmailEditorViewModel
{
Alias = part.Alias,
EmailAddress = part.EmailAddress,
DisplayOrder = part.DisplayOrder,
DisplayTitle = part.DisplayTitle,
IsDefault = part.IsDefault,
EmailMessageSummaries = part.EmailMessages.Select(ue => ue.Summary).ToList()
};
}
违规行是:
EmailMessageSummaries = part.EmailMessages.Select(ue => ue.Summary).ToList()
原因是使用CorporateEmailPartRecord_Id外键从EmailMessageRecord表检索数据时出现问题。我还没弄明白什么(从来没有使用nHibernate,这是果园使用的),但是这个错误的存在回答了当前的问题。
Orchard工作正常。
事实上,它的效果非常好。
模块中的代码无关紧要。
所以要更加小心你的调试。
Kevin Kuebler的视频是一个很好的果园学习资源。
当您重构某物的名称时,请仔细检查以确保它们已全部更改。
我找到了导致hHibernate错误的原因:伪劣重构。
我最初称之为CompanyEmails项目,但随后重构了所有内容,称之为CorporateEmails。唯一的问题是,我没有重构一切,是吗? EmailMessageRecord模型类上仍有一个CompanyEmailPartRecord_Id字段,而在数据库中,我已将其更改为CorporateEmailRecordPart_Id。所以,只是另一个错误,只是未能正确重构。