Any C#/MS CRM developers here?

Author
Discussion

Z064life

Original Poster:

1,926 posts

250 months

Friday 8th February 2008
quotequote all
I'm a fairly good user of C# but I'm new to CRM and the SDK. I know there are C# developers here as it's a popular language but mscrm development is more specialised. As a result, I'm on a mission to learn as much as I can to help me so I have these questions:


1) How can I pass parameters into an event handler? I'm using .NET 1.1. The problem is if an event handler calls a function which takes parameters.

2) I need to retrieve columns from 2 entities - contact (multiple) and account (single). What I need to do is write these to a csv file. I can open the file but, as I have stored each column attribute into a string variable (all columns retrieved being of type string), the file just says system.string[] (the type).

How can I actually write the real value of each attribute into the file (ie for phone nu mber, 020348384 or whatever it may be). As I store the columnset into a string variable I only get the methods and properties of a string. I'm fine with the streamwriter part of this, but not the retrieval.

I know this is to do with using the businessentitycollection object and iterating through this but despite everything I've tried I've been unsuccessful.

3) In a retrieve single, I need to set the GUID. Problem is, the ID for each entity is of type Key but I want a GUID. How can I successfully cast this into GUID and then pass it into the retrieve statement? I know it's all to do with casting but this is one of my weak areas.

I keep getting object reference not set to an instance of an object errors. Do I also have to pass the var as a function parameter? Which brings me back nicely to point 1...

I will post code samples up to aid these questions, soon.

Thanks

m12_nathan

5,138 posts

261 months

Friday 8th February 2008
quotequote all
1)For event handling and passing parameters look at the how the framework is written where every event handler accepts (Object sender, EventArgs e) - the clue is in there biggrin

2)Can you past your csv code?

3)If the key is actually of GUID type then you can try casting it explicitly in a try catch block so GUID g = (GUID)keyvalue. There are implimentations of GUID.tryparse out on the interweb if you'd prefer to use that method.


Z064life

Original Poster:

1,926 posts

250 months

Friday 8th February 2008
quotequote all
1) I've looked at event handler arguments and all sorts of things including delegates but when I pass parameters into those brackets, I get a whole load of complaints. I've tried to find the answer from reading loads of .net 1.1 books but I can't find the answer.

2) I will paste the code to this soon, as the code is on my work laptop.

3) I've tried casting, and Guid actually takes a string overload. In your example I assume keyvalue would be a variable pointing to the field which is of type key, which I can set tostring and save in a string variable.

I hope my questions make sense, as they are not all strictly general c# related.

m12_nathan

5,138 posts

261 months

Friday 8th February 2008
quotequote all
Create your own type that inherits from System.EventArgs, use that to pass the data around.

What error do you get when casting?

Z064life

Original Poster:

1,926 posts

250 months

Friday 8th February 2008
quotequote all
How do I do that? Is there an example anywhere on the net?


The error I get is the classic "object reference not set to an instance of an object". The cause is simple to understand but the solution is hard to find (probably due to my inexperience anyway I guess).

m12_nathan

5,138 posts

261 months

Friday 8th February 2008
quotequote all
Can you create a very small console app that has the same problem casting from your original type to a GUID?

http://www.csharphelp.com/archives/archive51.html has an example of creating your own eventags class to allow you to pass the required information.

Z064life

Original Poster:

1,926 posts

250 months

Saturday 9th February 2008
quotequote all
I have a retrieve statement which retrieves an entity from crm and takes a Guid. Problem is, the unique ID for the entity is a Key field and I need to pass this as a Guid. The key field can be stored as a string variable and be written as string AcID = accountid.Value.ToString();

The Guid object has an overload which accepts a string overload so I can pass the AcID variable in.

But in the retrieve statement, which basically includes the entity, columns to retrieve, and UID, it won't take the string. I get errors such as cannot convert from one type to another, implicitly or non-implicitly, and so forth.

I stored the field as a string var
But what I need to do is convert object Key into Guid - how?
Then I can call it in the retrieve statement



The CSV file writing functionality has a function. I use a business entity collection which contains all the business entities. Properties include:

BusinessEntities
EntityName
MoreRecords
PagingCookie

Casting looks like this:

contact ContactsEC = (contact) BEC.BusinessEntities[Cntr];

