Tag Cloud

CRM 2011 (161) CRM 4.0 (144) C# (116) JScript (109) Plugin (92) Registry (90) Techpedia (77) PyS60 (68) WScript (43) Plugin Message (31) Exploit (27) ShellCode (26) FAQ (22) JavaScript (21) Killer Codes (21) Hax (18) VB 6.0 (17) Commands (16) VBScript (16) Quotes (15) Turbo C++ (13) WMI (13) Security (11) 1337 (10) Tutorials (10) Asp.Net (9) Safe Boot (9) Python (8) Interview Questions (6) video (6) Ajax (5) VC++ (5) WebService (5) Workflow (5) Bat (4) Dorks (4) Sql Server (4) Aptitude (3) Picklist (3) Tweak (3) WCF (3) regex (3) Config (2) LINQ (2) PHP (2) Shell (2) Silverlight (2) TSql (2) flowchart (2) serialize (2) ASHX (1) CRM 4.0 Videos (1) Debug (1) FetchXml (1) GAC (1) General (1) Generics (1) HttpWebRequest (1) InputParameters (1) Lookup (1) Offline Plug-ins (1) OutputParameters (1) Plug-in Constructor (1) Protocol (1) RIA (1) Sharepoint (1) Walkthrough (1) Web.config (1) design patterns (1) generic (1) iframe (1) secure config (1) unsecure config (1) url (1)

Pages

Tuesday, April 23, 2013

Convert a Dynamic Entity to a System Entity

This sample code shows how to convert a dynamic entity instance into a strongly typed account entity instance. The code first creates a dynamic entity, populates its properties with account attributes and values, and then converts the dynamic entity to an account entity.



using System;
using System.Reflection;

using CrmSdk;
using Microsoft.Crm.Sdk.Utility;

namespace Microsoft.Crm.Sdk.HowTo
{
public class ConvertDynamicToCore
{
static void Main(string[] args)
{
// TODO: Change the server URL and organization to match your Microsoft
// Dynamics CRM Server and Microsoft Dynamics CRM organization.
ConvertDynamicToCore.Run("http://localhost:5555", "CRM_SDK");
}

public static bool Run(string crmServerUrl, string orgName)
{
// Create an account dynamic entity.
DynamicEntity accountDynamicEntity = new DynamicEntity();

//Set a few account properties.
StringProperty name = new StringProperty();
name.Name = "name";
name.Value = "Fabrikam Inc.";

StringProperty accountnumber = new StringProperty();
accountnumber.Name = "accountnumber";
accountnumber.Value = "AZ1200";

Picklist plist = new Picklist();
plist.name = "UPS";
plist.Value = 2;

PicklistProperty shippingmethodcode = new PicklistProperty();
shippingmethodcode.Name = "address1_shippingmethodcode";
shippingmethodcode.Value = plist;

accountDynamicEntity.Properties = new Property[] { name, accountnumber, shippingmethodcode };
accountDynamicEntity.Name = EntityName.account.ToString();

//Create a strongly typed account entity to copy the dynamic entity into.
account coreAccount = new account();

//Convert the dynamic entity to a strongly typed business entity.
coreAccount = (account)Convert(accountDynamicEntity);

Console.WriteLine("\n|Core Account Attributes\n|=======================");
Console.WriteLine("|name: {0}", coreAccount.name);
Console.WriteLine("|accountnumber: {0}", coreAccount.accountnumber);
Console.WriteLine("|address1_shipmethodcode: {0}", coreAccount.address1_shippingmethodcode.Value);

return true;
}

///
/// Convert a dynamic entity into a strongly typed business entity.
///

public static BusinessEntity Convert(DynamicEntity entity)
{
string coreEntityName = entity.Name;

Type entType = (new account()).GetType();
ConstructorInfo init = entType.GetConstructor(new Type[] { });
object ent = init.Invoke(new object[] { });

foreach (Property p in entity.Properties)
{
PropertyInfo entProp = entType.GetProperty(p.Name);
if (null == entProp)
{
Console.WriteLine("Could not find attribute {0} on entity {1}.", p.Name, coreEntityName);
}
else
{
entProp.SetValue(ent, GetAttribute(entity, p.Name), null);
}
}
return (BusinessEntity)ent;
}

///
/// This method returns the value of a dynamic entity attribute.
///

public static object GetAttribute(BusinessEntity entity, string attribute)
{
if (entity.GetType() == typeof(DynamicEntity))
{
DynamicEntity de = (DynamicEntity)entity;
foreach (Property prop in de.Properties)
{
if (prop.Name == attribute)
{
PropertyInfo propInfo = prop.GetType().GetProperty("Value");
return propInfo.GetValue(prop, null);
}
}
return null;
}
else
{
PropertyInfo propInfo = entity.GetType().GetProperty(attribute);
return propInfo.GetValue(entity, null);
}
}
}
}



