Hi ,
I want to Import the Data into D365 using Odata services in C# .net.
Should I have to use Odata v4 client code generator or Odata Connected services ?
I tried using using Odata Connected Service Extension using .Net Since I cannot find Odata v4 client code generator in the Extensions.Most of the samples are related to OData v4 client code generator .
Can someone provide me any link the has the sample to create a record using Odata Connected services Extension ?
Here is the sample code to read the record But I need to create a record usng Odata Services .Can someone help me in this ?
using System;
using System.Linq;
using System.Threading.Tasks;
// added manually
using Microsoft.Dynamics.DataEntities; //Resources
using Microsoft.Identity.Client; //Nuget Package: IConfidentialClientApplication, ConfidentialClientApplicationBuilder, AuthenticationResult
using Microsoft.OData.Client; //DataServiceQueryException, DataServiceClientException
using System.Web; //Manually browsed and added reference to System.Web: HttpUtility
using System.Text.Json; //JsonSerializer
namespace D365_BlogOData_ConsoleApp
{
class Program
{
static string aadClientAppId = "9e9999af-de0c-999d-a1d6-b4ea7f99a8e9"; // Azure App Client ID
static string aadClientAppSecret = "Abc7FvitABC93oLQEiK0tR1b3mXXXX5sLC1mABCieS8="; // Azure App Secret
static string baseURL = "https://xxxxxxxxxxxdevaos.cloudax.dynamics.com"; // D365FO instance no slash at end
static string aadTenant = "https://login.windows.net/domain.com"; //replace domain.com with your azure AD domain
private static async Task GetAuthenticationHeader()
{
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(aadClientAppId)
.WithClientSecret(aadClientAppSecret)
.WithAuthority(new Uri(aadTenant))
.Build();
string[] scopes = new string[] { $"{baseURL}/.default" };
AuthenticationResult result = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
return result.CreateAuthorizationHeader();
}
private static void ReportODataError(DataServiceQueryException ex)
{
//Client level Exception message
Console.WriteLine(ex.Message);
//The InnerException of DataServiceQueryException contains DataServiceClientException
DataServiceClientException dataServiceClientException = ex.InnerException as DataServiceClientException;
// You can get ODataErrorException from dataServiceClientException.InnerException
// This object holds Exception as thrown from the service
// ODataErrorException contains odataErrorException.Message contains a message string that conforms to dotnet
// Exception.Message standards
var odataErrorException = dataServiceClientException.InnerException as Microsoft.OData.ODataErrorException;
if (odataErrorException != null)
{
Console.WriteLine(odataErrorException.Message);
}
Console.WriteLine(dataServiceClientException.Message);
}
static void Main(string[] args)
{
try
{
MainAsync().Wait();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
Console.ReadLine();
}
private static async Task MainAsync()
{
Console.WriteLine("Authenticating with AAD...");
//AuthenticationConfig config = AuthenticationConfig.ReadFromJsonFile("appsettings.json");
string bearerToken = await GetAuthenticationHeader();
var context = new Resources(new Uri($"{baseURL}/data/"));
//Example to make all the OData requests cross-company, otherwise you will only reference records in the default company
context.BuildingRequest = (sender, eventArgs) =>
{
var uriBuilder = new UriBuilder(eventArgs.RequestUri);
var paramValues = HttpUtility.ParseQueryString(uriBuilder.Query);
if (paramValues.Get("cross-company") != null)
{
//Console.WriteLine("Note: cross-company parameter already present - removing");
paramValues.Remove("cross-company");
}
paramValues.Add("cross-company", "true");
uriBuilder.Query = paramValues.ToString();
eventArgs.RequestUri = uriBuilder.Uri;
};
//Add authorization token. This should be requested from AAD programatically, expiry managed, etc.
context.SendingRequest2 = (sender, eventArgs) =>
{
eventArgs.RequestMessage.SetHeader("Authorization", bearerToken);
};
//Read and update a customer credit rating using DE-001 customer for example
Console.WriteLine("Reading the customer rating...");
try
{
var custCreditRating = context.CustomerCreditRatings.Where(x => x.DataAreaId == "usmf" && x.CustomerAccount == "DE-001").First();
Console.WriteLine(JsonSerializer.Serialize(custCreditRating)); //Should be the same as the response Json after creation
Console.WriteLine("Updating Customer Credit Rating...");
custCreditRating.CreditRating = "Good";
context.UpdateObject(custCreditRating);
DataServiceResponse dsr = context.SaveChanges();
var changeResponse = (ChangeOperationResponse)dsr.First();
Console.WriteLine("HTTP status = {0}", changeResponse.StatusCode); //Success is 204
var entityDescriptor = (EntityDescriptor)changeResponse.Descriptor;
var custCreditRatingUpdated = (CustomerCreditRating)entityDescriptor.Entity;
Console.WriteLine(JsonSerializer.Serialize(custCreditRatingUpdated));
}
catch (DataServiceQueryException queryException)
{
ReportODataError(queryException);
}
catch (DataServiceClientException clientException)
{
Console.WriteLine(clientException.InnerException);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.InnerException);
}
}
}
}