The CRM Grid – A Microsoft CRM Blog

Greg Owens’ rose-tinted MS-CRM mumblings

Archive for MSCRM

Event execution order with ‘onbeforeunload’

Recommended JavaScript Book!

I'd also like to highly recommend this JavaScript book by Douglas Crockford - it will definitely improve the quality of your JavaScript development experience!


Recently I had a requirement to conditionally add some dynamic script to the onClose event for a CRM form. Given the flexiblility demanded by the requirements, it was not practical to write script in the form’s onClose() event hander in the CRM Form Properties window. Instead, I used Internet Explorer’s attachEvent method

The problem with the attachEvent method is that the collection of functions that are appended to the event are executed in “random order”. “Random” is rarely a desirable sequence  in my experience and in this case one cannot guarantee that a custom dynamic “validation check” (for example) will be executed before the default event handler (i.e. the one that may ask “Are you sure you want to navigate away from this page?”).

Alas a simple solution is at hand, thanks to this post made by “Adios” over at CodingForums.com. The function below will effectively inject your function call before the default event handler.  Obviously this function can be easily amended to deal with any type of event but the example  below is hard-coded to deal with the “onbeforeunload” event handler.

Define this function in your form onLoad script (or somewhere in your global code, if you have adopted a custom solution for centralising your JavaScripts):

function addbeforeunloadEvent(func)
{
    var oldonbeforeunload = window.onbeforeunload;
    if (typeof window.onbeforeunload != 'function') {
        window.onbeforeunload = func;
    } else {
        window.onbeforeunload = function() {
            oldonbeforeunload();
            func();
        }
    }
}

Then use the following snippet to insert your function ahead of the default or existing event handler:

//TODO: replace myFunctionName and myParameter list to match your custom function signature
addbeforeunloadEvent(function(){myFunctionName(myParameterList);});

SSRS – checking an external image exists

SSRS supports adding external images to your reports. This is useful if, like my client, you have images stored in a SharePoint Document Library. Using some commonly-found code for structuring their document libraries, most accounts have had an image called “main.jpg” uploaded. If “main.jpg” does not exist, there are good business reasons for this.

The client required a report which should include “main.jpg”, if it exists. Otherwise no image should be present at all. The problem is that SSRS is only aware of the URL to the image as a simple string. I used SQL to construct a URL string for each record, but SSRS can’t natively detect whether an image exists at this URL or not. There is a way around this, however. SSRS allows you to embed your own custom code in your report properties. The following code checks whether an image exists at a given URL and returns true or false. This code can be called from an image control’s “Hidden” property, or combined with an expression in the image controls “Value” property to manipulate the URL:


Public Function ImageExists(ByRef URL As String) As Boolean
'Create a web request
  Dim m_Req As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(URL)   

  'Get a web response
  Try
    Dim HttpWResp As System.Net.HttpWebResponse = CType(m_Req.GetResponse(), System.Net.HttpWebResponse)
    If HttpWResp.StatusCode = System.Net.HttpStatusCode.OK
      Return True
    Else
      Return False
    End If
  Catch ex As System.Net.WebException
    If ex.Status = System.Net.WebExceptionStatus.ProtocolError Then
      Return False
    End If
  End Try
  Return Nothing
End Function

To use it, copy the code above to your report properties (Report > Report Properties… > Code), then after inserting an image control (with Image Source of “Web”), add the following code to the Hidden property (Image > Visibility > Hidden > Expression…):

=If (Code.ImageExists(FieldNameThatHoldsImageURL)=True)
  Then Return False
Else
  Return True

Any suggestions, improvements or alternative approaches are welcome!

MSCRM Update Rollup 3 is available

Just a quickie – it appears that Update Rollup 3 has been released for Microsoft Dynamics CRM 4.0.

This fixes about a dozen issues that are acknowledged in KB articles and more than 50 previously undocumented items too. The list of issues addressed can be found on KB961768

onLoad code not running

Another strange problem encountered and fixed today. The form onLoad code “suddenly” stopped working. I say “suddenly” because in fact this was a red herring and the problem turned out to be the result of a change. The symptoms were however unexpected.