Convert a Dynamic Entity to a System Entity

This sample code shows how to convert a dynamic entity instance into a strongly typed account entity instance. The code first creates a dynamic entity, populates its properties with account attributes and values, and then converts the dynamic entity to an account entity.
/*
convert a dynamic entity instance into a strongly typed account entity instance. 
*/
using System;
using System.Reflection;
 
using CrmSdk;
using Microsoft.Crm.Sdk.Utility;
 
namespace Microsoft.Crm.Sdk.HowTo
{
   public class ConvertDynamicToCore
   {
      static void Main(string[] args)
      {
         // TODO: Change the server URL and organization to match your Microsoft
         // Dynamics CRM Server and Microsoft Dynamics CRM organization.
         ConvertDynamicToCore.Run("http://localhost:5555", "CRM_SDK");
      }
      
      public static bool Run(string crmServerUrl, string orgName)
      { 
         // Create an account dynamic entity.
         DynamicEntity accountDynamicEntity = new DynamicEntity();
 
         //Set a few account properties.
         StringProperty name = new StringProperty();
         name.Name = "name";
         name.Value = "Fabrikam Inc.";
 
         StringProperty accountnumber = new StringProperty();
         accountnumber.Name = "accountnumber";
         accountnumber.Value = "AZ1200";
 
         Picklist plist = new Picklist();
         plist.name = "UPS";
         plist.Value = 2;
 
         PicklistProperty shippingmethodcode = new PicklistProperty();
         shippingmethodcode.Name = "address1_shippingmethodcode";
         shippingmethodcode.Value = plist;
 
         accountDynamicEntity.Properties = new Property[] { name, accountnumber, shippingmethodcode };
         accountDynamicEntity.Name = EntityName.account.ToString();
 
         //Create a strongly typed account entity to copy the dynamic entity into.
         account coreAccount = new account();
 
         //Convert the dynamic entity to a strongly typed business entity.
         coreAccount = (account)Convert(accountDynamicEntity);
 
         Console.WriteLine("\n|Core Account Attributes\n|=======================");
         Console.WriteLine("|name:  {0}", coreAccount.name);
         Console.WriteLine("|accountnumber:  {0}", coreAccount.accountnumber);
         Console.WriteLine("|address1_shipmethodcode:  {0}", coreAccount.address1_shippingmethodcode.Value);
 
         return true;
      }
 
      /// <summary>
      /// Convert a dynamic entity into a strongly typed business entity.
      /// </summary>
      public static BusinessEntity Convert(DynamicEntity entity)
      {
         string coreEntityName = entity.Name;
 
         Type entType = (new account()).GetType();
         ConstructorInfo init = entType.GetConstructor(new Type[] { });
         object ent = init.Invoke(new object[] { });
 
         foreach (Property p in entity.Properties)
         {
            PropertyInfo entProp = entType.GetProperty(p.Name);
            if (null == entProp)
            {
               Console.WriteLine("Could not find attribute {0} on entity {1}.", p.Name, coreEntityName);
            }
            else
            {
               entProp.SetValue(ent, GetAttribute(entity, p.Name), null);
            }
         }
         return (BusinessEntity)ent;
      }
 
