Задача: есть файл, который хранится в SharePoint, следовательно есть к нему url, необходимо перенести этот файл в заметки Microsoft Dynamics CRM 4.0 для определенного объекта. Файл может быть любим: архив, документ word, excel, pdf …
Примечание:
для учетной записи пользователя должны быть предоставлены необходимые права в SharePoint
Сам алгоритм плагина будет выглядеть так:
1. сначала я должен получить список всех url документов,
2. после чего создаю заметку в MS CRM
3. считываю документ из SharePoint в буферный файл (в моем случае c:\\bufferFile)
4. добавляю файл в аннотацию (note)
5. повторяю шаги 2-4
Ниже я предоставлю код функции для плагина
public static void CreateNote(Lookup regarding, string lookupfield, DynamicEntity entity, ICrmService crmService)
Параметры которой следующие:
Lookup regarding – связанная запись, к которой привязаны записи документов из SharePoint с полем new_self – это url к документу и new_name – название документа
string lookupfield – поле по которому связана моя сущность с сущностью, содержащую карточки документов
DynamicEntity entity – исходная сущность
ICrmService crmService – IcrmService
//функция для создания примечания в листе согласования
public static void CreateNote(Lookup regarding, string lookupfield, DynamicEntity entity, ICrmService crmService)
{
//вытягиваю все Карточки файлов, привязанных к данному договору
ColumnSet cs = new ColumnSet();
cs.Attributes.AddRange(new string[] { "new_self", "new_name" });
QueryByAttribute qba = new QueryByAttribute();
qba.ColumnSet = cs;
qba.EntityName = "new_isorgdoc";
qba.Attributes = new string[] { lookupfield };
qba.Values = new object[] { regarding.Value };
RetrieveMultipleRequest rmr = new RetrieveMultipleRequest();
rmr.Query = qba;
rmr.ReturnDynamicEntities = true;
//получаю ответ
RetrieveMultipleResponse rmresponse = (RetrieveMultipleResponse)crmService.Execute(rmr);
//создаю новые заметки в листе согласованя и загружаю файлы из Карточки файлов
foreach (DynamicEntity _file in rmresponse.BusinessEntityCollection.BusinessEntities)
{
//получаю полный путь(url) к файлу
string currentPath;
Uri url = new Uri(_file["new_self"].ToString());
currentPath = url.ToString();
//получаю только имя файла, в формате имя_файла.расширение
string FileName = currentPath.Substring(currentPath.LastIndexOf("/") + 1, (currentPath.Length - currentPath.LastIndexOf("/") - 1));
// создаю заметку
annotation note = new annotation();
note.notetext = FileName; // тело заметки
note.subject = FileName; //тема заметки
note.objectid = new Lookup();
note.objectid.type = "new_list_soglasovaniya";
// привязываю ее к листу согласования
note.objectid.Value = ((Key)entity.Properties["new_list_soglasovaniyaid"]).Value;
note.objecttypecode = new EntityNameReference();
note.objecttypecode.Value = "new_list_soglasovaniya";
//создаю заметку
Guid createdNoteId = crmService.Create(note);
//отправляю запрос на чтение файла по полученному url
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url.ToString());
myReq.Timeout = 7000;
try
{
//авторизирую себя (пользователя)
myReq.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse MyResponse = (HttpWebResponse)myReq.GetResponse();
if (HttpStatusCode.OK == MyResponse.StatusCode)
{
// открываю поток
using (Stream MyResponseStream = MyResponse.GetResponseStream())
{
// открываю или создаю промежуточный файл
using (FileStream MyFileStream = new FileStream("c:\\bufferFile", FileMode.OpenOrCreate, FileAccess.Write))
{
byte[] MyBuffer = new byte[4096];
int BytesRead;
//записываю в промежуточный файл
while (0 < (BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)))
{
MyFileStream.Write(MyBuffer, 0, BytesRead);
}
}
}
}
}
catch (Exception err)
{
throw new Exception("Error saving file from URL:" + err.Message, err);
}
FileStream stream = File.OpenRead("c:\\bufferFile");
byte[] byteData = new byte[stream.Length];
stream.Read(byteData, 0, byteData.Length);
stream.Close();
string encodedData = System.Convert.ToBase64String(byteData);
// подгружаю файл к аннотации
annotation updateNote = new annotation();
updateNote.annotationid = new Key();
updateNote.annotationid.Value = createdNoteId;
updateNote.documentbody = encodedData;
updateNote.filename = FileName;
//updateNote.mimetype = @"application\ms-word";
crmService.Update(updateNote);
}
Пример вызова:
CreateNote(regardingLookup, "new_dogovor", entity, crmService);
Вот вроде бы и все. Решение не претендует на единственное, есть множество способов для его улучшения, просто представлен пример, показывающий возможность реализации такой задачи. Кстати, таким способом можно приаттачивать документы не только из SharePoint, но и других веб-ресурсов, а так же с локального сервера (localhost) все будет упираться в политику безопасности. Кстати, я не проверил, но возможно если расширение запрещено для загрузки в MS CRM, то загрузить файл не получится. Так что имейте это в виду.
Спасибо Андрею Бутенко aka a33ik, который постоянно меня направляет в нужное русло
Кстати, он получил статус MVP по Microsoft Dynamics CRM, так что еще раз мои поздравления!
Полезные ссылки:

13.01.2010 в 10:08
Спасибо, старина )
14.01.2010 в 14:55
и тебе спасибо за помощь
20.06.2010 в 10:53
Большое спасибо!!!!