Normally when a scripting error occurs in MSCRM, Internet Explorer will throw a script error dialog as the form loads (e.g. “There was an error with this field’s customized event.”):

scripterror

There was an error with this field's customized event

  Or alternatively a warning is shown at the bottom left of the Internet Explorer screen:

Error on page

Error on page

But on this occasion, there were no warnings. My first thought was to place a debugger statement into the code, but even after publishing this too failed to execute. I tried a simple alert() statement but this also failed. Odd.

Replacing all the code in the event handler with a simple alert() statement did work, so clearly this was a syntax problem, but very odd that it didn’t throw any error and in fact even blocked the debugger statement. If I were to delve deeper I’m sure I’d find that this is due to try…catch handling within the MSCRM ASPX pages…

In the end, the problem was caused by an htmlEncoded chevron character which had somehow been pasted into the javascript code (< ) while setting up a for loop.

Thanks due to Douglas Croxford’s JsLint for speeding the time to resolution somewhat.

Corrupted entity – NullReferenceException when publishing or exporting

A corrupted entity
I ran into a problem today with my client which frankly had me stumped. For some reason that I have yet to determine (though possibly related to a broken install of Update Rollup 2), the account entity got corrupted. We discovered this when somebody attempted to publish their changes to the account entity and ran into a “red” error dialog: “An error has occurred…please contact your system administrator”. This error was replicated if we tried to publish, delete any attributes from the entity or export the entity customizations. Not much scope for fixing the situation!

Troubleshooting…
After studying the server trace logs (thanks to CrmDiagTool4 and Michael Hoehne’s Trace Log Viewer for easing this process), the situation wasn’t much clearer. The underlying error was:

Request URL: http://localhost/MyOrgName/AppWebServices/SystemCustomization.asmx
Stack Trace Info: [NullReferenceException: Object reference not set to an instance of an object.]
at Microsoft.Crm.ObjectModel.OrganizationUIService.LabelLoaderAllLanguages.LoadMetadataLabel(Int32 entityType, String attributeName, ExecutionContext context)

I also did a SQL Trace using SQL Profiler on the server, but this didn’t really provide anything new at all.

So, when faced with a problem I can’t resolve myself, I turned to Google for help. I managed to find KB article 947096 which seemed very near to my problem, but sadly none of the resolution steps would help me. I then tried importing a known good copy of the account entity customizations but that failed too. At this point I looked back at the Trace Log and tried to determine what was going on “under the hood” prior to the failure…

It was clear from the logs that CRM was trying to pull in LocalizedLabel information for my entity attributes and form controls, however I couldn’t quite fathom out which attribute was causing the NullReferenceException (it seems that the last statement in the logs – MetadataProcessObject.ExecuteQuery – was successfully completing its SQL command and the following statement which was failing was not logging any parameters and therefore didn’t provide me with a “smoking gun”). In fact there were many calls to both CrmDbConnection.InternalExecuteReader and MetadataProcessObject.ExecuteQuery so clearly there was an interative loop going on. I didn’t know which mechanism within the CRM server black box was selecting the list of attributes to process, so I looked further back and found that this loop was likely being “triggered” by the FormXML property on the OrganisationUI view.

At this point everything clicked into place: the problem, somehow, was with the published version of my form (some of you may have realised this long ago). This form xml was being re-evaluated (for some reason) prior to every publish, export or delete request and then failing some integrity or logical check. Re-importing a known good copy would not help, since it would need to be published to take effect. I only had one option left – to break all the rules and manually amend the database in order to correct the corrupted FormXml property…

So here’s what I did:

Resolution
Took a backup of the current formXml property by running the following SQL statement within SQL Server Management Studio in the “_MSCRM” database (then right click on results tab and click “save as”…):


select organizationui0.ObjectTypeCode organizationui0.FormXml as 'formxml',
from OrganizationUI as organizationui0
where (organizationui0.InProduction = 1 and (organizationui0.ObjectTypeCode = 1))

Next I found my “good” copy of the customizations file. I identified the start and end node that was required in order to match the same format as the existing formXML property (the starting tags were <form><entity…>). Next I copied this xml to a new file and removed all tabs and new lines, to give a single continuous string.