This code comes from the example of looping through the collection and casting to contact. What I need to do is retrieve all the contact attributes and write them to a file. I need a do while loop and to cast the collection to contact but I keep getting errors @ runtime. I have the methods to write to file.

Example of code:


//Populate the business entity collection, and then loop through it

//Instantiate the BusinessEntity Collection here
BusinessEntityCollection BEC = new BusinessEntityCollection();


//Columnset is instantiated here
ColumnSet cols = new ColumnSet();

//Setup a counter
int Incrementor = 0; Incrementor++;

//Loop through the Business Entity Collection




int Cntr = 0; Cntr++;

do

{




CrmService serv = new HGCSV.mscrmredep.CrmService();
serv.Credentials = System.Net.CredentialCache.DefaultCredentials;


cols.Attributes = new string[] {"address1_addresstypecode", "address1_city", "address1_county", "address1_country", "address1_fax", "address1_line1", "address1_line2", "address1_line3", "address1_name", "address1_postalcode", "address1_postofficebox", "address1_primarycontactname",
"address1_stateorprovince", "address1_telephone1", "address1_telephone2", "address1_telephone3",
address1_upszone", "address2_addresstypecode", "address2_city", "address2_country"};

ConditionExpression condition = new ConditionExpression();
condition.AttributeName = "jobtitle";
condition.Operator = ConditionOperator.Equal;
condition.Values = new string [] {"CEO", "CFO"};
QueryExpression query = new QueryExpression();
query.EntityName = EntityName.contact.ToString();
query.ColumnSet = cols;
BEC = serv.RetrieveMultiple(query);




}while(Incrementor <= BEC.BusinessEntities.GetUpperBound(0));
contact ContactsEC = (contact) BEC.BusinessEntities[Cntr];

I've been told to loop through the collection, cast to contact, do the retrieve (that's the cols and queryexpresion bit), and then store the results in a string variable (I have a string variable pointing to cols.attributes.tostring();

I don't expect much luck on this query as it's quite specific to crm. Do you work on crm or just general c#?

Thanks for your help!

m12_nathan

5,138 posts

261 months

Saturday 9th February 2008
quotequote all
cols.attributes.tostring() will just return the type of cols.attributes (a string array).

If you want the values contained within that array you'll have to iterate through them, ie

foreach (string attributeValue in col.attributes)
{
console.writeline("value is "+attributeValue);
}




As for the retrieve statement - you need to pass in a GUID, not a string. Just because GUID has a constructor that will take a string it doesn't mean that the 2 types can be swapped around arbitrarily . Either create a GUID from the string on the line before and pass that in or do it within the method call. You'll have to make sure it is in a try catch block incase the cast fails.

so either

GUID userGuid = new GUID(accountid.Value.ToString());

and then pass userGuid into the retreive method.

or call

retreive(whatever, whatever, new GUID(accountid.Value.ToString()), whatever);

First option has the benefit of being able to see a GUID has been generated easily during debugging.

Z064life

Original Poster:

1,926 posts

250 months

Saturday 9th February 2008
quotequote all
m12_nathan said:
cols.attributes.tostring() will just return the type of cols.attributes (a string array).

If you want the values contained within that array you'll have to iterate through them, ie

foreach (string attributeValue in col.attributes)
{
console.writeline("value is "+attributeValue);
}




As for the retrieve statement - you need to pass in a GUID, not a string. Just because GUID has a constructor that will take a string it doesn't mean that the 2 types can be swapped around arbitrarily . Either create a GUID from the string on the line before and pass that in or do it within the method call. You'll have to make sure it is in a try catch block incase the cast fails.

so either

GUID userGuid = new GUID(accountid.Value.ToString());

and then pass userGuid into the retreive method.

or call

retreive(whatever, whatever, new GUID(accountid.Value.ToString()), whatever);

First option has the benefit of being able to see a GUID has been generated easily during debugging.
Thanks so much for that. The foreach loop makes so much sense I don't know why I never thought of that myself. I thought I could only use a foreach loop with an array but I guess that's just my naivety. So now I can use say foreach attribute, write to file, using the streamwriter functionality I have.

I did have a foreach loop which would delimit characters, by having an array and then replacing each character with the character and a set of quotation marks but this threw runtime errors of object reference not set to an instance of an object.


GUID userGuid = new GUID(accountid.Value.ToString());

I tried this but no luck. Hmm I will try again.