пятница, 14 мая 2010 г.

SharePoint 2010 CSOM: Using one client context object into another

Целый день провозился с ошибкой:
'System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.SharePoint.Client.ClientRequest.BuildQuery()
   at Microsoft.SharePoint.Client.ClientRequest.ExecuteQuery()
   at Microsoft.SharePoint.Client.ClientRuntimeContext.ExecuteQuery()
   at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()

Оказалось дело в том что я объекты полученные в рамках одного контекста использовал в другом.

В коде ниже я в одном контексте получаю пользователя, и засовываю его в другой.
Как раз при вызове последнего ExecuteQuery и вываливается "KeyNotFoundException", причем делается это даже без обращения к серверу.

static User GetUser(string name)
{
    using (var clientContext = new ClientContext(@"http://Server1/subsite"))
    {
        var usr = clientContext.Web.EnsureUser(name);
        clientContext.Load(usr);
        clientContext.ExecuteQuery();
        return usr;
    }
}

var lci = new ListItemCreationInformation();
lci.FolderUrl = @"/subsite/MyMeeting";
lci.UnderlyingObjectType = FileSystemObjectType.File;

using (var clientContext = new ClientContext(@"http://Server1/subsite"))
{
   var list = clientContext.Web.Lists.GetByTitle("MyMeeting");

   var item = list.AddItem(lci);
   item["Title"] = "Meet every week";
   item["Author"] = GetUser(@"DOMAIN\Max");
   item["Editor"] = GetUser(@"DOMAIN\Kate");
   item.Update();
   clientContext.Load(item);
   clientContext.ExecuteQuery();
}

2 комментария:

Advard II комментирует...

Здорово, но было бы лучше, если бы было и решение проблемы, а не только ошибочный код:) Понятно, что нужно подумать, но все же.

Advard II комментирует...

Так вроде же сказано , нельзя использовать объекты полученные в рамках одного контекста в другом. В качестве локального решения, можно получать пользователей в рамках одного клиентского контекста т.е. до вызова list.AddItem().