loading...

Using Glass Mapper To Create New Content In Sitecore With Fluent Configuration

kmac23va profile image Kenneth McAndrew ・2 min read

I found myself asking and answering my own question on StackExchange today (by the way, don't be afraid to do that if you find a good answer, and also be ready for a better answer to possible pop up!):

My typical build-out for Glass and fluent config is to use an interface and map file (using SitecoreGlassMap) for modeling, but I know if I need to use the model to add data to Sitecore I can't use the interface type. From a best practice standpoint, if my model is…

As an opening summary, my typical setup for using Glass with Sitecore is to use fluent configuration. So if I have a model like this:

public interface ITemplate {
  string Field { get; set; }
}

Then I would create this mapping entry to link up the POCO to Sitecore:

public class TemplateMap : SitecoreGlassMap<ITemplate> {
  public override void Configure() =>
    Map(config => {
      config.Field(f => f.Field).FieldName("Field");
    });
}

And then you can retrieve the item with code similar to this (note that SitecoreService needs to be replaced with an appropriately arranged call that establishes the service):

ITemplate item = SitecoreService.GetItem<ITemplate>(new GetItemByIdOptions(Guid.Parse("{}")));

So that's all good. But when you need to add content to Sitecore for any reason, you can't use the interface and instead need a standard class:

public class Template : ITemplate {
  public string Field { get; set; }
}

Now if you've done the Glass training, you'll see in the section on creating items that they use the attribute mapping. That's easy enough, but how does it work with the fluent configuration? Right now, the map goes to the interface only. So do we have to use attribute mapping, or make a separate map?

Turns out it's pretty easy. All you have to do is change the map to use the concrete class:

public class TemplateMap : SitecoreGlassMap<Template> {
  public override void Configure() =>
    Map(config => {
      config.Field(f => f.Field).FieldName("Field");
    });
}

Now if you use the GetItem call from earlier, it still works. And then if you need to create a new item as a subitem to that, this code will work:

ITemplate newItem = new Template {
  Name = "Test Item"
};

using (new SecurityDisabler()) {
  ITemplate createOrg = SitecoreService.CreateItem<ITemplate>(new CreateByModelOptions {
    Model = newItem,
    Parent = item
  });
}

So just one extra class and changing the class used in the mapping call, and you're good to go! I'd personally advise only bringing in concrete classes when you have to do these operations, since the interface will work perfectly fine if you're just doing read operations.

Posted on by:

kmac23va profile

Kenneth McAndrew

@kmac23va

Over 20 years in web development, from HTML (remember image maps and frames?) to classic ASP to ASP.NET to .NET CMSes.

Discussion

pic
Editor guide