RSS

Tag Archives: Dibyasingh Tripathy

Avoiding Deadlock in Plugins

Introduction

Multiple operations with the same Entity inside a Plugin, causes Deadlocks in Plugins and might cancel the transaction. Let’s explore the Trick to avoid the Deadlocks.

Background

In one of my projects, there was a situation, when multiple operations had been done on the same Entity records. A Plugin was there, which was simultaneously updating a record lets say “C” and then from record “C” based on some condition record “B” was being updated and another Plugin was there which was updating values from record “B” to record “A”. And after it is done the final amount had to be shown in record “A” immediately as soon as the custom Popup (a Web Resource), that causes the operation in record “C” is closed and the Popup was being invoked from the ribbon of entity “A”.
As the user wanted to see the effect immediately there was no other option than to just make the Plugin Synchrounous. So, Create/Update and Retrieve operation at the same time was causing the transaction to be Deadlocked sometimes and was not allowing the user to Add/Update multiple records.

Code

In order to solve the issue, I tried several ways. Finally I found that in QueryExpression there is a property called “NoLock” while using RetrieveMultiple method.

Its simple to use but its effect is something worthy to be noted. The code snippet is,

QueryExpression queryCItems= new QueryExpression("new_entityc");
queryCItems.NoLock = true;
queryCItems.ColumnSet = new ColumnSet("new_totalamount");
queryCItems.Criteria.AddCondition("new_aid", ConditionOperator.Equal, entC.Id);

This solved the issue. 🙂

By Dibyasingh Tripathy
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

Advertisements
 
Leave a comment

Posted by on November 26, 2013 in CRM Plug-in

 

Tags: , , , , , , , , , , , , , , ,

CRM 2011 Exception “The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘NTLM'”

Introduction

This is in reference to my previous post Calling external Web Service from a CRM 2011 Plug-in. This blog post is just a modification of the last post.

Background

In one of the project while calling an external Web Service hosted in some other server(other than CRM server), I found an issue like the one below.

” The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘NTLM’ “

Problem

Clearly its an Authentication Issue. Then I found out that in Authentication Section of IIS, the Authentication Scheme for the service was Ntlm, whereas I was using Default Authentication Scheme in my HTTP Binding inside Configuration Information.

Solution

Instead of using the Default Authentication, I changed my Binding to use Ntlm Authentication.

So, instead of the following code,

BasicHttpBinding myBinding = new BasicHttpBinding();

myBinding.Name = "BasicHttpBinding_Service";
myBinding.Security.Mode = BasicHttpSecurityMode.None;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

I changed my code like below…

BasicHttpBinding myBinding = new BasicHttpBinding();

myBinding.Name = "BasicHttpBinding_Service";
myBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

And to my utter surprise, it started to work :). !!!

By Dibyasingh Tripathy
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 

Tags: , , , , , , , , , , , , , , , ,

Using CRM LookUp functionality in a Silverlight WebResource with CRM Look and Feel

Introduction

In this blog, I will show you how to use the LookUp functionality of CRM in a Silverlight WebResource.

I am trying to create a LookUp for the Account inside a Contact record.

Design

Let’s first go for the Design.

In the Design, let’s add a RichTextBox and a LookUp image similar to the CRM LookUp image.

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="SilverlightApplicationLookUpDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:Label Height="20" Width="50" x:Name="lblLookup" HorizontalAlignment="Left" Content="Account" Margin="62,56,0,0" VerticalAlignment="Top"/>
        <RichTextBox Background="White" FontSize="10" VerticalScrollBarVisibility="Disabled" IsReadOnly="True" Height="21" HorizontalAlignment="Left" Margin="112,54,0,0" Name="txtLookUp" VerticalAlignment="Top" Width="200" TabIndex="1" />
        <Image Height="21" Width="21" HorizontalAlignment="Left" Margin="313,53,0,0" Name="ImgLookUp" MouseLeftButtonDown="LocalImage_MouseLeftButtonDown" Source="/SilverlightApplicationLookUpDemo;component/Images/btn_off_lookup.png" VerticalAlignment="Top"/>
    </Grid>
</UserControl>

It will look like below.

Capture

Code Behind

In the Code Behind, let’s insert the Event that will be fired, when the Image gets clicked.

The whole code will look something like this.

using System.Json;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace SilverlightApplicationLookUpDemo
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void LocalImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            string lookupId = string.Empty;
            string lookupName = string.Empty;
            string contactId = "7C1EF3C4-39D3-E211-8A25-B4B52F566DF2";
            string baseUrl = "https://example.crm.dynamics.com";
            string objectTypesContact = "2";

            //Relative URL for the LookUp
            string lookUpRecordUrl = "/_controls/lookup/lookupinfo.aspx?AllowFilterOff=1&DefaultType=1&" +