I saved this xml file onto my CRM server then went back to SQL Management Studio and ran the following SQL to import this long string directly into the SQL table:

declare @xmlText varchar(max)
select @xmlText =(select * from openrowset (bulk 'c:\amendedformxml.txt',SINGLE_CLOB)x)
update dbo.OrganizationUI
set FormXml = @xmlText
where (InProduction = 1 and (ObjectTypeCode = 1))

This effectively “forced” my old formXML into a published state and magically fixed my problems. Further, once I clicked “Publish” following these steps, the formXML was consequently re-evaluated again and the hitherto unpublished customizations become published (as expected) and therefore effectively no information had been lost by importing the older xml.

Conclusion
So I still don’t know what caused this issue… I’d love to know if anyone else has had a similar situation. I’m not entirely comfortable with the way I had to fix the problem either, but then sometimes your hand is forced into doing things you don’t want to do. I’ll monitor the situation and let you all know if there are any repercussions. In the meantime, the usual caveats apply – the steps above are definitely unsupported and could definitely render your CRM installation inoperable, so use the steps above at your own risk!

Minor problem after installing MSCRM 4.0 Update Rollup 2

Edit: It seems that the issue below was limited to my client’s machine only. I’ve reinstalled Update Rollup 2 and the problem went away… The rest of this post is here for reference:

It seems that there is a small bug introduced It seems that my client has encountered an issue with Update Rollup 2 for Microsoft CRM. After installing, the form labels shown in the form designer are incorrectly reading from the published entity definitions, rather than the unpublished definitions. The result of this is that if you update a field label and click save, it appears not to have worked. If you ignore this apparent effect and publish your entity, lo! The field labels are indeed automagically updated after all.

Steps to reproduce:

  1. Open any entity for via Settings > Customization > Customize Entities > …
  2. Go to Forms and Views > Form
  3. Double-click any existing field and change the Label attribute then click OK
  4. At this point, the amend appears correctly
  5. Click the Save button on the form
  6. Note that your label amendment appears to have been backed out…(!)
  7. Close the form designer screen and from the entity record, click Actions > Publish
  8. Go back to the form designer via Forms and Views > Form
  9. Note that your label amendment has indeed persisted and is now also in production too

Edit: so we fixed this by removing UR2, rebooting, downloading UR2 afresh, reinstalling UR2 and rebooting again. Can’t imagine what failed – perhaps I had an early release of Update Rollup 2 with a bug – I seem to recall that it was silently reissued shortly after release.

Microsoft CRM Event Management Accelerator released!

Great news – the much anticipated CRM Accelerators are finally starting to be released!

Initially there were two releases available on PartnerSource only, but now more code is appearing on Codeplex too: http://www.codeplex.com/crmaccelerators - specifically, we can now get our hands on the first really exciting one – the Event Management accelerator. This doesn’t appear to have been publicised so well just yet so I thought I’d shout up!

At the time of writing, it is now possible to download the following:

  • Event Management (Codeplex only at present)
    “Ability to manage the planning, execution, tracking and reporting requirements for events…” including an example external website allowing delegates to register themselves on your events and reports to measure effectiveness of your events.
  • Notifications
    Subscriptions to business events (e.g. new leads for current user) which are delivered via RSS feeds
  • Extended Sales Forecasting
    Primarily, new reports to allow better visibility of sales forecasts, including individualised sales pipeline and per salesperson performance against forecast by time period

Happy playing!

Mail merge with CRM Web Client fails – cannot find data source

We ran into an issue last week where attempts to mail merge (specifically the “Print Quote for Customer” button) were failing. CRM would provide a Word document for download, but opening the document resulted in a warning:

Opening this document will run the following SQL command:

This message was followed with… no SQL command. Clicking on “Yes” to continue, presented the message:

Mail_Merge_<random numbers>.doc is a mail merge main document. Word cannot find its data source, .

Mail_Merge_.doc is a mail merge main document. Word cannot find its data source, .

No matter which templates were selected or which permissions were granted, the same error occurred.

This seemed to happy with machines that had the web client only (unconfirmed, but I believe this does not happen with the Outlook CRM client) and Office 2007 SP1.

