Microsoft CRM web service
Интеграция с MS CRM по средствам встроенного сервиса дает возможность получать\изменять данные в системе.
Полезные ссылки:
http://example.com:5555/mscrmservices/2006/crmservice.asmx - сам сервис
http://example.com:5555/mscrmservices/2006/metadataservice.asmx - мета данные
http://example.com:5555/sdk/list.aspx - список сущностей
Для подключения к студии надо использовать вот такие ссылки:
http://example.com:5555/mscrmservices/2006/crmservice.asmx?WSDL&uniquename=COMPANYNAME
http://example.com:5555/mscrmservices/2006/metadataservice.asmx?WSDL&uniquename=COMPANYNAME
По ним будут доступны xml файлы описывающие сервис, со всеми кастомными полями и т.п. и именно они будут нужны для подключения к студии.
Добавление сервиса к проекту.
Для WinForms - правый клик по проекту Add Web Reference, в URL вбиваем путь к сохраненному xml файлу, в Web reference name вбиваем имя создаваемой ссылки.
Для asp.net - правый клик по проекту Add Service Reference, далее клик по кнопке Advanced... и еще раз клик по кнопке Add Web Reference... и дальше то же самое как и для обычных апликух.
http://msdn.microsoft.com/en-us/library/cc151015.aspx
http://msdn.microsoft.com/en-us/library/cc151014.aspx
Теперь после того как сервисы прикручены можно с ними работать.
Пример получения информации и компании из CRM
MetadataService ms = new MetadataService();
CrmService s = new CrmService();
s.Credentials = new NetworkCredential("LOGIN", "PASSWORD", "COMPANYNAME");
s.Credentials = new NetworkCredential("LOGIN", "PASSWORD", "COMPANYNAME");
EntityMetadata em = ms.RetrieveEntityMetadata("organization", EntityFlags.All);
List<string> attrs = new List<string>();
foreach(AttributeMetadata am in em.Attributes) {
attrs.Add(am.Name);
}
//MessageBox.Show(string.Join("\r\n", attrs.ToArray()));
ColumnSet colSet = new ColumnSet();
colSet.Attributes = new string[] { "accountid", "name", "new_notebookid", "createdon" };
QueryExpression query = new QueryExpression();
query.EntityName = EntityName.account.ToString();
query.ColumnSet = colSet;
//////
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = "createdon";
condition.Operator = ConditionOperator.LastXDays;
condition.Values = new object[] { 1 };
// Build the filter based on the condition.
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] { condition };
// Set the Criteria field.
query.Criteria = filter;
//////////////////////////
RetrieveMultipleRequest req = new RetrieveMultipleRequest();
req.Query = query;
RetrieveMultipleResponse response = (RetrieveMultipleResponse)s.Execute(req);
string res = "";
List<TMP> items = new List<TMP>();
foreach (BusinessEntity item in response.BusinessEntityCollection.BusinessEntities)
{
account a = (account)item;
items.Add(new TMP(a.accountid.Value.ToString(), a.new_notebookid, a.name));
}
dataGridView1.DataSource = items;
Собственно вот как это может выглядеть:
Чтобы не заморачиваться с ColumnSet - можно юзать вот такую штуку:
query.ColumnSet = new AllColumns();
Пример выуживания данных сразу из двух сущностей:
String fetch = "<fetch mapping='logical'>" +
"<entity name='account'>" +
"<attribute name='new_notebookid'/>" +
"<attribute name='name'/>" +
"<link-entity name='systemuser' link-type='inner' from='systemuserid' to='ownerid'>" +
"<attribute name='lastname'/>" +
"</link-entity>" +
"<filter type='and'>" +
"<condition attribute = 'name' operator='like' value='%Саша%'/>" +
"</filter>" +
"</entity>" +
"</fetch>";
String result = s.Fetch(fetch);
Взято из этих мест:
http://msdn.microsoft.com/en-us/library/ms914457.aspx
http://social.microsoft.com/Forums/en/crmdevelopment/thread/5ef585a5-58bc-46cd-a134-a46869d0684c
http://www.stunnware.com/crm2/topic.aspx?id=FindingData6
http://mymscrm3.blogspot.com/2008/01/fetchxml-query-examples.html
Вытягивание связанных записей
Задачи за последние N дней плюс кастомное поле из account
string fetchXml = @"
<fetch mapping=""logical"" count=""5"">
<entity name=""activitypointer"">
<attribute name=""subject"" />
<filter>
<condition attribute=""createdon"" operator=""last-x-days"" value=""3"" />
<condition attribute=""statuscode"" operator=""eq"" value=""1"" />
</filter>
<link-entity name=""account"" from=""accountid"" to=""regardingobjectid"">
<attribute name=""name"" />
<attribute name=""new_notebookid"" />
</link-entity>
</entity>
</fetch>
";
выглядит вот так:
fetch link-entity aggregate
Вытягиваем количество действий для конкретного аккаунта:
string fetchXml = @"
<fetch mapping=""logical"" count=""50"" aggregate=""true"">
<entity name=""activitypointer"">
<attribute name=""activityid"" aggregate=""count"" alias=""activitypointer_count"" />
<link-entity name=""account"" from=""accountid"" to=""regardingobjectid"">
<attribute name=""new_notebookid"" />
<filter>
<condition attribute=""new_notebookid"" operator=""eq"" value=""99"" />
</filter>
</link-entity>
</entity>
</fetch>
";
fetchxml into datagridview
string fetchXml = @"
<fetch mapping=""logical"" count=""50"" aggregate=""true"">
<entity name=""activitypointer"">
<attribute name=""activityid"" aggregate=""count"" alias=""activitypointer_count"" />
<link-entity name=""account"" from=""accountid"" to=""regardingobjectid"">
<attribute name=""new_notebookid"" />
<filter>
<condition attribute=""new_notebookid"" operator=""eq"" value=""99"" />
</filter>
</link-entity>
</entity>
</fetch>
";
String result = s.Fetch(fetchXml);
StringReader lxmlStringReader = new StringReader(result);
DataSet ds = new DataSet();
ds.ReadXml(lxmlStringReader);
dataGridView1.DataSource = ds.Tables[1];
Avoid CRM 5000 limit
By default CRM Web Services is limited to return only first 5000 records. Here is how you can retrieve all records:
MetadataService ms = new MetadataService();
CrmService s = new CrmService();
s.Credentials = new NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");
ms.Credentials = new NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");
int i = 1;
bool finished = false;
DataSet dsAll = new DataSet();
while (finished == false)
{
String fetch = @"<fetch mapping='logical' page='" + i + @"' count='5000'> <!-- add page and count attributes to avoid 5000 limit -->
<!-- http://example.com:5555/sdk/list.aspx - list of available entities can be found here-->
<entity name='account'>
<!-- <all-attributes /> - to retrieve all attributes -->
<attribute name='new_notebookid'/>
<attribute name='name'/>
<link-entity name='systemuser' link-type='inner' from='systemuserid' to='ownerid'>
<attribute name='fullname'/>
<attribute name='firstname'/>
<attribute name='lastname'/>
</link-entity>
<!-- filtering example
<filter type='and'>
<condition attribute = 'name' operator='like' value='%Саша%'/>
</filter>
-->
</entity>
</fetch>";
String result = s.Fetch(fetch);
DataSet ds = new DataSet();
StringReader reader = new StringReader(result);
ds.ReadXml(reader);
dsAll.Merge(ds);
// if there is <resultset morerecods="1"> in response
if (ds.Tables[0].Rows[0]["morerecords"].ToString() == "0") finished = true;
else i++;
}
grid.DataSource = dsAll.Tables[1];
grid.DataBind();