.NET architecture, programming tips and tricks around Microsoft technology stack - Azure, WCF Services, SQL and strategy work.
Thursday, May 17, 2007
GhostDOC VS addin to generate XML documents...
XML comments are invaluable tools when documenting your application. Using XML comments, you can mark up your code and then, using a tool like nDoc, you can generate help files or MSDN-like Web documentation based on those comments. The only problem with XML documentation is the time it takes to write it you often end up writing similar statements over and over again. The goal of GhostDoc is to automate the tedious parts of writing XML comments by looking at the name of your class or method, as well as any parameters, and making an educated guess as to how the documentation should appear based on recommended naming conventions. This is not a replacement for writing thorough documentation of your business rules and providing examples, but it will automate the mindless part of your documentation generation.
http://www.roland-weigelt.de/ghostdoc/
After installing GhostDoc, you can right-click on the method declaration and choose Document this.
Don't stop hereyou should add additional comments stating where the person is being saved to or perhaps give an example of creating and saving a person.
Adding these extra comments is much easier since the basic, redundant portion is automatically generated by GhostDoc. GhostDoc also includes options that allow you to modify existing rules and add additional rules that determine what kind of comments should be generated.
GhostDoc was written by Roland Weigelt and can be downloaded for VS 2005, VS Orcas as well from www.roland-weigelt.de/ghostdoc
HTH, Thanks - Dipesh
Wednesday, May 16, 2007
Filtered Views in CRM 3.0
FetchXML and QueryExpression give you information from CRM database via CRM web service but FilteredViews allow you to retrieve data from CRM directly hitting the SQL. Microsoft does not recommend you to access the CRM - SQL database directly for any manipulations but if you want to just retrieve(read) the records from CRM entities(built in + custom) it's absolutely fine to do so using Filtered Views.
One of the reason we would like to use FilteredViews is because we needed information from multiple entities. You cannot use QueryExpression for that in CRM 3.0 but sure can use FetchXML.
See my previous post
The problem with FetchXML is the flat structure it returns (as i mentioned in my prev posts). With FilteredViews you have the liberty to work the way you did in SQL server. You get the power of SQL DML usage and ADO.net (can also use features like GroupBy, multiple joins easily etc.)
However do NOT attempt to insert/update records directly into CRM database.
Here's an explanation on FilteredViews -
If you were to browse the Microsoft CRM SQL database (with a tool such as SQL Server Enterprise Manager or SQL Query Analyzer), you might notice multiple data objects related to Accounts, including:
1> AccountBase table
2> AccountExtensionBase table
3> AccountLeads table
4> Account view
5> FilteredAccount view
When you want to write your own custom report about Accounts, you might wonder which of these database objects includes the information you're looking for.
Fortunately, instead of forcing you to spend hours investigating what types of entity data CRM stores and what relationship exists between these objects, CRM has simplified reporting for us by offering "filtered views". Filtered views perform the cumbersome task of denormalizing multiple tables and relationships into a streamlined view of entity and system data. In addition, filtered views respect the CRM security settings so that users who query filtered views (or run reports that query filtered views) will see only the data that they're allowed to see.
Two different users viewing the same report might see entirely different results depending on the Microsoft CRM security settings. This feature will save you hours by trying to manually determine the security and data settings of each custom report.
These objects (as listed above) are also created for all custom entities that we create in CRM.
Also, filtered views translate lookup fields and picklist values, and they calculate all datetime values in both Coordinated Universal Time (UTC) and the user's localized value.
HTP, Cheers - Dipesh
Connection string with Windows and SQL Server authentication...
ConnectionStrings.com
Quick one for .net/SQL -
Integrated Security=True - If you want to use windows authentication (takes windows credentials)
SqlConnection connection = new SqlConnection("Data Source=
Integrated Security=False - If you want to use SQL server authentication (provide user name and password and this loging shud be present in SQL 2005)
SqlConnection connection = new SqlConnection("Data Source=
Credits - Gaurav for healthy discussion. Cheers - Dipesh
IIS Logs and Log Parser utility...
Depending on the amount of traffic to your Web site, the size of your log file (or the number of log files) can consume valuable disk space, memory resources, and CPU cycles. You might need to balance the gathering of detailed data with the need to limit files to a manageable size and number. If you are planning to put thousands of Web sites on one Web server with high traffic volumes and disk writes, you might want to use centralized binary logging to preserve server resources. Also, consider limiting log size by changing the frequency of log file creation.
For more information check MS site here - http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/b344f84e-bc77-4019-859c-9d483bc85c77.mspx?mfr=true
Ok, you can convert your IIS logs into SQL database as well so that you can do more efficent reporting
Also, you can write your custom logging modules and have logs displayed on ASP page as well. Check all about IIS logging here -
Do you need a tool to do all this - "Log Parser" (command line utility) :)
Log Parser allows you to do universal query access to text-based data such as log files, XML files and CSV files, as well as key data sources on the Windows® operating system such as the Event Log, the Registry, the file system, and Active Directory®.
Download it from here -
http://www.microsoft.com/downloads/details.aspx?familyid=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en
CRM 3.0 does not have functionality inbuilt for profiling transactions? To get reports like ...which user accessed Contacts, Case or a particular page number of times or any unauthorized access we need to use IIS logs to meet the needs. Credits to Ronald for sharing this info
Thanks - DJ
Friday, May 11, 2007
MS support link on issues/hot fixes/updates in CRM 3.0
HTH - DJ
Thursday, May 10, 2007
Advanced Find to generate FetchXML for you....(single entity)
You can just open the Advanced find page and build the query as you like. Then run the query to see if it returns the data as you wish it should. If you are satisfied with the results and you want to know what query was sent into the CRM Framework, then press F11 to get the address bar and enter this script below and press enter.
javascript:prompt("my query:", resultRender.FetchXml.value);
I was able to get this working for single entity though.. for multiple entities i had a tough time. But the tool i mentioned in my earlier post http://archdipesh.blogspot.com/2007/05/how-to-retrieve-multiple-attributes.html helps me for multiple entities! Thanks - Dipesh
how to retrieve multiple attributes from multiple entities in CRM 3.0?
For all those who have tried using QueryExpression to retrieve attributes from multiple entities i am sure it is a hard try! But with no fault of your's this seems to be the limitation within CRM 3.0 as QueryExpression just returns one object. So really in CRM 3.0 if you want to return multiple attributes from more than 1 entity you will have to use the CRM 1.2 - FetchXML technique. Here's how the fetchXML looks.
Entities in example include - Property (parent) related to child Meeting Room entity and meeting room is related to Events entity.
You can use Count to restrict the number of records spitted.
Really, if you feel this is all confusing you can use James tool - http://jamesdowney.net/fetchxml.aspx to create an fetchXML for you real quick. It is free!
here's a sample code for FetchXML -
try
{
//set the CRM service instance
CrmService crmService = new CrmService();
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Retrieve the results.
string result = crmService.Fetch(fetchXML); //fetchXML is the string shown above
return result;
}
catch (System.Web.Services.Protocols.SoapException ex)
{
return ex.Message;
}
CRM gurus say that they MS will try to overcome this limitation in Titan release. Till then this workaround works fine!
1 issue i found hard to meet my requirement was that it spits back flat structure rather than defined hirearchy. The parent record( property in example above) is returned as an XMl element with every child record. I am not sure how do we achieve GroupBy similar to SQL in FetchXML?! Thanks - Dipesh
Tuesday, May 08, 2007
Writing your own Code Snippet...
http://blogs.msdn.com/arash/archive/2006/07/14/666114.aspx
This snippet in example can be used for CRM activity. Cheers - Dipesh
Creating an XML Document using XMLDom and returning string as response...
This is the XML i am trying to create -
//Create XML document
XmlDocument xmlDoc = new XmlDocument();
//Write down the XML declaration
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
// Create the root element
XmlElement rootNode = xmlDoc.CreateElement("PropList");
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
xmlDoc.AppendChild(rootNode);
//
//Create an XML element
XmlElement parentNode = xmlDoc.CreateElement("Prop");
//Create an XML attribute
XmlAttribute idAttribute = xmlDoc.CreateAttribute("PropID");
idAttribute.Value = i.ToString();
//Associate the attribute to the element
parentNode.SetAttributeNode(idAttribute);
xmlDoc.DocumentElement.PrependChild(parentNode);
//
//Create an XML element
XmlElement newCityHocn = xmlDoc.CreateElement("CityHocn");
newCityHocn.InnerText = "MEMSG";
//Add this element as an child to Prop
parentNode.AppendChild(newCityHocn);
//
//Create an XML element
XmlElement newSecFacilityID = xmlDoc.CreateElement("SecondaryFacilityID");
newSecFacilityID.InnerText = "1000121";
//Add this element as an child to Prop
parentNode.AppendChild(newSecFacilityID);
//
// Save to the XML file
//xmlDoc.Save(@"D:\test.xml");
//return string
xmlDoc.OuterXML;
If you are creating a web service and you want to return string as an response to the web method then use xmlDoc.OuterXML instead of saving to a file. String response will help non .net platforms to consume from web service as well.
Others - http://www.mastercsharp.com/article.aspx?ArticleID=69&&TopicID=9
Thanks - Dipesh
Orcas Beta 1 VPC download...Step 1
1> Download the Base image (one-time only): VSCTPBase.exe (1.12 GB)
2> Download all parts of the Visual Studio Code Name Orcas Beta 1. The first part is a self-extracting EXE and will prompt for the other parts. Find the download for OrcasBeta1VSTS_VPC_8PartsTotal.part01.exe here - (700 MB)
http://www.microsoft.com/downloads/details.aspx?FamilyId=36B6609E-6F3D-40F4-8C7D-AD111679D8DC&displaylang=en
Find the steps to follow on the above URL as well to get your VPC working... no install needed. Get going now!
Thanks - Dipesh
Monday, May 07, 2007
Code snippets for daily coding tasks...
IntelliSense Code Snippets are reusable, task-oriented blocks of code. Visual Studio 2005 includes code snippets covering tasks ranging from creating a custom exception, to sending an e-mail message, to drawing a circle. A set of Visual Basic and Visual C# Code Snippets are included in the Visual Studio 2005 box – additional Code Snippets can be found below.
http://msdn2.microsoft.com/en-us/vstudio/aa718338.aspx
Thanks - Dipesh
Saturday, May 05, 2007
Is there an easy way to change the default 5555 port CRM uses and are there any implications?
You can easily change the port settings in 2 places:
1> In IIS, go into the properties of the CRM website and enter the default port 80 or any preferred used port number.
2> In the registry under the MSCRM hive, update the ServerURL regkey.
That's it!
"You can also setup an IIS web site using the desired port prior to the install and have CRM use that website during the install vs. creating its own. There is no way to override the install’s use of 5555 for the site it creates though.
Due to some of the nuances of what CRM does with the site and how it handles host headers and such, it may be easier to uninstall/reinstall in this manner than to try to mess with the port."
Thanks to Will and Matt for explaining this. Hope this helps. Thanks - D
Thursday, May 03, 2007
ReSharper 2.5.2 Maintenance Release
The full list of changes and enhancements is available at
http://www.jetbrains.com/resharper/releaseNotes252.html?rs252nl
You can download version 2.5.2 at
http://www.jetbrains.com/resharper/download/index.html?rs252nl
The latest maintenance release features multiple bugfixes and several enhancements, which include:
- Better ASP.NET support
- Join/split string context action
- Improved stability
- New evaluation scheme
The new evaluation scheme deserves a special mention. Simply put, we've made evaluation easier by eliminating evaluation licences. Just download, install and enjoy ReSharper for 30 days.
Cheers - Dipesh
Announcing: CRM SDK V3.0.7 Updated
Learn best practices for writing code that performs better by creating multiple threads and using unsafe connection sharing.
In the Sample Code section, you’ll find new samples that show you how to:
Create a customer relationship
Create an opportunity and set a picklist
Perform a bulk delete operation
You can download the updated SDK from this location: www.microsoft.com/downloads/details.aspx?FamilyId=9C178B68-3A06-4898-BC83-BD14B74308C5&displaylang=en. This update will be live on MSDN soon!
Wednesday, May 02, 2007
Sessions at MIX 07 - Las Vegas
http://sessions.visitmix.com
Silverlight now for download - http://blogs.iis.net/iisnews/archive/2007/04/30/silverlight-now-available-for-download.aspx
Cheers - DJ
Tuesday, May 01, 2007
IE Developer toolbar...
If you're like most Web developers, when you were first learning HTML, you probably spent a great deal of your time playing around with your browser. The fact that you could simply do a "View Source" and see how an interesting web page was implemented was one of the things that helped HTML catch on so quickly. This "code sharing" is undoubtably one of the reasons the Web was able to grow as quickly as it did.
Unfortunately, these days it's not so easy to take a look at the magic going on behind the scenes of the average web page. With the emphasis on usability and appearance, the previously simple HTML has become incresingly difficult to read and these days most web pages are made up of a combination of several files and use often use as much CSS and client-side script as they do HTML. Using "View Source" simply doesn't cut it anymore. Luckily Microsoft has realized this fact and is building a tool to help developers analyze these increasingly complex web documents. It's called the Internet Explorer Developer Toolbar. In this article I'll give you a quick introduction to this powerful new tool and examine some of it's most useful features.
These features enable you to:
1 Explore and modify the document object model (DOM) of a Web page.
2 Locate and select specific elements on a Web page through a variety of techniques.
3 Selectively disable Internet Explorer settings.
4 View HTML object class names, ID's, and details such as link paths, tab index values, and access keys.
5 Outline tables, table cells, images, or selected tags.
6 Validate HTML, CSS, WAI, and RSS Web feed links.
7 Display image dimensions, file sizes, path information, and alternate (ALT) text.
8 Immediately resize the browser window to a new resolution.
9 Selectively clear the browser cache and saved cookies. Choose from all objects or those associated with a given domain.
10 Choose direct links to W3C specification references, the Internet Explorer team weblog (blog), and other resources.
11 Display a fully featured design ruler to help accurately align and measure objects on your pages.
12 Find the style rules used to set specific style values on an element.
13 View the formatted and syntax colored source of HTML and CSS.
Download the beta version from here - http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en
Check for details on IE developer tool here - http://www.15seconds.com/issue/070208.htm
- D
Convert XML data to object and back using serialization
This article shows you how to convert an XML to a class object and retriving back.
Saving XML to a class object is called serialization and reading back using the reverse process is called as deserialization.
1> Assuming you have a sample xsd, to convert a class from XSD, we would run the following command:
xsd C:\Contact.xsd /t:lib /l:cs /c from VS.net command prompt.
2> /// auto generated code from xsd command ran above...using System.Xml.Serialization;
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public class Contact
{ public ContactInfo;
}
public class ContactInfo
{ public string Code;
public string FirstName;
public string LastName;
public string Email;
}
3> Now, we could save an contact XML data to this class using this simple function:
public Contact ContactObject(string xml)
{ StringReader stream = null;
XmlTextReader reader = null;
try
{ // serialise to object
XmlSerializer serializer = new XmlSerializer(typeof(Contact));
stream = new StringReader(xml); // read xml data
reader = new XmlTextReader(stream); // create reader
// covert reader to object
return (Contact)serializer.Deserialize(reader);
}
}
And to get the XML based on the Contact class object, use the following function:
public string ContactXML(Contact cont)
{ MemoryStream stream = null;
TextWriter writer = null;
try
{ stream = new MemoryStream();
// read xml in memory
writer = new StreamWriter(stream, Encoding.Unicode) ;
// get serialise object
XmlSerializer serializer = new XmlSerializer(typeof(Contact));
serializer.Serialize(writer, cont);
// read object
int count = (int) stream.Length;
// saves object in memory stream
byte[] arr = new byte[count];
stream.Seek(0, SeekOrigin.Begin);
// copy stream contents in byte array
stream.Read(arr, 0, count);
UnicodeEncoding utf = new UnicodeEncoding();
// convert byte array to string
return utf.GetString(arr).Trim();
}
}
Hope this helps for all working on XML!
Thanks - DJ
Monday, April 30, 2007
MIX 07 conference
Check out the cool videos, sessions, hot topics and debates posted here.
Cheers - Dipesh
Silverlight and Expression Studio News... 1.0 Beta released
Silverlight is a cross-browser, cross-platform plug-in for delivering the next generation of media experiences and rich interactive applications (RIAs) for the Web. The Silverlight 1.0 Beta has a go-live license that implies it can be used for commercial purposes.
What has it got for you?
· Cross platform .net framework through Silverlight (full Visual Studio experience)
· Perf when using C# instead of js to create rich internet apps is 300-1000 times faster
· Silverlight Visual Studio add-in enables debugging – even remotely debug an app running on a Mac (Matt saw it live!)
· Multiple languages are supported: JavaScript, Ruby, Python, C#, VB .NET, etc
Check this @ http://www.microsoft.com/silverlight/default01.aspx
Download ... It’s free: http://silverlight.live.com/
Cheers - Dipesh
Thursday, April 26, 2007
Ent Libs - How to use Logging block?
private static FlatFileTraceListener nFile;
private static void WriteLog(string sComments)
{
Console.WriteLine(sComments);
//Logger.Write(sComments);
if (nFile != null)
{
nFile.Write(DateTime.Now.ToString() + ": ");
nFile.WriteLine(sComments);
nFile.Flush();
}
}
Validate XML against your schema XSD
using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;
namespace ConsoleApplication3
{
///
/// Summary description for Class1.
///
class Class1
{
///
/// The main entry point for the application.
///
System.Boolean m_success;
[STAThread]
static void Main(string[] args)
{
//XmlValidatingReader reader = null; //obsolete in .net 2
XmlReader reader1 = null;
//XmlSchemaCollection myschema = new XmlSchemaCollection(); //obsolete in .net 2
XmlSchemaSet myschema1 = new XmlSchemaSet();
ValidationEventHandler eventHandler = new ValidationEventHandler(Class1.ShowCompileErrors);
try
{
//Create the XML fragment to be parsed.
// String xmlFrag = "YOUR XML string here" ;
//Create the XmlParserContext.
XmlParserContext context = new XmlParserContext(null, null, "", XmlSpace.None);
//Implement the reader.
//reader = new XmlValidatingReader(xmlFrag, XmlNodeType.Element, context); //obsolete in .net 2.0
XmlReaderSettings rs = new XmlReaderSettings();
rs.ValidationType = ValidationType.Schema;
myschema1.Add("http://www.newmarketinc.com", Server.Mappath("DirectBook.xsd"));
rs.Schemas.Add(myschema1);
StringReader srXml = new StringReader(xmlFrag);
reader1 = XmlReader.Create(srXml, rs, context);
//Add the schema.
//myschema.Add("http://www.newmarketinc.com", "D:\\Documents and Settings\\Administrator\\Desktop\\MI\\DirectBook.xsd");
//Set the schema type and add the schema to the reader.
//reader.ValidationType = ValidationType.Schema;
//reader.Schemas.Add(myschema);
while (reader1.Read())
{ //empty loop;
}
Console.WriteLine("Completed validating xmlfragment");
}
catch (XmlException XmlExp)
{
Console.WriteLine(XmlExp.Message);
}
catch (XmlSchemaException XmlSchExp)
{
Console.WriteLine(XmlSchExp.Message);
}
catch (Exception GenExp)
{
Console.WriteLine(GenExp.Message);
}
finally
{
Console.Read();
}
}
public static void ShowCompileErrors(object sender, ValidationEventArgs args)
{
Console.WriteLine("Validation Error: {0}", args.Message);
}
}
}
References -
.net 1.1 - http://www.codeproject.com/cs/webservices/XmlSchemaValidator.asp,
http://support.microsoft.com/kb/318504
.net 2.0 - http://aspalliance.com/941
Cheers - Dj
XSD Element
The any element enables us to extend the XML document with elements not specified by the schema.
The following example is a fragment from an XML schema called "family.xsd". It shows a declaration for the "person" element. By using the
[person - last name, firstname, any]
any can contain any additonal information (any other element from other schema as well)
So you can define another child.xsd and add it in your XML
Your XML can contain something like -
[person - lastname, firstname, [children - childname] ]
Its little difficult to format the XML output in this blog so please reference this link - http://www.w3schools.com/schema/schema_complex_any.asp
BTW, w3schools is the best site for all your questions regarding XML schema.
Cheers - Dj
Monday, April 23, 2007
This small piece of code is very helpful when you want to do repetative tasks of Fetching an XML and forming a dataset out of it.
public DataSet FetchDataSet(string fetchXml)
{
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
string strResult = service.Fetch(fetchXml);
DataSet ds = new DataSet();
StringReader reader = new StringReader(fetchXml);
ds.ReadXml(reader);
return ds;
}
Cheers - Dipesh
Tuesday, April 10, 2007
Latest Release: Enterprise Library 3.0 – April 2007 (for .NET Framework 2.0 and 3.0)
http://msdn2.microsoft.com/en-us/library/aa480453.aspx
Download Ent Libs 3.0 for .net framework 2.0 and 3.0
Cheers - Dipesh
Let's take a light topic... do you know how to Read and write web App.config files?
Here it is...
Read Config -
static void ReadConfig()
{
foreach(string key in ConfigurationManager.AppSettings)
{ string value = ConfigurationManager.AppSettings[key];
Console.WriteLine("Key: {0}, Value: {1}", key, value);
}
}
Write Config -
static void WriteConfig() {
// Open App.Config of executable
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Add an Application Setting.
config.AppSettings.Settings.Add("ModifiedDate", DateTime.Now.ToLongTimeString() + " ");
// Save the changes in App.config file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
}
}}
Output:
Key: Settings1, Value: Value1
Key: Modified Date, Value: 12:00:00
Ok, did you figure that the app.config does not stick values for the keys that you added or for the keys that you modified. Check the app.exe.config in the debug or release version. You should find it stick there. I foudn it little wierd but not sure when in debug mode i could not find app.config modified but had app.exe.config modified. If anyone you have had the same experience and seems that i might have missed something then please let me know.
Well, before i end you have another option as Settings file that can be used to get/set settings at user/application level for your application as well.
Thanks - Dipesh