"DisableQuickFind=0&DisableViewPicker=0&LookupStyle=single&ShowNewButton=1&ShowPropButton=1&" +
"browse=false&currentid=" + contactId + "&objecttypes=" + objectTypesContact;

           //Complete URL to open the LookUp
           string lookUpUrl = baseUrl + lookUpRecordUrl;

           //Open the Modal Window for the LookUp
           dynamic returnedParams = HtmlPage.Window.Invoke("showModalDialog", lookUpUrl, null, "dialogWidth:500px;dialogHeight:700px");

           //For earlier Rollups, it will return a json object
           if (returnedParams.items)
           {
               lookupId = returnedParams.items[0].id;
               lookupName = returnedParams.items[0].name;
           }

           //For Rollup 12, as in Rollup 12 returnedparams would
           //be a json string instead of a json object.
           else
           {
               JsonValue jsonValue = JsonValue.Parse(returnedParams);
               JsonObject jsonObject = jsonValue as JsonObject;

               //user selected
               lookupId = jsonObject["items"][0]["id"].ToString();
               lookupName = jsonObject["items"][0]["name"].ToString();
           }

           //Add style to the TextBox
           txtLookUp.Foreground = new SolidColorBrush(Colors.Blue);

           //Add selected item to the fiscal period TextBox
           Paragraph paragraph = new Paragraph();
           Underline underline = new Underline();
           Run run = new Run() { Text = lookupName };

           underline.Inlines.Add(run);
           paragraph.Inlines.Add(underline);
           txtLookUp.Blocks.Clear();
           txtLookUp.Blocks.Add(paragraph);
       }
    }
}

Now let’s add the WebResource to a Contact entity.

Output

So, after implementing, we will see something like this.

Image

Image

Notes

  1. For the demo, I have hard-coded the Contact Id and objecttype for Contact, but we can also pass them as QueryString Parameter/Custom Parameter for the Web Resource.
  2. For Server URL, we can use the “SilverlightUtility.GetServerBaseUrl()" function.
  3. The “SilverlightUtility.cs" can be found at location sdk\samplecode\cs\silverlight\soapforsilverlight\soapforsilverlightsample in the SDK provided by Microsoft.

By Dibyasingh Tripathy
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
2 Comments

Posted by on August 7, 2013 in WebResources

 

Tags: , , , , , , , , , , , , , , ,

Calling external Web Service from a CRM 2011 Plug-in

Introduction

This blog explains how to call external Web Service from a CRM 2011 Plug-in.

Background

Sometimes we need to call a Web Service from a Plug-in. We had a similar requirement, but while trying to access the service, we got the following error.

“Could not find default endpoint element that references contract ‘ServiceReference.Service′ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.”

Problem

The reason for this is because the configuration information for the Web Service from the client side is missing.

Using the Code

So, now in case of our plugin, we need to define the binding and endpoint information programmatically. Something like this…

using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using TestPluginConnectWebService.TestService;

namespace TestPluginConnectWebService
{
    public class TestConnectWebService : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            //Context = Info passed to the plugin at runtime
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            //Service = access to data for modification
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            // Adding Basic Http Binding and its properties.
            BasicHttpBinding myBinding = new BasicHttpBinding();
            myBinding.Name = "BasicHttpBinding_Service";
            myBinding.Security.Mode = BasicHttpSecurityMode.None;
            myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

            // Endpoint Address defining the asmx Service to be called.
            EndpointAddress endPointAddress = new EndpointAddress(@"http:///ReturnRecords/GetRecords.asmx");

            // Call to the Web Service using the Binding and End Point Address.
            GetGrantRecordsSoapClient myClient = new GetGrantRecordsSoapClient(myBinding, endPointAddress);

            var ab = myClient.GetGrants();

            if (ab != null)
            {
                 throw new InvalidPluginExecutionException("Success");
            }
            else
            {
                 throw new InvalidPluginExecutionException("Failure");
            }
        }
    }
}

This way we would be able to access our Web Service inside Plug-in.

Note

The following are some of the points that needs special attention.

Sandboxed Plug-ins can access network through the HTTP and HTTPS protocols. This capability provides support for accessing popular Web resources like Social Sites, News Feeds, Web services, and more.
The following Web access restrictions apply to this Sandbox capability.

  • Only the HTTP and HTTPS protocols are allowed.
  • Access to localhost (loopback) is not permitted.
  • IP addresses cannot be used. You must use a named Web address that requires DNS name resolution.

Reference – [MSDN] Plug-in Isolation, Trusts, and Statistics

By Dibyasingh Tripathy
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 

Tags: , , , , , , , , , , , , , , , , , , , , , ,

 
%d bloggers like this: