Предоставляет клиент, совместимый с WS-Trust, для подключения к локальным экземплярам IFD Dynamics 365 из .NET Core. Пакет создан на основе Microsoft.PowerPlatform.Dataverse.Client и предлагает альтернативную реализацию IOrganizationService с использованием WS-Trust. Это позволяет подключаться по URL-адресу службы организации, имени пользователя и паролю без каких-либо дополнительных действий.
$ dotnet add package Tisa.XrmCoreБиблиотека для .NET, предоставляющая клиент, совместимый с WS-Trust, для подключения к локальным экземплярам IFD Dynamics 365 из .NET Core. Библиотека создана на основе Microsoft.PowerPlatform.Dataverse.Client и предлагает альтернативную реализацию IOrganizationService с использованием WS-Trust.
dotnet add package Tisa.XrmCore
Библиотека предоставляет несколько клиентов для различных сценариев аутентификации.
Клиент для подключения к локальным экземплярам Dynamics 365 с использованием WS-Trust.
using Tisa.XrmCore;
using Microsoft.Xrm.Sdk;
// Создание клиента
var client = new OnPremiseClient(
organizationUrl: "https://your-org.crm.dynamics.com",
username: "your-username",
password: "your-password"
);
// Асинхронные операции
var whoAmIResponse = await client.ExecuteAsync(new WhoAmIRequest());
var userId = ((WhoAmIResponse)whoAmIResponse).UserId;
// Создание записи
var account = new Entity("account");
account["name"] = "Test Account";
var accountId = await client.CreateAsync(account);
// Получение записи
var retrievedAccount = await client.RetrieveAsync("account", accountId, new ColumnSet(true));
// Обновление записи
account["name"] = "Updated Account";
await client.UpdateAsync(account);
// Удаление записи
await client.DeleteAsync("account", accountId);
Клиент для аутентификации с использованием Active Directory.
using Tisa.XrmCore;
// Создание клиента с доменом
var client = new ADAuthClient(
url: "https://your-org.crm.dynamics.com",
username: "domain\\username", // или "username@domain.com"
password: "your-password",
upn: "service@domain.com"
);
// Использование аналогично OnPremiseClient
var response = await client.ExecuteAsync(new WhoAmIRequest());
Клиент для аутентификации на основе утверждений.
using Tisa.XrmCore;
var client = new ClaimsBasedAuthClient(
url: "https://your-org.crm.dynamics.com",
issuerEndpoint: "https://sts.your-domain.com/adfs/services/trust/13/usernamemixed"
);
var response = await client.ExecuteAsync(new WhoAmIRequest());
Сервис для валидации токенов и получения IOrganizationService на основе конфигурации.
{
"Tokens": {
"token-1": "Auth:Token1"
},
"Auth": {
"Token1": {
"AuthType": "IFD",
"Url": "https://your-org.crm.dynamics.com",
"User": "username",
"Password": "password"
}
}
}
using Tisa.XrmCore.Abstractions;
using Tisa.XrmCore.Infrastructure;
using Microsoft.Extensions.Configuration;
// Регистрация в DI
services.AddScoped<IXCoreService, XCoreService>();
// Использование
public class ContactService
{
private readonly IXCoreService _xCoreService;
public ContactService(IXCoreService xCoreService)
{
_xCoreService = xCoreService;
}
public bool ValidateToken(string token)
{
return _xCoreService.ValidateToken($"Tokens:{token}");
}
public void CreateContact(string firstName, string lastName)
{
var service = _xCoreService.GetOrganizationService();
var contact = new Entity("contact");
contact["firstname"] = firstName;
contact["lastname"] = lastName;
service.Create(contact);
}
}
Библиотека поддерживает следующие типы аутентификации:
{
"Auth": {
"ADAuth": {
"AuthType": "AD",
"Url": "https://your-org.crm.dynamics.com",
"User": "domain\\username",
"Password": "password"
},
"IFDAuth": {
"AuthType": "IFD",
"Url": "https://your-org.crm.dynamics.com",
"User": "username",
"Password": "password"
},
"OAuthAuth": {
"AuthType": "OAuth",
"ConnectionString": "AuthType=OAuth;Url=https://your-org.crm.dynamics.com;Username=username;Password=password;AppId=app-id;RedirectUri=redirect-uri;LoginPrompt=Auto"
},
"ClientSecretAuth": {
"AuthType": "ClientSecret",
"ConnectionString": "AuthType=ClientSecret;Url=https://your-org.crm.dynamics.com;ClientId=client-id;ClientSecret=client-secret"
}
}
}
Базовый класс для работы с данными Dynamics 365 с типовыми методами.
using Tisa.XrmCore.Data;
using Tisa.XrmCore.Abstractions;
using Microsoft.Xrm.Sdk;
using Tisa.Common.Primitives;
public class ContactDataService : XrmDataService
{
public ContactDataService(IXCoreService xCoreService)
: base(xCoreService)
{
}
public Result<Entity> GetContactById(Guid contactId)
{
var entityReference = new EntityReference("contact", contactId);
return Retrieve(entityReference, "firstname", "lastname", "emailaddress1");
}
public Result<EntityCollection> GetContactsByEmail(string email)
{
var query = new QueryExpression("contact");
query.ColumnSet = new ColumnSet("firstname", "lastname", "emailaddress1");
query.Criteria.AddCondition("emailaddress1", ConditionOperator.Equal, email);
return RetrieveMultiple(query);
}
public Result<Guid> CreateContact(string firstName, string lastName, string email)
{
var contact = new Entity("contact");
contact["firstname"] = firstName;
contact["lastname"] = lastName;
contact["emailaddress1"] = email;
return Create(contact);
}
}
Библиотека предоставляет множество методов расширения для упрощения работы с Dynamics 365.
using Tisa.XrmCore.Extensions;
using Microsoft.Xrm.Sdk;
var entity = new Entity("account");
entity["name"] = "Test Account";
// Безопасное получение значений
var name = entity.GetAttributeValue<string>("name");
var revenue = entity.GetAttributeValue<Money>("revenue");
// Установка значений с проверкой
entity.SetAttributeValue("name", "Updated Account");
using Tisa.XrmCore.Extensions;
using Microsoft.Xrm.Sdk;
var money = new Money(123.456m);
// Округление
var rounded = money.Round(2); // 123.46
var roundedUp = money.RoundUp(2); // 123.46
var roundedDown = money.RoundDown(2); // 123.45
// Операции
var sum = money.Sum(new Money(10m), new Money(20m));
var difference = money.Subtraction(new Money(10m));
var min = money.Min(new Money(100m));
var max = money.Max(new Money(100m));
// Получение значения с значением по умолчанию
var value = money.Value(0m);
using Tisa.XrmCore.Extensions;
using Microsoft.Xrm.Sdk.Query;
var query = new QueryExpression("account");
query.ColumnSet = new ColumnSet("name", "revenue");
// Добавление условий
query.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);
query.Criteria.AddCondition("revenue", ConditionOperator.GreaterThan, 1000000);
// Добавление связей
var link = query.AddLink("contact", "accountid", "parentcustomerid");
link.Columns = new ColumnSet("firstname", "lastname");
using Tisa.XrmCore.Extensions;
using Microsoft.Xrm.Sdk;
// Выполнение FetchXML
var fetchXml = @"
<fetch>
<entity name='account'>
<attribute name='name'/>
<filter>
<condition attribute='statecode' operator='eq' value='0'/>
</filter>
</entity>
</fetch>";
var results = service.FetchXml(fetchXml);
// Получение всех страниц результатов
var allResults = service.RetrieveMultiple(query, shouldRetrieveAllPages: true);
// Получение с ограничением количества
var limitedResults = service.RetrieveMultiple(query, maxResultCount: 100);
Класс для работы с транзакциями в Dynamics 365.
using Tisa.XrmCore.Data;
using Microsoft.Xrm.Sdk;
public class TransactionService
{
private readonly IOrganizationService _service;
public TransactionService(IOrganizationService service)
{
_service = service;
}
public void CreateMultipleEntities()
{
using var unitOfWork = new UnitOfWork(_service);
try
{
// Создание нескольких сущностей в одной транзакции
var account = new Entity("account");
account["name"] = "Test Account";
var accountId = unitOfWork.Create(account);
var contact = new Entity("contact");
contact["firstname"] = "John";
contact["lastname"] = "Doe";
contact["parentcustomerid"] = new EntityReference("account", accountId);
unitOfWork.Create(contact);
// Подтверждение транзакции
unitOfWork.Commit();
}
catch
{
// Откат транзакции при ошибке
unitOfWork.Rollback();
throw;
}
}
}
Все клиенты поддерживают асинхронные операции через интерфейс IOrganizationServiceAsync2.
using Tisa.XrmCore;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
var client = new OnPremiseClient(url, username, password);
// Асинхронное создание
var entity = new Entity("account");
entity["name"] = "Test Account";
var id = await client.CreateAsync(entity);
// Асинхронное получение
var retrieved = await client.RetrieveAsync("account", id, new ColumnSet(true));
// Асинхронное обновление
entity["name"] = "Updated Account";
await client.UpdateAsync(entity);
// Асинхронное удаление
await client.DeleteAsync("account", id);
// Асинхронное выполнение запроса
var query = new QueryExpression("account");
query.ColumnSet = new ColumnSet("name");
var results = await client.RetrieveMultipleAsync(query);
// Асинхронное выполнение запроса
var request = new WhoAmIRequest();
var response = await client.ExecuteAsync(request);
Библиотека предоставляет специализированные исключения для обработки ошибок.
using Tisa.XrmCore.Exceptions;
try
{
var client = new OnPremiseClient(url, username, password);
var response = await client.ExecuteAsync(new WhoAmIRequest());
}
catch (XrmCoreException ex)
{
// Обработка ошибок XRM
Console.WriteLine($"Ошибка XRM: {ex.Message}");
}
catch (Exception ex)
{
// Обработка других ошибок
Console.WriteLine($"Общая ошибка: {ex.Message}");
}
Abstractions/ - Интерфейсы (IXCoreService, IInnerOrganizationService)AuthHelpers/ - Вспомогательные классы для аутентификации WS-TrustData/ - Классы для работы с данными (XrmDataService, UnitOfWork)Exceptions/ - Исключения (XrmCoreException)Extensions/ - Методы расширения для Entity, Money, Query и т.д.Infrastructure/ - Инфраструктурные классы (XCoreService, XrmFactory)Resources/ - Ресурсы (FetchXML шаблоны)Wsdl/ - WSDL определенияusing Tisa.XrmCore;
using Tisa.XrmCore.Data;
using Tisa.XrmCore.Abstractions;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
public class ContactService
{
private readonly IXCoreService _xCoreService;
public ContactService(IXCoreService xCoreService)
{
_xCoreService = xCoreService;
}
public async Task<Guid> CreateContactAsync(
string firstName,
string lastName,
string email)
{
var service = _xCoreService.GetOrganizationService();
var contact = new Entity("contact");
contact["firstname"] = firstName;
contact["lastname"] = lastName;
contact["emailaddress1"] = email;
return service.Create(contact);
}
public async Task<Entity> GetContactAsync(Guid contactId)
{
var service = _xCoreService.GetOrganizationService();
return await service.RetrieveAsync(
"contact",
contactId,
new ColumnSet("firstname", "lastname", "emailaddress1"));
}
public async Task<List<Entity>> SearchContactsByEmailAsync(string email)
{
var service = _xCoreService.GetOrganizationService();
var query = new QueryExpression("contact");
query.ColumnSet = new ColumnSet("firstname", "lastname", "emailaddress1");
query.Criteria.AddCondition("emailaddress1", ConditionOperator.Equal, email);
var results = await service.RetrieveMultipleAsync(query);
return results.Entities.ToList();
}
}
При использовании библиотеки убедитесь, что:
Команда разработчиков TISA
MIT License
Для получения поддержки или сообщения об ошибках, пожалуйста, напишите нам на support@tisn.ru