November Happy Hour will be moved to Thursday December 5th.

How to add meta field to Mediachase.Commerce.Customers.CustomerAddress object programmatically?

Vote:
 

Hi,

Help me please to add metafield to CustomerAddress object (Mediachase.Commerce.Customers.CustomerAddress). Version of Mediachase.Commerce is 7.5.409.0.

I have added metafields for other objects with: MetaField.Create method of Mediachase.MetaDataPlus.Configurator.MetaClass.

But I cannot find corresponding metaclass for Mediachase.Commerce.Customers.CustomerAddress. Also I am not sure that addition of metafiled should be done via MetaDataPlus. 

Could you clarify the right way to do it programmatically?

#113188
Nov 14, 2014 13:32
Vote:
 

Guys, I would vey appreciate if someone can help as soon as possible - I need to implement it right now.

#113212
Nov 15, 2014 12:01
Vote:
 

Hi,

Hopefully this is not too late for you. But's here the pseudo code you can use:

var mc= DataContext.Current.MetaModel.MetaClasses["Address"];

using (MetaFieldBuilder builder = new MetaFieldBuilder(mc))

{

 builder.CreateText("NewField", "{Customer:Address_mf_NewField}", true, 64, false);

builder.SaveChanges();

}

Regards.

/Q

#113233
Edited, Nov 17, 2014 4:06
Vote:
 

Hi Quan Mai!

Thank you for the answer! Yes, you are still in time.

Could you help me to initialize module manifest also please?

I am trying to add the field on application start event in my .NET MVC application like this:

private static void AddMetaFieldsToOrderAddressClassIfNeeded()
{
//init context
var connectionString = ConfigurationManager.ConnectionStrings["EcfSqlConnection"].ConnectionString;
DataContext.Current = new DataContext(connectionString);

//get metaclass
var mc = DataContext.Current.MetaModel.MetaClasses[CustomerAddress.ClassName /*metaclass name*/];

//TODO: check that field doesn't already exist
var changeTrackingManifest = new ModuleManifest() { }; //ModuleManifest.Load(path-???)
ModuleManager.Activate(mc, changeTrackingManifest);
using (var builder = new MetaFieldBuilder(mc))
{
builder.CreateText("Address_AddressCompanyName", "{Customer:Customer:Address_mf_Address_AddressCompanyName}", true, 100, false);
builder.SaveChanges();
}
}

But now it throws exception:

Module is not installed
Parameter name: manifest

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentException: Module is not installed
Parameter name: manifest

on ModuleManager.Activate(mc, changeTrackingManifest);

#113266
Edited, Nov 17, 2014 14:05
Vote:
 

Initialized changeTrackingManifest by this code:

var changeTrackingManifest = ChangeTrackingManager.CreateModuleManifest();

looks like it works.

Quan Mai, could yolu please comment why do I need to write this code:

var changeTrackingManifest = ChangeTrackingManager.CreateModuleManifest();
if (!ModuleManager.IsModuleActivated(mc, changeTrackingManifest))
{
ModuleManager.Activate(mc, changeTrackingManifest);
}

and do I need to deactivate the module after addition of the metafield?

Also sometimes I got exception "Module has been already activated.", but I added check:

//prepare
var changeTrackingManifest = ChangeTrackingManager.CreateModuleManifest();
if (!ModuleManager.IsModuleActivated(mc, changeTrackingManifest))
{
ModuleManager.Activate(mc, changeTrackingManifest);
}

Is it correct?

#113268
Nov 17, 2014 15:23
Vote:
 

I guess you could make a shortcut and skip the ChangeTrackingManager, and instead check the field for existance directly on the metaclass? That's how we do it at least ;)

#113281
Nov 17, 2014 23:37
Vote:
 

Anatoli Miazhenny : No, you can remove that line related to ModuleManager, I made a mistake when copy the code - I don't think it's necessary here. 

Regards.

/Q

#113282
Nov 18, 2014 7:09
Vote:
 

Thank you guys, the issue is finally resolved.

The final version :)


private static void AddTextFieldToMetaclassAlt(string metaClassName, string fieldName, bool isNullable, int maxLength, bool isUnique)
{
//init context
if (DataContext.Current == null)
{
var connectionString = ConfigurationManager.ConnectionStrings["EcfSqlConnection"].ConnectionString;
DataContext.Current = new DataContext(connectionString);
}

//get metaclass
var mc = DataContext.Current.MetaModel.MetaClasses[metaClassName];

//check that field doesn't already exist
if (!mc.Fields.Contains(fieldName))
{
//add field
using (var builder = new MetaFieldBuilder(mc))
{
builder.CreateText(fieldName, string.Format("{{Customer:Customer:Address_mf_{0}}}", fieldName), isNullable, maxLength, isUnique);
builder.SaveChanges();
}
}
}

And the method call:

AddTextFieldToMetaclassAlt(CustomerAddress.ClassName /*metaclass name*/, "CustomerAddress_AddressCompanyName", true, 100, false);

Added this stuff to Global.asax.cs.

#113295
Edited, Nov 18, 2014 10:40
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.