A call to Microsoft support has verified that this is known issue, albeit undocumented for the public. It seems that Service Pack 1 for Office 2007 introduces an issue for mail merging from the web client. Apparently a hotfix is in the making but this is not being considered as a high-priority fix.

If you know of any workarounds let me know. If you have the problem yourself, get in touch with Microsoft and let them know so we can get a hotfix moved up their to-do list!

Debugging plug-ins in v4.0 (Updated)

(Updated 9th June 2009)

As you will know, the extensibility model for Microsoft CRM has changed in v4.0 and we now have a concept of plug-ins (instead of the callouts that were used in v3.0).

I’m not a particularly seasoned C# developer but having got a comfortable grasp of the language, I was struggling when it came to debugging my plug-in. I knew the general principles of debugging and thanks to the plug-in registration tool, could get my code to fire, but I couldn’t get it to debug. I can now and here’s what I did (note – no revelations here, I’m simply writing this for the benefit of other n00bs).

Please note, I still use Visual Studio 2005. I haven’t done this in any other version so there’s no point in me trying to write about it – please comment if you have and whether these steps differ.

  • So you’ve finished coding and are ready to deploy your assembly. Step one is to build your project via the Build… menu in VS.
  • Next you need to deploy your assembly to the development server. You’ll need to use the Plugin Registration Tool to do this. I usually opt to deploy to the database as this avoids me having to deal with “file in use” errors (see below).
  • In addition to deploying your assembly you must also place the debug symbols (.pdb file)  in  …\Program Files\Microsoft CRM\Server\bin\assembly. Once you’ve built your solution in Visual Studio, ensure that the latest copy of the .pdb file (look in your solution’s build directory) is copied to the aforementioned directory.  Every time you (re)build your  assembly you must copy the revised pdb file across.
  • After copying the pdb file, you’ll need to restart IIS using the iisreset command from the command prompt.  This is required so that the symbols can be read in (this step is also necessary sometimes in order to avoid “file in use” errors if you choose to deploy your assembly dll to disk) .  I usually add an iisreset command into my Post-Build script in Visual Studio, along with an xcopy command, to move the pdb file to the correct location after each build.
  • After running iisreset, you need to effectively “kick start” the CRM thread  by simply opening or refreshing any CRM page. This ensures that the w3wp process is available for the debugger to attach to.
  • The next step is to load your solution file up on the server. This of course requires Visual Studio to be installed on the development server. There may be alternatives to this approach (perhaps remote debugging or a test harness – see below) but I haven’t tried them.
  • With your solution open on the server, select Debug > Attach to Process and then select the w3wp.exe process from the the list. You may need to place a check in the “Show Processes from all users” and “Show processes in all sessions” in order to see w3wp.exe.
  • If you haven’t already done so, add some breakpoints to your code in VS by moving the cursor to the code you wish to break on and pressing [F9]. A red dot should appear in the margin.
  • Finally, go to CRM and do whatever is required (as per your plug-in registration) to fire your plug-in (i.e. create/delete/update an appropriate record)
  • The code should fire and reach your breakpoint in Visual Studio. You can step through the code a line at a time by press [F11] to advance to the next statement.

You might also be interested to hear that Akezyt Janedittakarn wrote on the MSCRM Team Blog about steps to aid the debug process using a test harness 

I’ve just found this article at sadev.co.za on how to debug CRM plug-ins remotely.

Microsoft CRM Development Environment (Part 2)

Part 2 of more than one post on the CRM Development environment.

I hope this post will prompt you to share your experiences of these tools and hopefully suggest others that may assist me and other readers with the CRM developments…


