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

MetaHelper.SetMetaFieldValue does not delete values (9.16)

Vote:
 

Hi,

We use the above method to set various dictionary metadata values; one example in particular is the _ExcludedCatalogEntryMarkets field.

Until either this release, or possibly a slightly older release (not sure as we've only just spotted it), if an empty object was passed in to the 'values' parameter, this would remove any existing values for that field.  Now, however, that bahaviour is not exhibited - if an empty object is supplied the method apparently does nothing.  This is a problem especially for the _ExcludedCatalogEntryMarkets field if, for example, a product was previously excluded from certain markets, but now we wish to update it to be available everywhere.

The Commerce Manager works as expected so there msut be some way of removing this kind of meta data using the API...?

For ref:

http://world.episerver.com/documentation/Class-library/?documentId=commerce/7.5/61388F84

Thanks

Jim

#150554
Jun 22, 2016 12:55
Vote:
 

Hi,

Note that MetaHelper.SetMetaFieldValue does not really save the value, you should still call metaObject.AcceptChanges() to persist the data.

In your case, try this:

var deletedMarket = new MetaDictionaryItem("MarketId");

marketField.Dictionary.Remove(deletedMarket);

var excludedMarkets = marketField.Dictionary.OfType<MetaDictionaryItem>().ToArray();

metaObject["_ExcludedCatalogEntryMarkets"] = excludedMarkets;

metaObject.AcceptChanges();

This is pseudo code, but you get the idea.

/Q

#151166
Jul 12, 2016 20:18
Vote:
 

Hi Quan,

Many thanks for your reply.  However I am still experiencing difficulties.  In each of the below experiments I have called metaObject.AcceptChanges(metaContext), but in every case no data has changed - the item still retains whatever values it previously has for the _ExcludedCatalogEntryMarkets field.

Please note that we are not deleting any markets from our site; we just want to remove the exclusions from an existing item.

These are the different things I've tried:

List<MetaDictionaryItem> multiValues = new List<MetaDictionaryItem>();

MetaHelper.SetMetaFieldValue(metaContext, metaObject, metaFieldName, multiValues.ToArray());

MetaHelper.SetMetaFieldValue(metaContext, metaObject, metaFieldName, null);

metaObject[metaFieldName] = null;

So far, none of these have worked.  The metaField in question does allow nulls.  Do you have any other suggestions, or could this be a symptom of a bug?

Thanks,

Jim

#151281
Jul 13, 2016 18:20
Vote:
 

This is indeed not a bug - as the function is working normally. The code above is not correct, this should do it:

var deletedMarket = new MetaDictionaryItem("MarketId");

var markets = marketField.Dictionary.OfType<MetaDictionaryItem>().ToList();

var excludedMarkets = markets.Remove(deletedMarket)

metaObject["_ExcludedCatalogEntryMarkets"] = excludedMarkets;

metaObject.AcceptChanges();

You are enabling the metaObject in the "MarketId" here.

#151285
Jul 13, 2016 20:04
Vote:
 

Hi Quan,


Thanks for your help.  As it turns out the problem was much more obscure.  I had a look at the SQL proc CatalogContentProperty_Save, which is where this information gets saved to the database, and found that the section that deletes MetaField data requires that the language submitted matches the default language of the catalog.  However, when updating MetaField data, that supplied language is overwritten by this statement earlier on:

IF @LanguageName NOT IN (SELECT LanguageCode FROM dbo.CatalogLanguage WHERE CatalogId = @catalogId)

BEGIN

SET @LanguageName = (SELECT DefaultLanguage FROM dbo.Catalog WHERE CatalogId = @catalogId)

END

This corrected @LanguageName parameter is used in the subsequent MERGE statement, but not in the DELETE statement if we are trying to set the MetaField data to NULL.
The fix, then, is to ensure the language submitted from the MetaDataContext is the same as the default language of our catalog - en-gb, in our case.  As this catalogue updater runs as a console application I needed to explicitly override the default en-us in the program's initialization.  Now it works as expected.


Thought this might be useful in case anyone else experiences anything similar!
Jim

#151323
Jul 15, 2016 12:41
Vote:
 

You should not have to override the default en-us in initialization module. When you load your MetaObject, just make sure to use en-gb in the MetaDataContext, something like this:

var metaDataContext = CatalogContext.MetaDataContext.Clone();

metaDataContext.UseCurrentThreadCulture = false;

metaDataContext.Language = "en-gb";

var metaObject = MetaObject.Load(metaDataContext, ...)

//Update & save it

#151327
Jul 15, 2016 13:23
* 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.