How to set a value for a Name Value List

Challenge:

This might sound newbie question. But I’ve been asked this question multiple times ranging from Beginner till expert. So, thought to blog it. Basically, You have Name value field in Sitecore, and you would like to set its value using API.

You have same question? Or not now. But have no clue and curious to know? How? Then this post is for you:

Solution:

We faced this challenge somewhere in April, and during that time we did a quick search and we were unable to find anything helpful. Then one of our Best Friend and Colleague — Sheetal Jain came up with following solutions:

NameValueListField nameValueListField = childItem.Fields["NAMEVALUELISTFIELDNAME"];
if (nameValueListField != null)
{
	nameValueListField.NameValues.Add("NAME1", "VALUE1");
	nameValueListField.NameValues.Add("NAME2", "VALUE2");
}
if (String.IsNullOrEmpty(childItem.Fields["NAMEVALUELISTFIELDNAME"].Value))
{
	childItem.Fields["NAMEVALUELISTFIELDNAME"].Value = "NAME1=VALUE1";
}
else
{
	childItem.Fields["NAMEVALUELISTFIELDNAME"].Value = childItem.Fields["NAMEVALUELISTFIELDNAME"].Value + "&"  + "NAME2=VALUE2";
}

Then before writing this post. Thought to do quick search again and found this post : https://community.sitecore.net/developers/f/8/t/202

  var db = Sitecore.Configuration.Factory.GetDatabase("master");
      var item = db.GetItem("{8A8E427B-9162-4680-AE69-239217F5B9AB}");

      //Initialize data
      var data = new NameValueCollection();
      data.Add("name1", "value1");
      data.Add("name2", "value2");
      data.Add("name3", "value3");
      data.Add("name4", "value4");
      
      using (new Sitecore.SecurityModel.SecurityDisabler())
      {
        item.Editing.BeginEdit();
        try
        {
          //where data is NameValueCollection
          //where '$' is divider 
          item["NameList"] = StringUtil.NameValuesToString(data, "&");
        }
        finally
        {
          item.Editing.EndEdit();
        }
      }

Which is also neat way to do the same. So, now you’ve three ways to solve one problem! Feel free to select whichever you like!

Happy Sitecoring! 🙂

Adding a language specific file to the Sitecore Media Library programmatically

Challenge:

Before few weeks back, was working on a task where we needed to add media file programmatically and that too language specific.

You may ask why we need to do so. Really a good question, Here’s the answer for the same: Let’s say for an example you have a product, and each product will have a USER Guide and user guide may exist in each language. So, rather than creating different media item for each language specific user guide, we wanted to have only one media item and language specific different file.

Solution:

Adding media file programmatically is pretty much straight forward task with Sitecore API, and following are the best resources on the web which helps us to do so:

But to add language specific media item programmatically, We haven’t found anything already written on the web. After that we did a bit of a research and invested good amount of time to make it happen. And thought to share with you with the hope that you no need to invest same time again.

To make it happen tried following approach first while creating file programmatically:

// Do not make a versioned template
options.Versioned = true;
// Language added
options.Language = language; // Language Instance gets passed to us

To test it, we iterate the loop twice, Where in first Iteration we create media item in en language and in second iteration we create media item in another language. Let’s say es-ES. But the later iteration overrides the first version. We also tried with options.KeepExisting = true; But with no luck 😦

Good to read : http://learningsitecorecms.blogspot.in/2013/09/sitecore-media-item-created-in-multiple.html

Then did a quick search on Google and SDN. But unfortunately couldn’t find anything which instructs us to do so. But at the same time found this nice article [Login Required] : http://sdn.sitecore.net/snippets/item%20handling/media%20library/updating%20image%20file%20on%20a%20media%20library%20item%20programmatically.aspx 

And changed code like this:


MediaItem mediaItem = (MediaItem)database.GetItem(options.Destination, <strong>language</strong>);

if (mediaItem == null)
{
// Now create the file in Sitecore. Using Static options
mediaItem = Sitecore.Resources.Media.MediaManager.Creator.CreateFromStream(memoryStream, fileName, options);
}
else
{

Sitecore.Resources.Media.Media media = MediaManager.GetMedia(mediaItem);
media.SetStream(memoryStream, ".pdf"); // Hard coded for simplicity
}

Here we are checking that if Media Item already exist then add language specific media version. And it worked!

Full Code:


/// <summary>
/// This method will be used to add file in
/// Sitecore Media Library folder
/// </summary>
/// <param name="fileName">Full Name of file</param>
/// <param name="sitecorePath">Sitecore Path</param>
///mediaItemName">Name of media item
/// <returns>Newly created media item</returns>
public static Item AddFile(string fileName, string sitecorePath, string mediaItemName, Stream responseStream, Database database, Sitecore.Globalization.Language language)
{
// Create the options
Sitecore.Resources.Media.MediaCreatorOptions options = new Sitecore.Resources.Media.MediaCreatorOptions();
// Store the file in the database, not as a file
options.FileBased = false;
// Remove file extension from item name
options.IncludeExtensionInItemName = false;
// Overwrite any existing file with the same name
//options.KeepExisting = false;
// Do not make a versioned template
// Set it as per your need - if you are going to use same method
// Make it parametrized
options.Versioned = true;

// Language added
options.Language = language;

// set the path
options.Destination = sitecorePath + "/" + mediaItemName;

// Set the database
options.Database = database;

// Now create the file
//Sitecore.Resources.Media.MediaCreator creator = new Sitecore.Resources.Media.MediaCreator();
//MediaItem mediaItem = creator.CreateFromFile(fileName, options);

// Read the file from stream:
MemoryStream memoryStream = new MemoryStream();

/* This approach throws an error  "This stream does not support seek operations."
* While using Response Stream. So, following approach works with FileStream as well
as HttpWebResponseStream
memoryStream.SetLength(fileStream.Length);
fileStream.Read(memoryStream.GetBuffer(), 0, (int)fileStream.Length);
memoryStream.Flush();
*/
byte[] buffer = new byte[2048];

int bytesRead = 0;
do
{
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, bytesRead);

} while (bytesRead != 0);

responseStream.Close();
memoryStream.Flush();

/*
*
Added SetStream Code as there is no such way using which Sitecore's API
will create language specific version directly, It used to overwrite
* the last upload operation. Which means at one time only one language
* version was getting uploaded
*/

MediaItem mediaItem = (MediaItem)database.GetItem(options.Destination, language);

if (mediaItem == null)
{
// Now create the file in Sitecore. Using Static options
mediaItem = Sitecore.Resources.Media.MediaManager.Creator.CreateFromStream(memoryStream, fileName, options);
}
else
{
// Attach Version specific media item
Sitecore.Resources.Media.Media media = MediaManager.GetMedia(mediaItem);
media.SetStream(memoryStream, Path.GetExtension(fileName));

}

memoryStream.Dispose();

return mediaItem;
}

Just a note: We confirmed this approach with Sitecore support and they are fine with it!

Happy Language Specific Media Creation! 🙂