Useful Utilities

  • What is it?
    Joris Kalz’s Microsoft CRM Caching Tool
    What does it do?
    This simple utility runs as a Windows service on your (development) CRM server. Periodically it will ping a whole list of MS CRM URLs on your server and consequently keeps the web services “warm”. This is especially useful when the server has been rebooted and you’re accessing CRM for the first time.
    Where do I get it?
    Microsoft CRM Caching Tool (Joris’ blog)
  • What is it?
    Internet Explorer Developer Toolbar
    What does it do?
    This invaluable utility is simply a must-have if you are doing any clientside scripting for CRM. It’s a plug-in for Internet Explorer that provides a new toolbar that allows you to easily explore the DOM of any page you are looking at. After installing this utility, you can click on any object on the screen and see full details of its properties and CSS attributes. Furthermore you can even change some of these properties and see instant feedback on your screen.
    Where can I get it?
    The Internet Explorer Developer Toolbar (Microsoft Download Center)
  • What is it?
    Microsoft Script Debugger
    What does it do?
    It helps… debug scripts. Ok so that’s pretty self-evident. The point here is that IE does not come out of the box with a debugger for when clientside script. Although rudimentary, MSD gets the job done and is a lot more useful than deciphering a vague “Object Expected” error message!
    Where can I get it?
    The Microsoft Script Debugger (Microsoft Download Center)
    Further Reading
    Jonathan Boutelle has an excellent post on using the Script Debugger which is worth a quick read if you’ve not used it before.
  • What is it called?
    CrmDiagToolTurbo
    What does it do?
    This is a tremendously helpful tool that comes into its own when you encounter those infuriating “Contact your System Administrator” error messages. This tool turns all manner of logging and tracing on for your CRM Server and outputs reams of useful, readable plain text. All of the logs it creates can, I believe, be forced into being by changing the registry and a few other places, but this is all neatly handled in a simple winforms application. Perhaps the most useful element (in my experience) has been the ability to get full SOAP tracing from the MSCRM Services since you are then able to view the raw error message that lies behind bland end-user error messages (key violations for example).
    Where can I get it?
    CrmDiagToolTurbo and CrmDiagToolTurbo4 (Benjamin’s blog)
  • What is it called?
    JSLint
    What does it do?
    As far as I’m concerned, despite the fact that it is an insufferable pedant for syntax (probably a good thing, considering its purpose in life!), JSLint helps me to spot those simple but frustratingly impossible to spot syntax errors in your JavaScript code (missing or extra brackets are good examples!). Officially, it’s “a JavaScript program that looks for problems in JavaScript problems”. And it’s free (and nothing like as I,Robot as it may sound!)
    Where can I get it?
    You can’t “get” it, but can use it from Douglas Crockford’s site
  • What is it called?
    SQLInform
    What does it do?
    Hot on the heels of JSLint, how about something similar for your SQL code? It’s not quite a syntax checker, rather it “beautifies” your SQL code by applying regular formatting. I find this particularly useful when working with Reporting Services reports, where the IDE has a charming habit of reformatting all of your nicely structured SQL code into a contiguous ugly blob of words. Fine if you’re a computer but hard as heck to read and amend…SQLInform is Java based and can run in your web browser or there’s also a standalone version for while you’re on the train ;)
    Where can I get it?
    See Guido Thelen’s site for the hosted and downloadable versions
  • What is it called?
    TextPad
    What does it do?
    It is a plain old text editor. We all have our favourites and Textpad is mine. Some of the things I really like about it:

    • Regular expression based searches, within files and across directory trees
    • Macro support
    • Downloadable/customisable syntax files
    • Option of Microsoft-a-like shortcut keys

    Where can I get it?
    It’s not free, but it’s not pricey either (£16.50). See www.textpad.com

  • What is it called?
    HTML Match
    What does it do?
    It’s a visual differencing tool, designed for web pages but perfect for comparing all sorts of other (non-binary) files. I’ve found this useful when comparing lengthy program output during testing, muddled file versions when developing Javascripts and even for troubleshooting unexpected problems in Exported Customisation XML files.
    Where can I get it?
    Another really cheap tool at US$ 27.50. See http://www.htmlmatch.com/
  • What is it called?
    The Microsoft CRM forums
    What does it do?
    Often, all the things you can’t do yourself! There are three busy forums full of knowledgeable professionals and just as importantly, others with less knowledge but asking the questions you want the answers to! The forums are a trove of information and a brief search across the topics will often find an answer to the majority of CRM questions that occur.
    Where can I get it?
    Links to all three forums are available here

I’m sure there will be other things that occur to me for this list, but please comment to add your own to this discussion :)

Older entries »