0

I'm trying to retrieve items via a multiselect rendering parameter. It parses the rendering parameter correctly but even though it doesn't throw an error when adding a new item to the model, when it tries to create one it seems to be creating items that are null. I'm able to confirm that there are the appropriate number of items in the view, but if I try to retrieve any information about them - fields, id, etc., it throws a null reference exception, and it does the same if I try to do this in the controller. Here's my controller code:

public ActionResult Audio()
    {
        var model = new AudioModel();
        var items = RenderingContext.Current.Rendering.Parameters["Audio Files"];
        if (!(String.IsNullOrEmpty(items)))
        {
            var results = items.Split('|');
            foreach(string item in results)
            {
                model.Items.Add(Context.Database.GetItem(new ID(item)));
            }
        }            
        return View(model);
    }

And here is the model if that's helpful:

public class AudioModel
{
    public List<Sitecore.Data.Items.Item> Items { get; set; }

    public AudioModel()
    {
        Items = new List<Sitecore.Data.Items.Item>();
    }
}
  • If I'm reading your question properly, items does contain something like {id-000-1}|{id-000-2}, but when you try to retrieve the items they are null? If so, are you sure the items you're trying to retrieve are published? – jrap Jun 21 at 20:19
  • Also for safer code use ID myId; if(ID.TryParse(itemId, out myId){ var myItem = Context.Database.GetItem(myId); if(myItem != (Item)null){model.Items.Add(myItem);} (note, change your foreach to foreach(var itemId in results)) – jrap Jun 21 at 20:22
  • Yes, that was it, one of them wasn't published. Thanks for the suggestion for the code, it works well. – Levi Wallach Jun 21 at 20:35
3

Based on the comments, in this particular scenario the issue was due to the dependent items not being published. However, for completeness sake, the existing method can be written in a more defensive way:

public ActionResult Audio()
{
    var model = new AudioModel();
    var itemIdsRaw = RenderingContext.Current.Rendering.Parameters["Audio Files"];

    if(string.IsNullOrWhiteSpace(itemIdsRaw))
        return View(model); // exit early, reduce nesting

    var itemIdStrings = itemIdsRaw.Split('|');
    foreach(var itemIdString in itemIdStrings)
    {
        Id itemId;
        if(!ID.TryParse(itemIdString, out itemId))
            continue; // log?
        var item = Context.Database.GetItem(itemId);
        if(item == (Item)null)
            continue; // log?
        model.Items.Add(item);
    }
    return View(model);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.