IFrame security problems

I recently wanted to show a dynamic SQL RS report in CRM using customization of the sitemap.

I had some problems with the dymanic functionalities of the report, which didn’t work. After some work, I found that it was due to the fact that the Reporting Server had the wrong security settings in IE, and hence was prohibited to fully use the JavaScripts that controlled the drill-down of the reports. The simple solution was to add the reporting server to Local Intranet Sites in IE.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se

How to create .NET-class files from xsd files

XML is great! But most of you who have worked with it probably pull your hair out due to all the navigational problems and code needed to navigate through the xml-structure. Wouldn’t it be neat if there was some way to create a .NET class from an xsd-schema and load it up with the contents of a specific xml-structure? Well, guess what, there is, and it is provided by our very good friends in Redmond, WA, Microsoft.

To some of you, this might be yesterday’s news, but for those of you who havn’t tried it, you should.

I will try to explain how to do it here. In this example, we’ll be basing the .NET class on a InfoPath form. InfoPath is, as you might know, just a front-end to XML, ie. a user friendly way of creating xml-data.

Create you xml-form in any way you like. I won’t go into how exactly you do that, but
That will create a schema in the background. To export it to an xsd-file, select “Save as source files…” from the file menu and direct it to a directory of your choice, for instance, “c:temp”.

Use the file explorer, go to the directory where you just saved the files, and you will find a file with the name of your different data sources followed by the extension “.xsd” in this directory. Remember the name of the xsd-file, let’s call it “source.xsd” in this example.

Then, start up a “Visual Studio 2005 Command Prompt”, go to the directory where you saved the source files, for instance:

cd c:temp

Then, using the command xsd you can create the cs-file containing the .NET-class with the following command:

xsd source.xsd /c

This will create a new file called “source.cs”. This is the file that contains the .NET class.

Now open your development project and add the file source.cs to the project. This will now give you access to the .NET class in you project. Open the file and you can see the name of your class, it should be “myFields”.

Now we want to instantiate the class with some xml-data. This is done in the following manner using c#-code.

XmlSerializer serializer = new XmlSerializer(typeof(myFields));
XmlTextReader reader = new XmlTextReader(“c:XmlInstanceOfSourceXsd.xml”);
myFields fields = (myFields)serializer.Deserialize(reader);

Now, you can access the xml-data using the instance fields of the class myFields.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se

News about Titan

Microsoft has released some more news about Titan, the codename for the next version of MS CRM, 3.5, 4 or 5, only the future will tell what it will be called 🙂

In the article from MS (click the heading of this post) they mention that they are planning to release Titan in mid 2007. The last release for version 3, was actually ahead of schedule so, I believe we could actually expect it to arrive in Q3 2007.

Some of the new features that are rumored to be found in Titan are multi-language (in the same installation) and multi-currency. Features that will enable MS CRM to move into the league of the more international companies.

When I hear more, I will surely let you know!

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se

How to create an CRM email with a report server attachment as a pdf

In Microsoft CRM there are several methods to create great looking documents with mailmerge and the crm emails can be created with dynamic data. However, it is quite complicated to create automatic mails with data from one main entity and several sub entities. The most common example being an order confirmation, with data from both the order head and the order detail lines.

To make it a bit flexible, I created a function that could be called from the workflow engine.

Here is the method declaration that I will use bellow:

public string SendMailWithReport(System.Guid OrderId, string subject, string body, string reportpath, string callerXml)

The parameters are as follows:
OrderId – A Guid containing the orderid to be used as a parameter to the report.
Subject – a string that will contain the mail subject.
Body – a string that will contain the mail body
Reportpath – to make it a bit more flexible, the report path is not hard coded but can be inputed as a parameter,
callerXml – standard handling for getting the caller data to enable impersonation.

The first thing we want to do is to get the pdf from the report server.

We’ll store the binary pdf in the byte-array called result. When this is done, we’ll encode this into a string called encoded data. The rest is stuff that is needed to make this happen.

string encodedData = “”;

//Create Report PDF
ReportingService rs = new ReportingService();
rs.Credentials = new System.Net.NetworkCredential(username, passwd, domain);
Byte[] result;

string encoding;
string mimetype;
ParameterValue[] parametersUsed;
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = “CRM_OrderId”;
parameters[0].Value = “{” + OrderId.ToString() + “}”;

Warning[] warnings;
string[] streamids;

result = rs.Render(reportpath,
“PDF”,
null,
null,
parameters,
null,
null,
out encoding,
out mimetype,
out parametersUsed,
out warnings,
out streamids);

encodedData = System.Convert.ToBase64String(result);

The most complex part of this which took me the most time, was the “Render” method of the reporting server web service. I use it this way because it works, don’t ask me what all the parameters really are, I don’t know.

The next part is to create the CRM mail. This is quite straight forward, if you are used to the crm web service.

The “from” and “to” can be set to anything that can be used as a “to” or “from” in the CRM GUI.

CrmService service = new CrmService();
service.CallerIdValue = new CallerId();
service.CallerIdValue.CallerGuid = GetCaller(callerXml);
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

//Get current user
WhoAmIRequest userRequest = new WhoAmIRequest();
WhoAmIResponse user
= (WhoAmIResponse) service.Execute(userRequest);

//Load salesorder and account objects.
salesorder so = (salesorder)service.Retrieve(EntityName.salesorder.ToString(), OrderId, new AllColumns());

account acc = (account)service.Retrieve(EntityName.account.ToString(), so.customerid.Value, new AllColumns());

email em = new email();
activityparty from = new activityparty();
from.partyid = new Lookup();
from.partyid.type = EntityName.systemuser.ToString();
from.partyid.Value = user.UserId;
em.from = new activityparty[] {from};

