Разработка
05
Окт
8

Чтение всех атрибутов объекта в C#

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Metadata;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;

namespace RetrieveAttributes
{
    class Program
    {
        static void Main(string[] args)
        {
            // Подключаемся к CRM
            ClientCredentials credentials = new ClientCredentials();
            credentials.Windows.ClientCredential = new System.Net.NetworkCredential("Administrator", "1qaz@WSX", "D2011");
            Uri uri = new Uri("http://crm2011:5555/superfirma/XRMServices/2011/Organization.svc");
            OrganizationServiceProxy proxy = new OrganizationServiceProxy(uri, null, credentials, null);
            proxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
            IOrganizationService service = (IOrganizationService)proxy;

            // Возвращаем все поля записи Организация
            Entity retrievedAccount = service.Retrieve("account", new Guid("14E25FE5-73E2-E111-B2D5-000C29CDB72E"), new ColumnSet(allColumns: true));

            // Просматриваем по очереди все возвращенные поля
            foreach (KeyValuePair<string, object> metaAttribute in retrievedAccount.Attributes)
            {
                // Берем один атрибу...
                object myProp = retrievedAccount.Attributes[metaAttribute.Key];

                // ... и запрашиваем его метаданные
                RetrieveAttributeRequest attribReq = new RetrieveAttributeRequest();
                attribReq.EntityLogicalName = retrievedAccount.LogicalName;
                attribReq.LogicalName = metaAttribute.Key;
                attribReq.RetrieveAsIfPublished = true;
                RetrieveAttributeResponse amRes = (RetrieveAttributeResponse)service.Execute(attribReq);
                AttributeMetadata attmetadata = amRes.AttributeMetadata;

                // Вызываем метод GetMetadataValue, чтобы он в зависимости от типа атрибута вернул его значение
                string sMyValue = GetMetadataValue(myProp , amRes);
                
                // Выводим название атрибута и его значение
                Console.WriteLine("{0} \t= {1}", metaAttribute.Key, sMyValue);
            }

            Console.WriteLine("\nPress <Enter> to exit.");
            Console.ReadLine();
        }

        // Метод возвращает значение атрибута в зависимоти от его типа
        static string GetMetadataValue(object oAttribute, RetrieveAttributeResponse attMetadata)
        {
            string sReturn = string.Empty;

            // Наборы параметров...
            if (oAttribute.GetType().Equals(typeof(Microsoft.Xrm.Sdk.OptionSetValue)))
            {
                OptionMetadata[] optionList = null;
                // трушный Пиклист
                if (attMetadata.AttributeMetadata.GetType().FullName.Contains("PicklistAttributeMetadata"))
                {
                    PicklistAttributeMetadata retrievedPicklistAttributeMetadata = (PicklistAttributeMetadata)attMetadata.AttributeMetadata;
                    optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
                } // Поле Статуса
                else if (attMetadata.AttributeMetadata.GetType().FullName.Contains("StatusAttributeMetadata"))
                {
                    StatusAttributeMetadata retrievedPicklistAttributeMetadata = (StatusAttributeMetadata)attMetadata.AttributeMetadata;
                    optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
                } // Поле Состояния
                else if (attMetadata.AttributeMetadata.GetType().FullName.Contains("StateAttributeMetadata"))
                {
                    StateAttributeMetadata retrievedPicklistAttributeMetadata = (StateAttributeMetadata)attMetadata.AttributeMetadata;
                    optionList = retrievedPicklistAttributeMetadata.OptionSet.Options.ToArray();
                }
                else
                    return string.Empty;
                
                // Получаем текстовое значение Набора параметров
                int i = int.Parse((oAttribute as Microsoft.Xrm.Sdk.OptionSetValue).Value.ToString());
                for (int c = 0; c < optionList.Length; c++)
                {
                    OptionMetadata opmetadata = (OptionMetadata)optionList.GetValue(c);
                    if (opmetadata.Value == i)
                    {
                        sReturn = opmetadata.Label.UserLocalizedLabel.Label;
                        break;
                    }
                }
            } // Деньги
            else if (oAttribute.GetType().Equals(typeof(Microsoft.Xrm.Sdk.Money)))
            {
                sReturn = (oAttribute as Microsoft.Xrm.Sdk.Money).Value.ToString();
            } // Лукап
            else if (oAttribute.GetType().Equals(typeof(Microsoft.Xrm.Sdk.EntityReference)))
            {
                sReturn = (oAttribute as Microsoft.Xrm.Sdk.EntityReference).Name;
            } // Все остальное - легко преобразуемое в текст
            else
            {
                sReturn = oAttribute.ToString();
            }

            if (sReturn == null || sReturn.Length == 0)
                sReturn = "No Value";
            
            return sReturn;
        }
    }
}

Что мы тут делаем:

  • Подключаемся к CRM;
  • Возвращаем все поля одной записи Организации;
  • Просматриваем все возвращенные атрибуты и для каждого из них запрашиваем метаданные;
  • Затем сам атрибут и его метаданные передаем в функцию GetMetadataValue, которая на основе типа атрибута, определяет способ извлечения данных атрибута и возвращает их.


Комментарии (8)
  • skfd 05.10.2012

    А почему не использовать early bound классы?

  • slivka_83 05.10.2012

    Лень 🙂 Этож нужно открвыать sdk, зпускать тулзу и т.д. 🙂

  • Андрей 05.10.2012

    А не проще просто просмотреть и вывести коллекцию форматированных атрибутов сущности.

  • slivka_83 05.10.2012

    Не совсем понял что Вы имели ввиду?

  • Павел 05.10.2012

    Андрей наверно имел ввиду что для получения значения в OptionSet достаточно будет использовать соответсвующее значение из FormattedValues колекции в Entity. Тогда метадату можно будет вообще не вычитывать.

  • Aleks 05.10.2012

    Может кто-нибудь подсказать как передать данные из приложения написанного на C# в CRM. Чтобы при передаче создавался объект и в поля записывались данные, которые я передаю.

  • slivka_83 05.10.2012

    Ну, тут в двух словах не рассказать 🙂

  • slivka_83 05.10.2012

    Как пример можете посмотреть тут: http://mmcrm.ru/?p=2423 и http://mmcrm.ru/?p=2415

*

code