System.InvalidCastException Dynamics CRM - c#

I have a code that creates or updates an account. This block of code calls another method that saves the accountid on the contact record once it is chosen as the primary contact of the account.
However, when I try to run this, I am receiving this error:
An exception of type 'System.ServiceModel.FaultException`1' occurred in Microsoft.Xrm.Sdk.dll but was not handled in user code
Additional information: System.InvalidCastException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #06B9DDED
It happends around the Update I do on the UpdateAccountNameContactEntity method. I've read a couple of sites, saying it might be the Guid I'm using, but I'm very new to this and I don't know how should I fix it.
I'm using ASP.NET MVC and Dynamics 365 right now. I have used this as my guide to create this.
Here is the code.
public void SaveAccount(AccountEntityModels objAccountModel)
{
using (OrganizationService service = new OrganizationService("CRM"))
{
Entity AccountEntity = new Entity("account");
if (objAccountModel.AccountID != Guid.Empty)
{
AccountEntity["accountid"] = objAccountModel.AccountID;
}
AccountEntity["name"] = objAccountModel.AccountName;
AccountEntity["telephone1"] = objAccountModel.Phone;
AccountEntity["fax"] = objAccountModel.Fax;
AccountEntity["websiteurl"] = objAccountModel.Website;
AccountEntity["primarycontactid"] = new Microsoft.Xrm.Sdk.EntityReference { Id = objAccountModel.PrimaryContact.Id, LogicalName = "account" };
if (objAccountModel.AccountID == Guid.Empty)
{
objAccountModel.AccountID = service.Create(AccountEntity);
UpdateAccountNameContactEntity(objAccountModel.AccountID, objAccountModel.PrimaryContact.Id);
}
else
{
service.Update(AccountEntity);
UpdateAccountNameContactEntity(objAccountModel.AccountID, objAccountModel.PrimaryContact.Id);
}
}
}
public void UpdateAccountNameContactEntity(Guid accountId, Guid contactId)
{
using (OrganizationService service = new OrganizationService("CRM"))
{
try
{
Entity contactEntity = new Entity("contact");
contactEntity["contactid"] = contactId;
contactEntity["parentcustomerid"] = accountId;
service.Update(contactEntity); //THIS IS WHERE I GET THE ERROR
}
catch (Exception ex)
{
}
}
}

You are trying to assign GUID in EntityReference.
Change this line
contactEntity["parentcustomerid"] = accountId;
like below:
contactEntity["parentcustomerid"] = new Microsoft.Xrm.Sdk.EntityReference { Id = accountId, LogicalName = "account" };

Related

How to insert the value of custom field while creating the entity record?

I'm facing a problem about how to insert the custom field value through create a new systemuser.
In Microsoft CRM system, there has systemuser table and I have a custom field named "SSOID", and the value of "SSOID" I get it from webapi.
My requirement is when I am in systemuser creation page in CRM, I enter the domainname value to the domainname textbox, the other fields like firstname, lastname and businessID will auto populated base on domainname. They come from active directory.
And meanwhile I also call the webapi to get the SSOID base on domainname.
What I want is after I click the save button, the new systemuser should be create and the SSOID also should be insert along with new systemuser.
But now when I click the button, some error happened
usersettings With Id = 5ab7eb74-511a-ea11-810b-005056ba5450 Does Not Exist
Below is my code, it looks very simple, but some error happened;
IPluginExecutionContext context;
IOrganizationServiceFactory factory;
IOrganizationService service;
// 获取执行上下文
context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// 获取服务工厂
factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// 获取服务
service = factory.CreateOrganizationService(context.UserId);
if (context.MessageName.ToLower() == "create"
&& context.InputParameters.Contains("Target")
&& context.InputParameters["Target"] is Entity)
{
try
{
var domainName = "";
Entity entity = (Entity)context.InputParameters["Target"];
if (context.Depth > 1)
{ return; }
if (entity.Attributes.Contains("domainname"))
{
domainName = entity["domainname"].ToString();
}
var SSOId = " get from webapi";
if (!string.IsNullOrEmpty(SSOId))
{
var businessEntityRef = (Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["businessunitid"]);
var businessunit = service.Retrieve(businessEntityRef.LogicalName, businessEntityRef.Id, new ColumnSet(true));
entity["businessunitid"] = businessEntityRef; // businessunit id is look up field comes from businessunit reference table
entity["domainname"] = entity["domainname"];
entity["lastname"] = entity["lastname"];
entity["firstname"] = entity["firstname"];
entity["new_ssoid"] = SSOId;
service.Update(entity); //i can't use create method, it shows "The specified Active Directory user already exists as a Dynamics 365 user"
}
else
{
throw new InvalidPluginExecutionException("userID not exist");
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message);
}
}
I'm new to CRM plugin development, can anyone who guide me how to solve this problem?
Please use the below code:
var SSOId = " get from webapi";
if (!string.IsNullOrEmpty(SSOId))
{
Entity entityToUpdate = new Entity("systemuser", new Guid(entity.Id));
entityToUpdate["new_ssoid"] = SSOId;
service.Update(entityToUpdate);
}
else
{
throw new InvalidPluginExecutionException("userID not exist");
}
You need to create a new instance of entity object to update after record creation (Post-create Asynchronous plugin).
Also if you throw exception when there is no error, the transaction will rollback. Think about it.