      /// <summary>
      /// This method returns the value of a dynamic entity attribute.
      /// </summary>
      public static object GetAttribute(BusinessEntity entity, string attribute)
      {
         if (entity.GetType() == typeof(DynamicEntity))
         {
            DynamicEntity de = (DynamicEntity)entity;
            foreach (Property prop in de.Properties)
            {
               if (prop.Name == attribute)
               {
                  PropertyInfo propInfo = prop.GetType().GetProperty("Value");
                  return propInfo.GetValue(prop, null);
               }
            }
            return null;
         }
         else
         {
            PropertyInfo propInfo = entity.GetType().GetProperty(attribute);
            return propInfo.GetValue(entity, null);
         }
      }
   }
}

Microsoft Dynamics CRM 4.0 Reports

What is Microsoft  Dynamics CRM Reports

It uses the term Report to refer to any type of data analysis file, regardless of its origin and type. Therefore, a report may be a Microsoft Office Excel file, a SQL Server Reporting Services report, a third-party reporting file, or a link to an external Web page report.

How to create Reports

Microsoft Dynamics CRM 4.0 includes approximately 24 Reporting Services reports in the default installation and those reports include an additional 28 Subreports. However we will definitely want to create new reports (or modify the default reports) as we customize our MS CRM database with new entity attributes and custom entities.
In Microsoft Dynamics CRM 4.0 we can create Reports in two methods:

Report Wizard

All users have access to the Report Wizard to create a report for their personal use, assuming they have any level of access to the Report Create Privilege. The Installation enables the Report Create Privilege on all security roles by default. By default, the Report Wizard creates the report as a personal (individual viewable) report.One can access the Report Wizard by creating a new report from the Reports grid. In addition to creating a report, one can use the Report Wizard to edit an existing Report Wizard report.

Report Definition Language with VS 2005
One can create their own Reporting Services report from scratch by using Visual Studio 2005. To develop reports in VS 2005, one should need Business Intelligence Development Studio add-in to be installed with VS 2005

Reporting Service Versions

Microsoft Dynamics CRM 4.0 Supports the following Reporting Services editions:
1. SQL Server 2005, Standard Edition with SP2
2. SQL Server 2005, Enterprise Edition with SP2
3. SQL Server 2005, Workgroup Edition with SP2
4. SQL Server 2005, Standard Edition, x64 SP2
5. SQL Server 2005, Enterprise Edition x64 SP2

Data Flow Diagram

DFD

Microsoft Dynamics CRM 4.0 reports depend on the connector for Microsoft SQL server Reporting services. SSRS data connector used to proxy request between CRM 4.0, SSRS and SQL server thereby removing trust for delegation Requirement. The SRS connector runs as an SSRS Data Processing Extension and handles all of the delegation for you. The use of the data connector is recommended for Internet facing deployments and anywhere users are not using NT Auth to connect to CRM. Other way to do this in Microsoft CRM 4.0 is to use integrated authentication where trust for delegation is required between the CRM server, the SSRS server and the SQL server with the CRM DB.

Reporting Services Architecture Diagram

Reporting Services Architecture Diagram

Microsoft Dynamics CRM 4.0 Architecture Consist of three layers. First level is MS Dynamics CRM which consist of Reports and Report Viewer ASP.Net Control, here Reports is nothing but an Entity which presented in MSCRM which is not there in MSCRM 3.0 Version. The SQL Reporting Services Report Viewer is an ASP.Net control which runs on the CRM 4.0 Web server. When you choose to run a report from Microsoft CRM 4.0, the ASP.Net control requests the report and data from the remote SSRS box. In practical terms, In Microsoft CRM 4.0 the URL for a report is the CRM Web server.

Authentication in MSCRM 4.0 Reports

Authentication in MSCRM 4.0 Reports

Microsoft Dynamics CRM 4.0 Server uses Report viewer to display data from SRS Server, the connection between Report Viewer and SRS Webservice uses CRM User Context for Authentication.SRS Webservice and CRM Data Connector uses SRS App pool and CRM User Context for establishing connection to MSCRM Filtered views in SQL Server. All data retrieved using CRM Data Connecter controlled by CRM Roles and Privileges Advantages of Data Connector are that it Removes trust for delegation (TFD) requirement. Enabling reports for external applications still is subject to TFD.Report entity is a full CRM entity and Sharing Report is also available. No longer need to make calls to SRS to display list of reports in CRM.RDLs are mastered in CRM.

