我正处于开发新模块的早期阶段。
其中大部分是根据模型等进行布局的。还有所有设置的迁移,我的数据库现在有我的模块的表。
我在致电ContentManager.New<myPart>
时遇到以下错误,并希望得到一些帮助。
错误是这样的:
An unhandled exception has occurred and the request was terminated. Please refresh the page. If the error persists, go back
Specified cast is not valid.
System.InvalidCastException: Specified cast is not valid.
at Orchard.ContentManagement.ContentCreateExtensions.New[T]
(IContentManager manager, String contentType)
触发异常的代码块是:
public static T New<T>(this IContentManager manager, string contentType) where T : class, IContent {
var contentItem = manager.New(contentType);
if (contentItem == null)
return null;
var part = contentItem.Get<T>();
if (part == null)
throw new InvalidCastException();
return part;
}
以下是我的模块中与我正在努力的操作相关的各个部分:
ContentPart
public class GoogleMapsSettingsPart : ContentPart<GoogleMapsSettingsPartRecord>
{
public string ApiKey {
get { return Record.ApiKey; }
set { Record.ApiKey = value; }
}
}
ContentPartRecord
public class GoogleMapsSettingsPartRecord : ContentPartRecord
{
public virtual string ApiKey { get; set; }
}
处理程序
public GoogleMapsSettingsPartHandler(IRepository<GoogleMapsSettingsPartRecord> repository)
{
Filters.Add(StorageFilter.For(repository));
}
此表的迁移
// Settings Table
SchemaBuilder.CreateTable("GoogleMapsSettingsPartRecord", table => table
.ContentPartRecord()
.Column("ApiKey", DbType.String, c => c.WithLength(60))
);
此模型的控制器中的一些代码等
public AdminController(IContentManager contentManager, IShapeFactory shapeFactory, IServiceLocatorService serviceLocatorService, INotifier notifier)
{
_contentManager = contentManager;
_serviceLocatorService = serviceLocatorService;
_notifier = notifier;
Shape = shapeFactory;
T = NullLocalizer.Instance;
}
/// <summary>
/// Display Settings
/// </summary>
/// <returns></returns>
public ActionResult Settings()
{
var settings = _serviceLocatorService.GoogleMapsSettings;
var editor = CreateSettingsEditor(settings);
var model = _services.ContentManager.BuildEditor(settings);
return View((object)model);
}
最后 - 我的电话会抛出此异常的服务
private GoogleMapsSettingsPart _settings;
public GoogleMapsSettingsPart GoogleMapsSettings
{
get {
if (_settings == null)
{
_settings = _contentManager.Query<GoogleMapsSettingsPart, GoogleMapsSettingsPartRecord>().List().FirstOrDefault();
if (_settings == null)
{
_settings = _contentManager.New<GoogleMapsSettingsPart>("GoogleMapsSettings");
}
}
return _settings;
}
}
发生异常的实际行是_settings = _contentManager.New<GoogleMapsSettingsPart>("GoogleMapsSettings");
我尝试过各种各样的东西代替“GoogleMapsSettings”,但没有任何工作。
我很确定在这一点上它很简单,虽然这样可以避开我......我对Orchard的知识有限,难以理解我
任何帮助将不胜感激:)
答案 0 :(得分:2)
抛出异常是因为您的内容类型没有指定要获取的部分。
_contentManager.New<GoogleMapsSettingsPart>("GoogleMapsSettings");
此方法调用会创建类型为GoogleMapSettings
的新内容项,并将内容项设为GoogleMapsSettingsPart
。但是,GoogleMapSettings
内容类型似乎没有GoogleMapsSettingsPart
。这就是异常被抛到这里的原因。
var part = contentItem.Get<T>();
if (part == null)
throw new InvalidCastException();
您必须将部件动态附加到您的内容类型,或者在迁移中执行(或者在管理员中手动添加,但这不是一个好主意)。您的迁移应该如下所示。
this.ContentDefinitionManager.AlterTypeDefinition("GoogleMapsSettings",
alt => alt
.WithPart("GoogleMapsSettingsPart");
答案 1 :(得分:0)
好的,所以我修好了......
我对Orchard如何运作的理解仍处于学习阶段。
对于这个特定的操作,我不想在管理员中有一个内容类型 - 虽然不确定为什么在添加ContentType后它仍然无效......
无论如何,将下面的行添加到我的处理程序中可以完成剩下的工作。我相信它实际上是在创建一个临时类型,因此系统中不需要它。
public GoogleMapsSettingsPartHandler(IRepository<GoogleMapsSettingsPartRecord> repository)
{
Filters.Add(new ActivatingFilter<GoogleMapsSettingsPart>("GoogleMapsSettings"));
Filters.Add(StorageFilter.For(repository));
Filters.Add(new TemplateFilterForRecord<GoogleMapsSettingsPartRecord>("GoogleMapsSettings", "Parts/GoogleMapsSettings"));
}
答案 2 :(得分:0)
我得到了同样的错误,但在我的情况下,迁移类的一切都很好。 原因是不幸的合并,它删除了我的驱动程序类。 只需看看这个ContentPartDriverCoordinator类的Activating方法代码。在我的情况下,我的内容部分没有partInfo,结果部分变成了ContentPart,因此强制抛出异常
var partInfos = _drivers.SelectMany(cpp => cpp.GetPartInfo()).ToList();
foreach (var typePartDefinition in contentTypeDefinition.Parts) {
var partName = typePartDefinition.PartDefinition.Name;
var partInfo = partInfos.FirstOrDefault(pi => pi.PartName == partName);
var part = partInfo != null
? partInfo.Factory(typePartDefinition)
: new ContentPart { TypePartDefinition = typePartDefinition };
context.Builder.Weld(part);
}