Link Account to activity CRM

I'm writing code that pulls from a db and populates the information as an activity, I'm successfully able to add fields from db to description and subject field, but I cant seem to get it to link to an account?
Here is what i have tried;
foreach (var phoneNumber in phoneNumbers)
{
var potentialMatches = _xrm.AccountSet.Where(account => account.Address1_Telephone2.Equals(phoneNumbers)).ToList();
if (potentialMatches.Count > 0)
{
var accountMatch = potentialMatches.First();
var actualCRMAccount = (Account) _xrm.Retrieve("Account", accountMatch.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
if (actualCRMAccount != null)
{
//Is this correct way?
new ActivityParty()
{
PartyId = new EntityReference(Account.EntityLogicalName, actualCRMAccount.Id)
};
activityParties.Add(new ActivityParty() {Id = actualCRMAccount.Id});
}
}
}
//RegardingObjectId not working
//RegardingObjectId = new EntityReference(Account.EntityLogicalName, recordRow.Cells[0].Value.ToString);
newMsg.To = activityParties;
newMsg.Description = recordRow.Cells[0].Value.ToString();
newMsg.Subject = recordRow.Cells[2].Value.ToString();
_xrm.Create(newMsg);
EDIT 1:
When i run it now im getting this warning
An unhandled exception of type 'System.ServiceModel.FaultException`1' occurred in Microsoft.Xrm.Sdk.dll .
Additional information: The entity with a name = 'Account' was not found in the MetadataCache.
This is the piece of code where it throws the warning
var actualCRMAccount = (Account)_xrm.Retrieve("Account", accountMatch.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
Why would this be?
Edit 2:
I replaced Account with account, see below.
var actualCRMAccount = (Account)_xrm.Retrieve("account", accountMatch.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
Edit 3:
Im now trying to do it for leads. but when i add this bit of code.
newMsg.RegardingObjectId = activityParties;
I get this error.
Cannot implicitly convert type 'System.Collections.Generic.List' to 'Microsoft.Xrm.Client.CrmEntityReference'
How can assign a value to RegardingObjectId.
Thanks for everyone's help.
The problem is that you´re adding the account via:
new ActivityParty() { Id = actualCRMAccount.Id }
To define a new ActivityParty you must set the PartyId property which is an entity reference for the chosen Type.
new ActivityParty() { PartyId = new EntityReference(Account.EntityLogicalName,actualCRMAccount.Id) }
should work.
There is a typo in the following line:
var potentialMatches = _xrm.AccountSet.Where(account => account.Address1_Telephone2.Equals(phoneNumbers)).ToList();
.Equals(phoneNumbers) should be: .Equals(phoneNumber)
Then replace the code after the retrieval of the account record with this:
var actualCRMAccount = (Account)_xrm.Retrieve("Account", accountMatch.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
if (actualCRMAccount != null)
{
activityParties.Add(new ActivityParty { PartyId = actualCRMAccount.ToEntityReference() });
}

Cannot find com.apiconnector.API in the dotMailer API for C#

I am trying to make sense of the dotMailer API for C#.
I have a class library where I intend to store the functionality that will consume the dotMailer API which references version 1.5 of the API. I also have a Service Reference set up from this WSDL
I was looking through the C# examples, but already I'm stumped! The following was pulled directly from here
Example of use in C#
/// <summary>
/// Adds a contact to an address book
/// </summary>
public void AddContactToAddressBook()
{
const string username = "apiuser-XXXXXXXXXXXX#apiconnector.com";
const string password = "password";
const int addressBookId = 1; // ID of the target address book
Console.WriteLine("AddContactToAddressBook");
Console.WriteLine("-----------------------");
// Get an instance to the web reference
com.apiconnector.API api = new com.apiconnector.API();
try
{
// we need a new contact
com.apiconnector.APIContact contact = new com.apiconnector.APIContact();
// populate the contact
contact.AudienceType = com.apiconnector.ContactAudienceTypes.B2B;
// populate the data fields
contact.DataFields = new com.apiconnector.ContactDataFields();
contact.DataFields.Keys = new string[3];
contact.DataFields.Values = new object[3];
contact.DataFields.Keys[0] = "FIRSTNAME";
contact.DataFields.Values[0] = "John";
contact.DataFields.Keys[1] = "LASTNAME";
contact.DataFields.Values[1] = "Smith";
contact.DataFields.Keys[2] = "POSTCODE";
contact.DataFields.Values[2] = "IP4 1XU";
// email address
contact.Email = "joe.smith#example.com";
contact.EmailType = com.apiconnector.ContactEmailTypes.PlainText;
contact.Notes = "This is a test only email";
contact.OptInType = com.apiconnector.ContactOptInTypes.Single;
// This method will create the contact required if it doesn't already exist within the dotMailer system,
// so we don't have to call CreateContact as a prerequisite.
//
// This method will also overwrite an existing contact, with the information provided here.
//
// This method will fail if you try to add a contact to the "Test" or "All Contacts" address books.
//
com.apiconnector.APIContact newContact = api.AddContactToAddressBook(username, password, contact, addressBookId);
// Did we get something back from the API ?
if (newContact != null)
{
Console.WriteLine("Contact added to address book {0} -> {1}", newContact.ID, addressBookId);
}
}
catch (SoapException ex) // catch any soap issues/errors from the web service
{
Console.WriteLine("Error -> {0}", ex.Message);
}
Console.WriteLine();
}
My problem is that the following line does not resolve.
com.apiconnector.API api = new com.apiconnector.API();
I have looked in namespace dotMailer.Sdk.com.apiconnector for API but it does not exist, so where is it?
Am I missing something?
Add the wsdl as a service reference. In the example below I've called it "ServiceReference1" (because that's the default and I was lazy). You then use the reference to the APISoapClient (I've called it Client) instead of "api" that you're having trouble declaring.
All compiles fine, I'm not going to execute it because I've no idea what shenanigans my random code snippet is going to cause for the server! Should point you in the right direction?
using WindowsFormsApplication1.ServiceReference1;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
const string username = "apiuser-XXXXXXXXXXXX#apiconnector.com";
const string password = "password";
const int addressBookId = 1; // ID of the target address book
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
AddContactToAddressBook();
}
private void AddContactToAddressBook()
{
using (ServiceReference1.APISoapClient Client = new ServiceReference1.APISoapClient())
{
APIContact Contact = new APIContact();
Contact.AudienceType = ContactAudienceTypes.B2B;
APIContact NewContact = Client.AddContactToAddressBook(username, password, Contact, addressBookId); // etc. etc.
}
}
}
}

Silverlight -CRM2011 : The Currency Cannot Be null

I use Silverlight o-data services to interact with crm 2011 from my application
When I try to save the data in the entity SalesOrder as follows:
Private void beginSave()
{
SalesOrder orderHeader = new SalesOrder();
orderHeader.TransactionCurrencyId = new EntityReference(){ Id = new Guid("77D695B5-ACB4-E111-97BC-00155D55B216"), LogicalName="transactioncurrency" };
orderHeader.AccountId = new EntityReference() { Id = new Guid(MyClassGeneralOrder.customerId), LogicalName = "account" };
orderHeader.Name = "My Name";
Money totalAmount = new Money(); Money totalAmountBase = new Money();
Money totalTaxe = new Money(); Money totalAmountLessFreight = new Money();
totalAmount.Value = (decimal)MyClassGeneralOrder.InvoiceTotal;
totalAmountBase.Value = (decimal)MyClassGeneralOrder.totalRetail;
totalTaxe.Value = (decimal)MyClassGeneralOrder.totalCharges;
totalAmountLessFreight.Value = (decimal)MyClassGeneralOrder.totalNet;
orderHeader.TotalAmount = totalAmount;
orderHeader.TotalAmount_Base = totalAmountBase;
orderHeader.TotalTax = totalTaxe;
orderHeader.TotalAmountLessFreight = totalAmountLessFreight;
orderHeader.Description = element.Name;
orderHeader.PriceLevelId = new EntityReference() { Id = new Guid("03C5C4CB-EBD0-E111-8140-00155D55B216"), LogicalName="pricelevel" };
_context.AddToSalesOrderSet(orderHeader);
_context.BeginSaveChanges(SaveCallback, orderHeader);
}
private void SaveCallback(IAsyncResult result)
{
_context.EndSaveChanges(result);
}
In my function EndSaveChanges (result), I receive this error message : : « The Currency Cannot Be null ».
I don't understand why, because my "orderHeader.TransactionCurrencyId" field is not null.
I assuming that all of your other Currency fields are populated?
Any chance you have another plugin that is firing as a result of yours that is throwing the exception. That always seems to bite me. Try disabling all other plugins except for the one you're working on...
If you're still having issues, turn on crm server side tracing. You'll get much better error information. Use the CRM diagnostic tool to turn on trace logging: http://crmdiagtool2011.codeplex.com
Mostly your Guid is wrong and it's resulting in null. Make sure it's the correct GUID you are using or not. Run an advanced find against the entity and find the correct GUID. It's not a good idea to hard code the GUID. If you deploy your solutions to some other org it won't work.

"Could not find transactional storage type" error with embedded RavenDB

I was able to successfully run a simple test for RavenDB based on the code found at: http://ravendb.net/tutorials/hello-world
Next I tried to run it in an Embedded Manner, but I keep on getting the following error:
Message: Could not find transactional storage type: Raven.Storage.Esent.TransactionalStorage, Raven.Storage.Esent
StackTrace: at Raven.Database.Config.InMemoryRavenConfiguration.CreateTransactionalStorage(Action notifyAboutWork) in c:\Builds\raven\Raven.Database\Config\InMemoryRavenConfiguration.cs:line 272
at Raven.Database.DocumentDatabase..ctor(InMemoryRavenConfiguration configuration) in c:\Builds\raven\Raven.Database\DocumentDatabase.cs:line 109
at Raven.Client.Client.EmbeddableDocumentStore.InitializeInternal() in c:\Builds\raven\Raven.Client.Embedded\EmbeddableDocumentStore.cs:line 130
at Raven.Client.Document.DocumentStore.Initialize() in c:\Builds\raven\Raven.Client.Lightweight\Document\DocumentStore.cs:line 388
at Tests.RavenEmbedded.RavenDB..ctor() in C:\Users\Pranav\Documents\Projects\Repositories-Clone\Common-clone\Tests\RavenDB.cs:line 114
at Tests.TestRavenDB.Basics() in C:\Users\Pranav\Documents\Projects\Repositories-Clone\Common-clone\Tests\RavenDB.cs:line 170
Setup:
Target framework is .NET Framework 4
I added the following References to my project:
\RavenDB-Build-309\EmbeddedClient\Raven.Client.Embedded.dll
\RavenDB-Build-309\Client\Raven.Client.Lightweight.dll
\RavenDB-Build-309\EmbeddedClient\Raven.Storage.Esent.dll
\RavenDB-Build-309\EmbeddedClient\Raven.Storage.Managed.dll
The code is:
namespace Tests.RavenEmbedded
{
using Raven.Client.Client;
using Raven.Client.Document;
using Raven.Storage.Esent;
using Raven.Storage.Managed;
using Tests.RavenData;
class RavenDB
{
public RavenDB()
{
// EmbeddableDocumentStore store = new EmbeddableDocumentStore { DataDirectory = #"C:\Temp\RavenData" };
//Raven.Storage.Esent.TransactionalStorage
var store = new EmbeddableDocumentStore { DataDirectory = #"C:\Temp\RavenData" };
store.Initialize();
#region Write Data
using (var session = store.OpenSession())
{
var product = new Product
{
Cost = 3.99m,
Name = "Milk",
};
session.Store(product);
session.SaveChanges();
session.Store(new Order
{
Customer = "customers/ayende",
OrderLines =
{
new OrderLine
{
ProductId = product.Id,
Quantity = 3
},
}
});
session.SaveChanges();
}
#endregion
#region Read Data
using (var session = store.OpenSession())
{
var order = session.Load("orders/1");
Debug.Print("Customer: {0}", order.Customer);
foreach (var orderLine in order.OrderLines)
{
Debug.Print("Product: {0} x {1}", orderLine.ProductId, orderLine.Quantity);
}
session.SaveChanges();
}
#endregion
}
}
}
namespace Tests
{
public class TestRavenDB
{
public static void Basics()
{
try
{
//var db = new RavenClientServer.RavenDB();
var db = new RavenEmbedded.RavenDB();
}
catch (Exception ex)
{
Debug.Print("Message: {0} ",ex.Message);
Debug.Print("StackTrace: {0} ",ex.StackTrace);
}
}
}
}
I have tried searching for this for a few days and tried a few different variations too. I am not sure what's going on.
Thanks to Ayende Rahien on groups.google.com/group/ravendb/topics.
The solution was to add "Raven.Storage.Esent" reference to the main project. It's an issue with Visual Studio and indirect references.
Thanks #Derek for suggesting that I post there.
-- Pranav
You need to add a reference to Raven.Storage.Esent.dll

Categories