Note:

  1. If a user does not have Privileges in CRM he or she will get a blank Report.
  2. Credentials supplied by the user running the report option which expects SystemUserId as the Login Name and OrganizationId as the Password.
  3. Sharing Reports – Users Can share their reports to a team or any specific user.

Prerequisites for Installation of SRS Data Connector:

  1. SQL Server Reporting Service 2005 or 2008
  2. MS CRM 4.0 needs to be installed (Connector requires MSCRM_CONFIG db)

Installation of SRS Data Connector:

  1. Run the Splash.exe file
  2. Select SRS Data Connector
  3. Select Update the Installation files(Recommended)
  4. Select the MSCRM db Server name in the picklist

Security Privileges

Security Privileges

In Microsoft Dynamics CRM 4.0 Reports are just like CRM system entity. As such, the report entity adheres to the standard security characteristic with that applies to all entities in MS CRM. Each report in MSCRM contains a viewable by attribute, with values of organization or individual. If the report viewable by value equals organization, all users will be able to run reports, provided they have read privileges. If the viewable by value equals individual, the report read privileges will determine each user’s access to the report.

Other Privileges:

  1. Publish Reports – allows users to make a report available to the Organization
  2. Add Reporting Services Reports – allows users to upload .rdl files
  3. Create : allows users to create reports using the Report Wizard

Existing roles will get access to reports as follows:

  1. Manage Reports privilege : full access
  2. Other : default privileges

Get the selected items in a CRM grid in CRM 4.0


//With this function you get only the GUIDs of the records selected.
function GetSelectedItemsInGrid()
{
return getSelected("crmGrid");
}

Use LINQ to Retrieve Data from Microsoft Dynamics CRM

The XrmDataContext class contains an underlying query provider to translate LINQ queries from C# syntax into the query API that the Microsoft Dynamics CRM can read natively. This query provider abstracts much of the Microsoft Dynamics CRM SDK query APIs under a more familiar C# syntax; however, the querying capability of the query provider is limited to the functionality provided by Microsoft Dynamics CRM. There are some areas indicated where you may have problems with the standard LINQ to Objects capabilities when applied to the Microsoft Dynamics CRM LINQ provider. For more information about the LINQ query language, see LINQ. For more information about query features in Microsoft Dynamics CRM, see Building Queries.

The Advanced Developer Extensions LINQ query provider offers the following capabilities:

  • Supports the Join, Where, OrderBy, and Select functions.
  • Supports the Skip, Take, Distinct, Single, and First functions.
  • Handles the other IEnumerable extensions.
  • Supports Select to anonymous types, constructors, and initializers.
  • Supports Where conditions with Contains, StartsWith, EndsWith, and Equals String functions.
  • Allows you to specify attributes statically or dynamically.

To get an idea of what the typical Microsoft Dynamics CRM LINQ queries look like, here are some samples of common data retrieval scenarios.

Examples

The following example shows how to retrieve all contact records.

// Loop through all Microsoft Dynamics CRM contacts using the IQueryable interfaces
// on the XrmDataContext object.
System.Console.WriteLine("List all contacts in CRM");
System.Console.WriteLine("========================");
foreach (var c in crm.contacts)
{
System.Console.WriteLine(c.fullname + " " + c.emailaddress1);
}

The next sample adds a "where" clause filter and returns a single result.

// Find a contact by user name.
var namedContact = (
from contact in crm.cContacts
where contact.Username emailaddress1 == " allison.brown@contoso.com someuser"
select contact).Single();

// Here is the equivalent query using an inline expression.
var namedContact2 = crm.Contacts.Where(c => c.Username == "someuser").Single();
Console.WriteLine(namedContact.Username);var allisonBrown =
crm.contacts.FirstOrDefault(c => c.emailaddress1 == "allison.brown@contoso.com");

if (allisonBrown != null)
{
System.Console.WriteLine(allisonBrown.fullname)
}


A basic join can be done between two entities with a where clause added against one or both entities.

