Creating a content part in code

Nov 16, 2010 at 9:25 PM

I'm working on a module where I need to store my settings. I'm storing them in a content part called ContactUsSettingsPart.

I've got an Admin controller that is linked from the admin menu. Here is the important part of my Edit settings action method:

var contact = _contactUsService.Get();
if (contact == null) contact = Services.ContentManager.New<ContactUsSettingsPart>(typeof(ContactUsSettingsPart).Name);
var model = Services.ContentManager.BuildEditor(contact);

This is based on the blog admin controller. I'm having trouble with the second line. I needed this because I couldn't pass null to BuildEditor, and contact is null before a user has filled out the form for the first time.

ContentManager.New<ContactUsSettingsPart> throws an InvalidCastException because inside New var part = contentItem.Get<T>() makes part = null.

I think I may have fundamentally got what the ContentManager does quite mixed up, or there is something wrong with my model or data migration. Am I trying to do roughly the right thing, but have made a small mistake, or am I way off the mark?

Coordinator
Nov 16, 2010 at 10:58 PM

Aren't you supposed to give the content type name to New? For settings, that would be "Site". You can find an example of a module exposing site settings in Orchard.Email.Handlers:

Filters.Add(new ActivatingFilter<SmtpSettingsPart>("Site"));
Nov 17, 2010 at 10:18 AM

Thanks Bertrand. That looks like a good example.

I think I've missunderstood a few things. Hopefully that will get me closer to where I want to be.

Developer
Dec 3, 2010 at 3:44 PM
Edited Dec 3, 2010 at 3:47 PM

I have the same problem...

I created a custom part, corresponding record, set activating and storage filters accordingly and created data migrations correctly and still have the InvalidCastException thrown:/ It looks like there's something wrong with the data migrations. Problem exists when creating custom type using parts from the same module (don't know if only in that situation), all created in single Create() data migration method.

I'll check this out once again - some time ago had similar problem, and suddenly it just started to work. I'm using the latest dev source.

Piotr

Developer
Dec 4, 2010 at 3:34 AM

It is weird. I've made no changes in code and it suddenly started to work - no InvalidCastException thrown. Maybe there's some db caching issue, because it started to work after restarting the whole site. I realized that every time I had that issue with InvalidCastException thrown when calling IOrchardServices.ContentManager.New<T>(...) it happened in the same session when I enabled my module with custom type declared in it. Of course the type name and part type provided was correct.

It looks like the content parts are cached (I didn't get deep into the code so I'm not sure how does it work - correct me please if I'm wrong) and the cache is not refreshed from database after enabling a module. I checked the database just after enabling a module and all record tables and type definitions are there. It seems like an issue to me.

Piotr

Coordinator
Dec 4, 2010 at 5:17 AM

Hi Piotr,

Do you use the latest official release (Orchard 0.8) or a recent dev branch?

Can you provide a specific series of steps that leads to the "InvalidCastException" you are running into? Orchard does have a "dynamic compilation" system (documented here: http://orchardproject.net/docs/Orchard-module-loader-and-dynamic-compilation.ashx), and we've noticed that sometimes changes are not detected. We have fixed a few of these issues in the recent dev branch, but we've also added database caching for performance, so it would be good for us to exactly understand the problem you are running into so that we can fix it before the 1.0 release.

Thanks,

Renaud

Developer
Dec 4, 2010 at 3:17 PM

Thanks for the info - now it's way more clearer to me:) Sure. I'll provide the steps to reproduce my case in few hours (I'm currently writing from mobile and it's not much comfortable...)

Cheers, Piotr