Programmatically filling certain content fields

Topics: Customizing Orchard, General, Troubleshooting, Writing modules
Aug 29, 2012 at 3:31 PM
Edited Aug 29, 2012 at 3:32 PM

We have made a custom authentication module and we want to use the Orchard Profile Module so that we can have user profiles. We added some fields on the profile type and we want to fill those fields when someone logs in.

In out authentication module we make the user be able to login, using their credentials from a different system (LDAP for example), when the user does not exist yet in Orchard, it will be created after the validation was successful.

When that user is being created in Orchard, we also want to fill the content fields that we manually added to the profile, but I can't figure out exactly how to do that. I found that I probably have to do something like this:


var orchardUser = this.membershipService.GetUser(user.UserName);
if (orchardUser == null)
	orchardUser = this.membershipService.CreateUser(new CreateUserParams(user.UserName, Guid.NewGuid().ToString(), user.EmailAddress, Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), true));

dynamic dyn = orchardUser;

var newField = new TextField();
newField.Storage = new SimpleFieldStorage();
newField.Value = "Test";


But I don't know what to fill in the parameters of "new SimpleFieldStorage()". I'm not sure if this is even the correct way of doing it, so I'm hoping someone here can help me out.

In my search I came across a similar topic, but his question is a bit different from mine and the answers there don't help me. But someone there does say "Every thing which is done in the UI can be done as a module, or during any event in this module.", so what I'm trying to do does not seem impossible. I also can't imagine it being impossible with an awesome CMS like Orchard.

Aug 29, 2012 at 5:15 PM

You don't have to work with the field storage directly. Instead, you can simply use code like this (since the variable is dynamic):

dynamic dyn = orchardUser;

dyn.ContentItem.ProfilePart.FirstName.Value = "John";

This works because the CreateUser method returns an IUser, which derives from IContent. Each IContent has a ContentItem property, from which you can navigate to all of its attached parts, like ProfilePart. Via these parts, you can navigate to each attached fields of the part. In this example, I assumed you attached a TextField called FirstName to the ProfilePart. TextFields have a Value property, which holds the actual value of the field.

Alternatively, you could use code like this:

dynamic profilePart = orchardUser.As<ProfilePart>();

profilePart.FirstName.Value = "John";

Which is basically the same as the first approach: as long as you have access to a content part, you can easily access the attached content fields if the variable holding the content part is dynamically typed.

Aug 30, 2012 at 7:50 AM

Aha, so it's a lot easier than I thought. This is exactly what I wanted to know, I've tried it out and it works, so thanks a lot for your help :)

Aug 30, 2012 at 2:16 PM

Hmm, now we decided that we also want to add the fields programmatically if they don't exist. Could you give me an example of how to accomplish that? I have tried it by creating a new TextField, but the DisplayName and Name properties don't have setters, so I'm guessing that I have to do it differently.

Aug 30, 2012 at 2:49 PM

To attach content fields to parts, simply inject an IContentDefinitionManager and use it as you would use it from your migrations.

Aug 31, 2012 at 8:12 AM

Yes, why didn't I think of that myself. Anyways, it works. Thanks again :)