System.Console.WriteLine("List all contacts where Parent Customer = 'Contoso':");
var contosoContacts = from c in crm.contacts
join parentCustomer in crm.accounts
on c.parentcustomerid.Value equals parentCustomer.accountid
where parentCustomer.name == "Contoso"
select c;

foreach (var c in contosoContacts)
{
System.Console.WriteLine(c.fullname + " " + c.emailaddress1);
}

A many-to-many relationship requires a more complex query that involves joining a relationship entity between the two entities.

// List the contacts in the Softball team marketing list.
System.Console.WriteLine("List all contacts in Softball Team:");

var members = from c in crm.contacts
join mlm in crm.listmembers on c.contactid equals mlm.entityid
join ml in crm.lists on mlm.listid equals ml.listid
where ml.listname == "Softball Team"
select c;

foreach (var c in members)
{
System.Console.WriteLine(c.fullname + " " + c.emailaddress1);
}

When you access a date/time attribute value, you can use the formatted values collection to retrieve the value in the user's converted time zone.

var query = from contact in crm.contacts
where contact.fullname.Contains("Ken")
select new { contact.fullname, contact.contactid, contact.createdon };
foreach (var c in query)
{
System.Console.WriteLine(c.fullname);
System.Console.WriteLine(c.contactid);
System.Console.WriteLine(c.FormattedValues["createdon"]);
}

Monday, April 22, 2013

Online vs. Offline Plug-ins

You can register plug-ins to execute in online mode, offline mode, or both. Your plug-in code can check whether it is executing in offline mode. The following code sample shows you how to determine offline plug-in execution by checking the IPluginExecutionContext.IsExecutingInOfflineMode property value.

Example
using System;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;

namespace MyPlugins
{
public class AccountCreateHandler: IPlugin
{
public void Execute(IPluginExecutionContext context)
{
// Check Whether the Web service is offline.
if (context.IsExecutingInOfflineMode)
{
// Do something…
}
}
}
}

When you design a plug-in that will be registered for both online and offline execution, you should consider the possibility that the plug-in could be executed two times. The first time that the plug-in could potentially execute is while Microsoft Dynamics CRM for Microsoft Office Outlook is offline. The plug-in is then executed again when Microsoft Dynamics CRM for Outlook goes online and synchronization between Microsoft Dynamics CRM for Outlook and the Microsoft Dynamics CRM server occurs.


You can add code to your plug-in to check if the plug-in is being executed due to a synchronization between Microsoft Dynamics CRM for Outlook and the Microsoft Dynamics CRM server. To add this functionality to your plug-in, add code to inspect the CallerOrigin property of IPluginExecutionContext as shown in the following code sample.

using System;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;

public class OnlinePlugin : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
// Check to see if this is a playback context.
CallerOrigin callerOrigin = context.CallerOrigin;
if (callerOrigin is OfflineOrigin)
{
// This plug-in was fired from the playback queue after the user
// selected to go online within Microsoft Dynamics CRM for Outlook.
return;
}
else
{
// Do something here.
}
}
}

When registering a plug-in for offline execution, always register the plug-in for a synchronous mode of execution. Asynchronous execution of offline plug-ins is not supported.

Plug-in Constructor

The Microsoft Dynamics CRM platform has special support for a plug-in constructor that accepts two string parameters. If you write a constructor for your plug-in that accepts two string parameters, you can pass any two strings of information to the plug-in at run time. The following code shows these two parameters.

using System;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;

namespace MyPlugins
{
public class AccountCreateHandler: IPlugin
{
public AccountCreateHandler(string unsecure, string secure)
{
// Do something with the parameter strings.
}

public void Execute(IPluginExecutionContext context)
{
// Do something here.
}
}
}

The first string parameter of the constructor contains public (unsecure) information. The second string parameter contains non-public (secure) information. However, the secure string is not passed to a plug-in that executes while offline.


The information that is passed to the plug-in constructor in these two strings is specified when the plug-in is registered with Microsoft Dynamics CRM. When you use the PluginRegistration tool to register a plug-in, you can enter the secure and unsecure information in the Secure Configuration and Unsecure Configuration fields provided in the Register New Step form. The PluginDeveloper tool only supports the unsecure string through its CustomConfiguration attribute of the Step tag in the register.xml input file.