Задача: есть файл, который хранится в 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, так что еще раз мои поздравления!

Полезные ссылки: