Saturday, January 30, 2010

Unable to obtain DNS hostname of Active Directory domain controller with ntdsa object name


Last week, my colleague tried to unregistered plug-in using Plugin Registration Tool and got above error message.Since it was very generic error message, I tried to look detail error message in Event Viewer but have no luck to find it.

One of my colleagues suggested me to check whether log-in account had deployment manager role or not. I tried to open Deployment Manager MMC and got following error message.


Below is the detail error message I got from CRM trace log.
System.DirectoryServices.ActiveDirectory.ActiveDirectoryOperationException: Unable to obtain DNS hostname of Active Directory domain controller with ntdsa object name "CN=NTDS Settings, CN=[DOMAIN CONTROLLER], CN=Servers, CN=Default-First-Site-Name, CN=Sites, CN=Configuration, DC=[CRM SERVER], DC=[DOMAIN NAME], DC=org, DC=sg".
Resolution:
When we unregistered a plug-in, CRM tried to query login user credential and role from AD. But Active Domain Controller information is pointed to Replicated AD which was no longer available at that moment. Then, plug-in registration process had assess right issue and we got "Server was unable to process request" error message.

Remove unused Domain Controller from "Active Directory Sites and Services" will help your problem. Please refer to Reference link for more information.

Reference:
Delete Failed DCs from Active Directory
Delete Failed DCs from AD.pdf

You have exceeded the maximum number of allowable lookup columns. (N:N Relationship)


Last week, my users report that they received an error when they click "Add Existing Contact" button in account entity. Below is the screen shot:


When I tried to trace the error, I found that it only happened on N:N Relationship entity. In Event Viewer, I found following error message:
Exception information:
    Exception type: IndexOutOfRangeException
    Exception message: You have exceeded the maximum number of allowable lookup columns.

Stack trace:    at Microsoft.Crm.Web.Controls.Lookup.Columns.Add(String displayName, String logicalName, String bindingName, String bindingAttribute, ColumnType type, String size)
   at Microsoft.Crm.Web.Controls.Lookup.LookupParser.ParseSectionColumns(XmlReader xmlReader, Object elementName)
   at Microsoft.Crm.Web.Controls.Lookup.LookupParser.Execute(String xml, Int32 objectType)
   at Microsoft.Crm.Web.Controls.Lookup.LookupDataPage.ConfigurePage()
   at Microsoft.Crm.Application.Controls.AppUIPage.OnPreRender(EventArgs e)
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Resolution: 
MS CRM has column limitation in Lookup View. You can show only up to 18 Columns. If you list more than that, IndexOutOfRangeException will occur when you add data to N:N Relationship entity. Remove columns from Lookup View will solve your problem.

Reference:
Account Lookup Column limit?

Monday, January 25, 2010

Download a file from URL in CRM text box



Sometimes you may want to download a file from URL showing in CRM text box. By default, when you click the URL, CRM will show content of the file in a new window (if it is a known MIME type). You can click 'Save As' from File menu to save the file. But, it is not very convenient for user to go through the whole process.  

Here is the solution:

  1. Create an ASP page (download.asp) and place it under ISV folder
  2. Attach Click Event on Text Box to download a file

Download.asp
<%@Language="VBScript"%>
<%Option Explicit%>
<%Response.Buffer = True%>

<%
On Error Resume Next

Dim strPath
strPath = CStr(Request.QueryString("file"))

'-- do some basic error checking for the QueryString
If strPath = "" Then
Response.Clear
Response.Write("No file specified.")
Response.End
ElseIf InStr(strPath, "..") > 0 Then
Response.Clear
Response.Write("Illegal folder location.")
Response.End
ElseIf Len(strPath) > 1024 Then
Response.Clear
Response.Write("Folder path too long.")
Response.End
Else
Call DownloadFile(strPath)
End If

Private Sub DownloadFile(file)
'-- Detect HTTP/HTTPS
Dim objRegExp
Set objRegExp = new RegExp
objRegExp.Pattern = "^h?[t|f]tps?://"
objRegExp.IgnoreCase = True
objRegExp.Global = True 
If objRegExp.Test(file) = True Then
objRegExp.Pattern = "([A-Za-z]{3,9})://([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((/[-\+~%/\.\w]+)?\??([-\+=&;%@\.\w]+)?#?([\w]+)?)?"
Dim matches
Set matches = objRegExp.Execute(file)
file = matches(0).SubMatches(5)
End If
'set absolute file location
Dim strAbsFile
strAbsFile = Server.MapPath(file)
'-- create FSO object to check if file exists and get properties
Dim objFSO
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
'-- check to see if the file exists
If objFSO.FileExists(strAbsFile) Then
Dim objFile
Set objFile = objFSO.GetFile(strAbsFile)
'-- first clear the response, and then set the appropriate headers
Response.Clear
'-- the filename you give it will be the one that is shown
' to the users by default when they save
Response.AddHeader "Content-Disposition", "attachment; filename=" & objFile.Name
Response.AddHeader "Content-Length", objFile.Size
Response.ContentType = "application/octet-stream"
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
'-- set as binary
objStream.Type = 1
Response.CharSet = "UTF-8"
'-- load into the stream the file
objStream.LoadFromFile(strAbsFile)
'-- send the stream in the response
Response.BinaryWrite(objStream.Read)
objStream.Close
Set objStream = Nothing
Set objFile = Nothing
Else 'objFSO.FileExists(strAbsFile)
Response.Clear
Response.Write("File not found!")
End If
Set objFSO = Nothing
End Sub
%>

Attach On Click Event (place under Form_OnLoad event)
DownloadFile = function(fileURL)
{
var url= window.location.protocol + "//" + window.location.host + "/Download.asp?file=" + fileURL;  
window.open(url,'popup','width=100,height=50,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=100,top=200');
}
crmForm.all.[attribute_name].attachEvent('onclick', DownloadFile);

Syntax Example: 
1. Download.asp?file=/SampleFiles/test.txt
2. Download.asp?file=http://localhost/SampleFiles/test.txt

Download Link:
download.asp

Reference:
Downloading any file using ASP, FSO and the ADODB Stream object

Friday, January 15, 2010

Insufficient Permissions



Sometime you may encounter insufficient permissions warning in CRM applications while you are trying to assign ownership of a record to another user. If you try to look into Event Viewer, you will only get following error message:
Exception information:
    Exception type: TargetInvocationException
    Exception message: Exception has been thrown by the target of an invocation.

To resolve the issue, please follow the steps below:

1. Please Change
to
in web.config file of your CRM application. The file is usually located under C:/Program Files/Microsoft Dynamics CRM/CRMWeb folder.

2. Please test your application again. You will get following error message instead of Insufficient Permissions warning:



3. Please take PrivilegeId from your error message and follow the instruction from my previous post.

Reference:
CRM: SecLib::CheckPrivilege failed.
Tracing and Debugging error in CRM 4.0