activityparty toparty = new activityparty();
toparty.partyid = new Lookup();

toparty.partyid.type = EntityName.account.ToString();
toparty.partyid.Value = acc.accountid.Value;

em.to = new activityparty[] {toparty};

em.subject = subject;
em.sender = “test@test.com”;
em.regardingobjectid = new Lookup();
em.regardingobjectid.type = EntityName.salesorder.ToString();
em.regardingobjectid.Value = so.salesorderid.Value;

em.description = body;
em.ownerid = new Owner();
em.ownerid.type = EntityName.systemuser.ToString();
em.ownerid.Value = user.UserId;

Guid createdEmailGuid = service.Create(em);

Now, we have created the email. You can see it in CRM if you like.

The last part is now to create the attachment on the email as the pdf that we downloaded from the report server in the first part of this walk-through.

activitymimeattachment ama = new activitymimeattachment();
ama.activityid = new Lookup();
ama.activityid.type = EntityName.email.ToString();
ama.activityid.Value = createdEmailGuid;
ama.body = ” “;
ama.mimetype = “application/pdf”;
ama.attachmentnumber = new CrmNumber();
ama.attachmentnumber.Value = 1;
ama.filename = “A filename”;
Guid createdAttachment = service.Create(ama);

//Upload file
// Create the Request Object
UploadFromBase64DataActivityMimeAttachmentRequest upload = new UploadFromBase64DataActivityMimeAttachmentRequest();

// Set the Request Object’s Properties
upload.ActivityMimeAttachmentId = createdAttachment;
upload.FileName = “attachmentfilename.pdf”;
upload.MimeType = “application/pdf”;
upload.Base64Data = encodedData;

// Execute the Request
UploadFromBase64DataActivityMimeAttachmentResponse uploaded = (UploadFromBase64DataActivityMimeAttachmentResponse) service.Execute(upload);

The last part, if you want to, is to send the mail:

SendEmailRequest req = new SendEmailRequest();
req.EmailId = createdEmailGuid;
req.TrackingToken = “”;
req.IssueSend = true;
SendEmailResponse res = (SendEmailResponse)service.Execute(req);

I have made some simplifications, like removing try-catch clauses, which you really should use, but the code has apart from that been cut-n-pasted from a working application and should work.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se

A question from a CRM admin

I recieved this question by email from one of the readers of this blog and thought that I might aswell let all of you in on the answer. (I’ve take the liberty to remove his name and to correct a few typos).


Hi Gustaf,
Let me introduce myself, I am XXX new to MS CRM. I got your mail id through your blog.I am mailing you as we have a urgent query with respect to mscrm. We have a company domain, which is being used by the entire organisation, now if i am going to install MS CRM 3.0 Server setup do we need to have a different domain/domain controllers for the CRM. Are their any issues which must be taken care of before going ahead, as we will be dealing with the live domain. The objective of this is to integrate with sharepoint technologies. I will be thankful for your earlier response.

Regards, XXX

—- My answer:

Hi,
When you install MS CRM 3 it will add a few groups to the AD, but apart from that will not touch the AD. MS CRM:s user handling and security information is stored in the MS CRM database hence no need for further schema extensions of the AD.

I understand your concern when installing on a live domain but there should not be any problems. If you still feel a bit worried, you can always install MS CRM in a virtual environment and see the changes for you self.

The live CRM server should be installed in the company domain.

Kind regards,
Gustaf

——

If your question is in regard to something I’ve posted on the blog, please add it as a comment, otherwise, you can always mail me. Please note that I will gladly answer technical questions like the one above but it is not feasable for me to design you solution. If you want my help in that aspect, please contact Humandata (www.humandata.se) and we can get you a good deal. I hope you appreciate that even I need to have a house to live in and food for my family 🙂

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se

Back again – with a question

Well, as some of you might have noticed, not much has happened on this blog for the last 3 weeks which has been due to the fact that I’ve been on my honeymoon in Thailand and frankly didn’t start CRM och SharePoint even once :).

I’ve tried to find out a bit more about the upcoming integration engine CRM-Nav from Microsoft but have not been very successful. The main question is what kind of infrastructure it will be based on and I think the following three are the hottest tips:

1. Celenia/Tectura – The integration formerly known as Tectura, (see my previous postings), now called the Celenia CRM-Nav integration, has previously been put forward by Microsoft as THE integration engine to use.

2. BizTalk based integration – BizTalk is the talk of the town concerning integration, and it would not be very strange if the integration would be BizTalk based.

3. New/Custom – They might just have sat down and started from scratch and written an integraiton engine specifically for CRM-Nav.

Well, where’s my money? To start off, Microsoft have been very very quite about this integration engine, would seem a bit strange if the engine would be according to 2 or 3 above, when there really would be no reason for that.

However, if they are up to an aquisition of Celenia or just the program, then they would probably like to be just very very quite about it until all the formalities had been settled.

Another reason for not going along with 2, the BizTalk version, is that it would require an installation of BizTalk at each customer which might cause more problems and costs than what is reasonable.

One reason for not choosing 3 is that it most probably will be quite costly.

Something to take into consideration in the Celenia business is that the integration engine was previously owned by Tectura (although it had been developed by Celenia) but for reasons unknown to me, was reverted to Celenia. Most probably after considerable preasure from Microsoft.

Bottom line, my money is on the Celenia integration (1). Which versions of Nav it will support is still unknown and if it will still only be a technical integration is also still unknown, when I learn more, I will let you know.

Gustaf Westerlund
CRM and SharePoint Consultant

Humandata AB
www.humandata.se