Webhooks to Dynamics 365 Serverless Integration using Azure Functions

Recently I needed to create an integration between a cloud platform and Dynamics 365 Customer Engagement Cloud. This Cloud Application (Unbounce) allows you to register Webhooks which you can use to send data across from that platform to any other web application.

Please note that this article already assumes that the reader understands the basics of Webhooks and Azure Functions.

Webhooks sends data when a server event occurs typically to a web application. They are lightweight HTTP pattern with a publish/subscribe model which sends POST requests with JSON payload. This means Webhook POST requests can be consumed by any programming language or web application anywhere.

So when our 3rd party Cloud application (for example Unbounce) sends out the webhook POST message, how can Dynamics 365 receive this POST message? The answer is: Azure Functions.

It’s not the first time that Microsoft Azure Serverless Inegration capabilities, namely Azure Function Apps, come to the rescue. Azure Functions are becoming more and more the default preferred option for many Dynamics 365 related integrations.

So Unbounce sends out the webhook POST message to the Azure Function which in turn sends this data to Dynamics 365. To do this, you need to create an Azure Function that is triggered by Webhook and in your function, you can write the code that sends Data to Dynamics 365. Below are 6 steps that show case the process for adding an Azure Function App triggered by a Webhook POST call. Please comment below if you require the code in the Azure funciton (It’s standard Dynamcis 365 call to create a field so nothing fancy).

1) First, create your Azure Function App:

2) Make sure that the function is triggered by Webhook + API and using C#:

3) Then once created, create a Function within your Function app

4) Following that, we need to reference Dynamics 365 CRM SDK Core Assembly package. To do this, add a file called project.json as below:

5) then input your code inside the run.cx function which will receive JSON POST message and writes it to Dynamics 365:

6) then finally, run a test on your Azure Function App to see a record created in Dynamics 365 (a Lead in our case):

Please note that in step 5 above, you will definitely need to write code to receive the JSON payload that will come in the POST request message. So in our example, if this is coming from Unbounce, we have parse the Unbounce JSON data sent in the POST message so we can then use this data to create our lead (or contact) in Dynamics 365.

Please comment below if you require this code and I’ll be happy to share it.

Note: I’m delivering this session at a number of Dynamics 365 Saturday events starting tomorrow in London (7th July 2018). Hence, I’ll be updating it regularly (and apologies for rushing the post!)

Your feedback via comments below is invaluable and will encourage me to update it and write more about this subject.

Using Server to Server S2S authentication to connect your application to Dynamics 365 – .Net MVC Web application as an example

Microsoft has recently released a feature that allows your application to connect securely and seamlessly connect to Microsoft Dynamics 365 Online solutions. S2S authentication is now the standard way that apps registered on Microsoft AppSource use to access the Dynamics 365 data of their subscribers. I found this feature a great addition to help secure .Net MVC applications access to Dynamics 365.

With S2S authentication a special Dynamics 365 unlicensed application user account is created and includes information about your application registered with Azure Active Directory (Azure AD). Rather than user credentials, the application is authenticated based on a service principal identified by an Azure AD Object ID value which is stored in the Dynamics 365 application user record. The Dynamics 365 application user is associated with a custom security role which controls the kinds of data and operations the application is allowed to perform.

I have found this feature extremely useful and a specially secure way to integrate a number of my Azure hosted .Net MVC portal with Dynamics 365. I have recently changed all my portals to use this feature to benefit from the new functionality.

You will need to be careful though as all operations performed by your application or service in this case while using S2S, it will be performed as the application user you provide rather than as the user who is accessing your application. If you want your application to perform data operations on behalf of a specific user, such as the one who is interacting with your application, you can apply impersonation when the custom security role applied to your application service principal has the privileges required.

Further details and MSDN article source can be found here:

https://msdn.microsoft.com/library/mt790168.aspx

 

Microsoft Dynamics CRM Portal Development #MSDynCRM #CRM2013 Binding CRM data to ASP .NET Web Forms in an Application

There are many ways you can bind data from Microsoft Dynamics CRM into an ASP.Net web form. Dynamics CRM SDK provides a set of DLLs and helper classes that allows for some innovative portal development in Dynamics CRM. The most interesting of which, in my view, is the ability to bind a webpage to Dynamics CRM view so that every time you change the view, the changes are then automatically reflected on your web page on the next refresh.

So, in order to bind Dynamics CRM data to your website pages, you can either use:

  1. asp:LinqDataSource to bind CRM fields data to an ASP.Net webpage,
  2. crm:SavedQueryDataSource to bind a Dynamics CRM view into an Web Form so that any change to the view is reflected on the webpage,
  3. crm:CrmDataSource to have a webpage that renders a contact data entry form based on a Microsoft Dynamics CRM view definition in which case the Web Form displays the columns defined in your Dynamics CRM View, Or,
  4. Use code behind to connect a Microsoft Dynamics CRM data source to an ASP.NET GridView control.

To try the above, first create an ASP.Net Web Application in Visual Studio. Run the CRM Service Utility CRMSvcUtil.exe to generate all your early bind entity classes and service contexts. Add your generated class into your Web Application project.

Also, make sure you add the following references from the SDK\bin folder:
AntiXSSLibrary.dll
Microsoft.Crm.Sdk.Proxy.dll
Microsoft.Xrm.Client.dll
Microsoft.Xrm.Portal.dll
Microsoft.Xrm.Portal.Files.dll
Microsoft.Xrm.Sdk.dll

and then add the following references from .NET:
Microsoft.IdentityModel.dll
Microsoft.Data.Entity.dll
System.Data.Services.dll
System.Data.Services.Client.dll
System.Runtime.Caching.dll
System.Runtime.Serialization.dll

In your Web.config, make sure you add the following:

<configuration>
 <configSections>
 <section name="microsoft.xrm.client"
 type="Microsoft.Xrm.Client.Configuration.CrmSection, Microsoft.Xrm.Client" />
<connectionStrings>
 <add name="Xrm" connectionString="Server=http://crm/contoso; Domain=CONTOSO; Username=Administrator; Password=pass@word1" />
</connectionStrings>
<microsoft.xrm.client>
 <contexts>
 <add name="Xrm" type="Xrm.XrmServiceContext, YourWebApplicationProjectName" />
 </contexts>
</microsoft.xrm.client>
 <system.web>
 <pages>
 <controls>
 <add tagPrefix="crm" namespace="Microsoft.Xrm.Portal.Web.UI.WebControls" assembly="Microsoft.Xrm.Portal" />

In each of the above Four cases, you need to create an ASP.Net Form and then add the following code for each case:

(1)

<!--This example lists all contacts from the Microsoft Dynamics CRM system. -->
<asp:LinqDataSource ID="Contacts" ContextTypeName="Xrm.XrmServiceContext" TableName="ContactSet" runat="server" />
<asp:GridView DataSourceID="Contacts" AutoGenerateColumns="false" runat="server">
 <Columns>
 <asp:TemplateField HeaderText="First Name">
 <ItemTemplate>
 <asp:Label Text='<%# Eval("firstname")%>' runat="server" />
 </ItemTemplate>
 </asp:TemplateField>
 <asp:TemplateField HeaderText="Last Name">
 <ItemTemplate>
 <asp:Label Text='<%# Eval("lastname")%>' runat="server" />
 </ItemTemplate>
 </asp:TemplateField>
 <asp:TemplateField HeaderText="City">
 <ItemTemplate>
 <asp:Label Text='<%#Eval("address1_city") %>' runat="server" />
 </ItemTemplate>
 </asp:TemplateField>
 </Columns>
</asp:GridView>

(2)

<crm:SavedQueryDataSource ID="ActiveContacts" SavedQueryName="Active Contacts" runat="server" />
<asp:GridView DataSourceID="ActiveContacts" runat="server" />

(3)

<asp:ScriptManager runat="server" />
<crm:CrmDataSource ID="Contacts" runat="server" />
<crm:CrmEntityFormView DataSourceID="Contacts" EntityName="contact" SavedQueryName="Create Contact Web Form" runat="server" />

(4)

<asp:GridView ID="ContactsGridView" AutoGenerateColumns="false" runat="server">
 <Columns>
 <asp:TemplateField HeaderText="First Name">
 <ItemTemplate>
 <asp:Label Text='<%# Eval("firstname")%>' runat="server" />
 </ItemTemplate>
 </asp:TemplateField>
 <asp:TemplateField HeaderText="Last Name">
 <ItemTemplate>
 <asp:Label Text='<%# Eval("lastname") %>' runat="server" />
 </ItemTemplate>
 </asp:TemplateField>
 <asp:TemplateField HeaderText="City">
 <ItemTemplate>
 <asp:Label Text='<%# Eval("address1_city") %>' runat="server" />
 </ItemTemplate>
 </asp:TemplateField>
 </Columns>
</asp:GridView>

and the code behind:

using System;
using System.Linq;
using Xrm;
namespace YourCRMPortalProjectNameSpace
{
 public partial class WebForm_CodeBehind : System.Web.UI.Page
 {
 protected void Page_Load(object sender, EventArgs e)
 {
 var xrm = new XrmServiceContext("Xrm");
 //Use all contacts where the email address ends in @example.com.
 var exampleContacts = xrm.ContactSet
 .Where(c => c.EMailAddress1.EndsWith("@example.com"));
 ContactsGrid_CodeBehind.DataSource = exampleContacts;
 ContactsGrid_CodeBehind.DataBind();
 }
 }
}

In all of the above cases, once you create your web form, just save all files, build the project/solution and then right click and click run the webpage in the browser.

You should then end up with something like this:

ASP .Net Webpage rendering Dynamics CRM Data
ASP .Net Webpage rendering Dynamics CRM Data

Examples in this post are taken directly from Dynamics CRM SDK Portal Walkthrough page which describes the ability to build Dynamics CRM Websites and Portals and their webpages and web forms that are directly connected and linked to CRM as a backend.

 

ModernOdataApp and ModernSoapApp Dynamics CRM SDK Modern and Mobile Apps development in Visual Studio

Microsoft Dynamics CRM 2013 SDK has added new Sample Modern and Mobile Apps which show how to write a Windows 8 desktop modern application that can send requests to the organization web service without linking to the SDK assemblies.

These 2 Apps: ModernOdataApp and ModernSoapApp are good starting points for building and developing Windows 8 Apps for Dynamics CRM. They can be found in the Dynamics CRM SDK under the “Sample Code” folder: SampleCode\CS\ModernAndMobileApps

One important note is that if you try to open these Visual Studio solutions on a machine running windows server 2012, you will most likely get an error from Visual Studio stating that: “The Project is not supported by this installation”.

If you get this error message on your development environment which is running Windows Server rather than Windows 8, it is because Windows Server 2012 requires the “Desktop Experience” feature to allow you to open this Visual Studio project. This Visual Studio project builds a Windows 8 Desktop App and hence will require this feature as a minimum as otherwise you will not be able to build, package or deploy this sample App for Dynamics CRM. Hence, you must install the “Desktop Experience” feature on your Windows Server machine through your server manager add new roles or features under the “Manage” drop down menu. (or alternatively through Control Panel > Programs > turn on or off Windows Features).

The “Desktop Experience” feature can be found under Features >> “User Interfaces and Infrastructure” then “Desktop Experience”.

Please also note that you will need to register for Windows Store Developer license to be able to open these two app solutions.

Happy coding!

 

Getting Started with nopCommerce – Book Review

Packt Publishing has recently asked me to review the “Getting Started with nopCommerce” book. I have just finished reading it and I found the book to be a good introduction to any new starters who want to build a website using nopCommerce. The book does not focus on the programming, coding or extension of nopCommerce online shop but it rather focuses on the functionality. The book is more of a practical guide on how to install, setup and configure your Ecommerce store and Online shop based on nopCommerce. It does not include .NET code samples or guides on how to programmatically extend nopCommerce.

The book seems to be trying to show non-developers how to setup and configure nopCommerce with plenty of step by step guides supported with Screen shots of nopCommerce. It is about 125 pages, so not a massive or large book to read but rather an introduction guide if you want to quickly get started with the core functionality of nopCommerce.

I found the book to be fairly useful for nopCommerce starters and I recommend to site owners or starters who want to learn how to deploy and configure their nopCommerce Online store.

In case you don’t know what nopCommerce is, or do, here is what it is:

nopCommerce is an open source e-commerce solution and online shop that contains both a catalog frontend and an administration tool backend. nopCommerce is a fully customizable shopping cart. It’s stable and highly usable. From downloads to documentation, nopCommerce.com offers a comprehensive base of information, resources, and support to the nopCommerce community.

nopCommerce is a fully customizable shopping cart. It’s stable and highly usable. nopCommerce is an open source e-commerce solution that is ASP.NET 4.5 (MVC 4) based with a MS SQL 2005 (or higher) backend database. Our easy-to-use shopping cart solution is uniquely suited for merchants that have outgrown existing systems, and may be hosted with your current web host or our hosting partners. It has everything you need to get started in selling physical and digital goods over the internet. nopCommerce offers unprecedented flexibility and control.

Since it is open-source, nopCommerce’s source code is available free for download.

http://www.nopcommerce.com

If you have questions or need help with nopCommerce, please comment below or use the contact page to get intouch.

Scribe Insight (v 7.6) Bulk Delete and Bulk Insert into Microsoft Dynamics CRM and other products

Four years ago, I wrote a blog post about a way to do bulk delete of Microsoft Dynamics CRM records using Scribe Insight:http://www.mohamedibrahim.net/blog/2009/09/23/microsoft-dynamics-crm-bulk-delete-methods-using-scribe-insight-for-bulk-delete-dynamics-crm-records/

The post has been popular for a work around to do bulk delete before CRM 2011 came with the bulk delete system job (that wasn’t available before). Just recently, Scribe has released new version update which is Scribe Insight 7.6 and which includes bulk delete and bulk import functionality for its steps.

These new features have proven to be very popular amongst Scribe technical users and have recently been voted as the most required functionality in Scribe.

The advantage of bulk delete is clear where you can just delete all records of a specific entity in Dynamics CRM case.

The bulk insert into Dynamics CRM is even more useful as it means that Scribe will insert all records in one open connection rather than row by row if you select the just “insert” option. This means that Scribe will open one connection to Dynamics CRM API and insert all records then close the connection in contrast to inserting row by row if the bulk option is not selected.

Here is a screenshot of how the new bulk insert and bulk delete features look in Scribe Workbench DTS Step configuration:

 

Scribe Insight 7.6 Bulk Operations: Bulk Insert & Bulk Delete
Scribe Insight 7.6 Bulk Operations: Bulk Insert & Bulk Delete

 

 

Creating, consuming and using Microsoft Dynamics CRM 4.0 Service, Using CRM API and CRM SDK to access CRM database via the webservice

  

Creating, consuming and using Microsoft Dynamics CRM 4.0 Service, Using CRM API and CRM SDK to access CRM database via the webservice. Custom .NET code to access CRM, create, update (edit), insert, delete, retrieve (return) and retrievemultiple records for system entities and custom entities using both entity objects and dynamic entities. 

This post is a collection of the main methods that you would frequently use in your .NET code (Plugin, Website) that is accessing a dynamics CRM 4.0 system and consuming its CRM services. 

The CrmService Web service provides a set of methods used to perform the most common operations on system and custom entities. 

This collection mainly comes from sevaral pages on MSDN. I just thought it will be useful to have them all together if we need one or more of them. 

  

The following code shows how to set up the Web service, and how to use the Create and Retrieve methods. 

  

  

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://<servername>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
// Create an account entity and assign data to some attributes.
account newAccount = new account();
newAccount.name = "Greg Bike Store";
newAccount.accountnumber = "123456";
newAccount.address1_postalcode = "98052";
newAccount.address1_city = "Redmond";
 
// Call the Create method to create an account.
Guid accountId = service.Create(newAccount);
 
Guid contactId = new Guid("2B951FBC-1C56-4430-B23B-20A1349068F3");
 
// Call the Retrieve method to retrieve an existing contact.
ColumnSet myColumnSet = new ColumnSet();
myColumnSet.Attributes = new string[] { "firstname" };
contact myContact = (contact) service.Retrieve ("contact", contactId, myColumnSet)

  

 

 

—————————- 

The following example demonstrates the use of the Create method. 

  

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
 
// You can use enums.cs from the SDK\Helpers folder to get the enumeration 
//   for Active Directory authentication.
token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://<servername>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
// Create the contact object.
contact contact = new contact();
 
// Create the properties for the contact object.
contact.firstname = "Jesper";
contact.lastname = "Aaberg";
contact.address1_line1 = "23 Market St.";
contact.address1_city = "Sammamish";
contact.address1_stateorprovince = "MT";
contact.address1_postalcode = "99999";
contact.donotbulkemail = new CrmBoolean();
contact.donotbulkemail.Value = true;
 
// Create the contact in Microsoft Dynamics CRM.
Guid contactGuid = service.Create(contact);

  

———————————- 

  

The following example demonstrates the use of the Retrieve method. 

  

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
 

// You can use enums.cs from the SDK\Helpers folder to get the enumeration
//   for Active Directory authentication

  

token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://<servername>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
// Create the column set object that indicates the properties to be retrieved.
ColumnSet cols = new ColumnSet();
 
// Set the properties of the column set.
cols.Attributes = new string [] {"fullname"};
 
// contactGuid is the GUID of the record being retrieved.
Guid contactGuid = new Guid("4D507FFE-ED25-447B-80DE-00AE3EB18B84");
 
// Retrieve the contact.
// The EntityName indicates the EntityType of the object being retrieved.
contact contact = (contact)service.Retrieve(EntityName.contact.ToString(), 
                                             contactGuid, cols);

  

  

—————————- 

  

The following example demonstrates the use of the RetrieveMultiple method. 

  

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
 

// You can use enums.cs from the SDK\Helpers folder to get the enumeration
//   for Active Directory authentication

  

token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://<servername>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
// Create the ColumnSet that indicates the properties to be retrieved.
ColumnSet cols = new ColumnSet();
 
// Set the properties of the ColumnSet.
cols.Attributes = new string [] {"fullname", "contactid"};
 
// Create the ConditionExpression.
ConditionExpression condition = new ConditionExpression();
 
// Set the condition for the retrieval to be when the 
//    contact's address' city is Sammamish.
condition.AttributeName = "address1_city";
condition.Operator = ConditionOperator.Like;
condition.Values = new string [] {"Sammamish"};
 
// Create the FilterExpression.
FilterExpression filter = new FilterExpression();
 
// Set the properties of the filter.
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] {condition};
 
// Create the QueryExpression object.
QueryExpression query = new QueryExpression();
 
// Set the properties of the QueryExpression object.
query.EntityName = EntityName.contact.ToString();
query.ColumnSet = cols;
query.Criteria = filter;
 
// Retrieve the contacts.
BusinessEntityCollection contacts = service.RetrieveMultiple(query);

  

—————————- 

  

  

The following example demonstrates the use of the Update method. 

  

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
 

// You can use enums.cs from the SDK\Helpers folder to get the enumeration
//   for Active Directory authentication

  

token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://<servername>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
// Create the contact object.
contact contact = new contact();
 
// Set the contact object properties to be updated.
contact.address1_line1 = "34 Market St.";
 
// The contactid is a key that references the ID of the contact to be updated.
contact.contactid = new Key();
// The contactid.Value is the GUID of the record to be changed.
contact.contactid.Value = new Guid("4D507FFE-ED25-447B-80DE-00AE3EB18B84");
 
// Update the contact.
service.Update(contact);

  

—————————- 

  

The following example demonstrates the use of the Delete method. 

  

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
 

// You can use enums.cs from the SDK\Helpers folder to get the enumeration
//   for Active Directory authentication

  

token.AuthenticationType = 0; 
token.OrganizationName = "AdventureWorksCycle";
 
CrmService service = new CrmService();
service.Url = "http://<servername>:<port>/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
// contactGuid is the GUID of the record being deleted.
Guid contactGuid = new Guid("4D507FFE-ED25-447B-80DE-00AE3EB18B84");
 
// Delete the contact.
// The EntityName indicates the EntityType of the object being deleted.
service.Delete(EntityName.contact.ToString(), contactGuid);

  

—————————- 

  

For Dynamic Entities: The following sample shows how to create a new entity instance by calling the CreateEntity method followed by the AddObject method. 

  

var contact = crm.CreateEntity("contact");
 
// Set the string properties.
contact.SetPropertyValue("firstname", "Allison");
contact.SetPropertyValue("lastname", "Brown");
contact.SetPropertyValue("emailaddress1", "allison.brown@contoso.com");
 
// Setting an explicit ID value is optional, it can be left unassigned, 
//    but here it is being explicitly assigned.
var id = Guid.NewGuid();
contact.SetPropertyValue("contactid", id);
 
// Pass the entity name of the entity being created as the first parameter.
crm.AddObject("contact", contact);
crm.SaveChanges();
 
// The ID value can be retrieved after you have called the SaveChanges method.
var id2 = contact.GetPropertyValue<Guid>("contactid");

  

  

  

These methods have been collected from MSDN mainly from these two locations:  http://msdn.microsoft.com/en-us/library/cc151016.aspx and http://msdn.microsoft.com/en-us/library/ff681571.aspx  

  

  

Ajax Update progress screen to block access to form during background server side processes

If you are writing an Ajax based .NET web application or web page, there are situations were you might want to block the whole webpage from being accessed while a background or server side process is taking place. So for example if the user clicks submit, you want to make the web page not accessible until the backend server side event handler function finishes and reloads the page.

To do this, you need to do the following:

In the button click event, call the javascript function showprogress (client side – aspx page code):
———————-

<asp:Button ID="ApplyFilterButton" runat="server" OnClick="ApplyFilterButton_Click"
OnClientClick="if(Page_ClientValidate())ShowProgress();" Text="Apply Filter"
CssClass="ms-crm-Button" Style="height: 23px" />

The show progress function should look something like the following:
————————

<script type="text/javascript">
   function ShowProgress() {
document.getElementById('<% Response.Write(PageUpdateProgress.ClientID); %>').style.display = "inline";
        }
</script>

 The update progress control should look something like this:
————————

<asp:UpdateProgress ID="PageUpdateProgress" runat="server"
AssociatedUpdatePanelID="PageHiddenPanel" DisplayAfter="50">
  <ProgressTemplate>
     <div id="progressDiv"
     style="background-position: center center;
     background-image: url(../../Images/progress.gif);
     background-repeat: no-repeat; background-attachment: fixed;
     vertical-align: middle; background-color: #000;
     filter: alpha(opacity=50);">
            </div>
            <script type="text/javascript">
                var targetDiv = document.getElementById("progressDiv");
                targetDiv.style.top = 0;
                targetDiv.style.left = 0;
                targetDiv.style.height = screen.availHeight;
                targetDiv.style.width = screen.availWidth;
            </script>
        </ProgressTemplate>
    </asp:UpdateProgres> 

 Hope it helps.

Creating and Using Silverlight web.config app settings (Web.config Configuration Applicatioin Settings) or app.config application settings configuration file for Silverlight

Post Summary:

This posts explains how to create and use something similar to a silverlight  web.config, App.config and appsettings (or app settings) configuration file for silverlight application. This is based on re-using serviceReference.clientconfig as an appconfig configuration file.

The Problem:

A) configuration application settings (like the one in web.config, appsettings or app settings application configuration file):
This is probably very common. Your silverlight application might well need to have some configuration settings that you can change their values without having to re-build and re-deploy the whole application because of a small change in a connection string or appSetting value. Again, AppSettings in good old web.config files in ASP.net applications were the best solution in this case.

B) WCF Address (EndPoint address value) change after building:
Another reason for wanting to have a configuration file in a silverlight application: Have you ever wanted to change the WCF service address (endpoint address) in your silverlight application after deployment. Imagine that you built a silverlight application and deployed it on your test server. The application was tested and confirmed issues and bug free. Now you want to re-deploy the application to the Live server but the WCF service address (end point address) is different which is probably quite common. It might also be that the address is the same but the port on which the WCF service is listening is different. In this case, you will need to change the value of the WCF endpoint address and re-build. So what happened to configuration files! They are a standard now in all Microsoft environments.

Problem Summary: The problem is there is no clear web.config file in silverlight as the whole code is compiled into a (.xap) file which any html or aspx page can call.

Solution:

In my silverlight application, I had a connection string value that I need to use in my silverlight application (pass it to the webservice). Hence, I wanted the flexibility to change the WCF endpoint address and the connection string configuration value (or any other application setting). I started looking for a solution but I found that most work arounds were either t0o long or too complicated. As always, I like simple things and I don’t like over complications. I have to say though that most if not all work arounds that I found were useful for me to come up with this solution. I am not sure but I believe (and hope) the following solution is unique as I have searched for quite a while to find anyone suggesting this idea but I couldn’t find any.

Solution part 1: The simplest way for adding application settings to a silverlight application.

Now since ServiceReferences.ClientConfig is just an xml configuration file, you can actually edit it in visual studio and simply add your application settings.

Your file will look something like this:

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name=”xrmServiceBasicHttp” maxBufferSize=”2147483647″
                    maxReceivedMessageSize=”2147483647″>
                    <security mode=”None”>
                        <transport>
                            <extendedProtectionPolicy policyEnforcement=”Never” />
                        </transport>
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address=”http://localhost:1234/MyWCFService.svc” binding=”basicHttpBinding”
                bindingConfiguration=”xrmServiceBasicHttp” contract=”XrmService.IXrmService”
                name=”xrmServiceBasicHttp” />
        </client>
    </system.serviceModel>
<appSettings>
<add key=”ConnectionString” value=”data source=ABC01;initial catalog=DB01;integrated security=SSPI;persist security info=False;packet size=4096″ />  
</appSettings>
</configuration>

Now that you have added your application setting (connection string) to your ServiceReferences.ClientConfig, you need to use it in your silverlight code behind (.xaml.cs) file.

Remember, ServiceReferences.ClientConfig is just an XML file (already said that many times!). Hence, you can write a very simple and straight forward function that parses your ServiceReferences.ClientConfig xml file and returns the appSetting value of your application setting.
A function to return an AppSetting value from your clientconfig file can look something like this:

private string getAppSetting(string strKey)
        {
            string strValue = string.Empty;
            XmlReaderSettings settings = new XmlReaderSettings();           
            settings.XmlResolver = new XmlXapResolver();
            XmlReader reader = XmlReader.Create(“ServiceReferences.ClientConfig”);
            reader.MoveToContent();
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == “add”)
                {
                    if (reader.HasAttributes)
                    {
                        strValue = reader.GetAttribute(“key”);
                        if (!string.IsNullOrEmpty(strValue) && strValue == strKey)
                        {
                            strValue = reader.GetAttribute(“value”);
                            return strValue;
                        }
                    }
                }
            }
            return strValue
}

Finally in your code, to retrieve the AppSetting value for the appSetting key (ConnectionString) that you created, you can just call the above function like this:

client.SetConnectionStringAsync(getAppSetting(“ConnectionString”));

And One last thing, remember when you create the WCF service client object, don’t explicitly call the WCF service address, as it is already in your ClientConfig file.

So, just call the end Point Configuration Name (endPointConfigurationName) that you want to use. Just like this:

MyServiceClient client = new MyServiceClient(“MyServiceBasicHttp”);

———-

Solution part 2: Changing WCF address and endpoint values in “ServiceReferences.ClientConfig”.

Anyway, the first thing we need to do is to understand that “ServiceReferences.ClientConfig” that all silverlight applications have and use if they are connecting to a WCF sercvice, is just a simple XML file. Actually, not only an XML file but also a configuration file for the application.

You also need to know that the silverlight xap (*.xap) file that silverlight generates is a simple compressed (zipped) file. For this reason, you actually can rename the file to (something.zip) from (something.xap) and then you can access its content. The content of the xap file includes AppManifes.xaml, your application dlls and most importantly “ServiceReferences.ClientConfig”.

Now, when I tried to unzip it, change the content of one of its files and then re-zip it and rename it back to (something.xap), this has corrupted it. My application failed. I am not sure why. This was the case despite the fact that most posts about unpacking, unzipping and re-packaging the .xap file works.

What actually works is the following:
Rename the something.xap file to something.zip file. Open the zip file without unzipping (just double click on it) and then copy the file you want to edit, which in our case is the “ServiceReferences.ClientConfig” and paste it in a different location. Edit it and make all the changes you need to it and then copy it and paste back into the something.zip file. Replace the exisitng file there. Now go to something.zip and rename it back to something.xap.

Whatever change you have made should now work.

———–

I hope this helps. I really think it is an effective way to get your AppSetting values.

If you got any questions, please comment below (Kindly don’t use the contact page for questions on posts please)

Also, please let me know (via a comment below) if you want a copy of this application code.

Problems with Deploying WCF services on IIS 7.0 (or IIS 6, IIS) and other deployment options and scenarios (visual studio .NET and Windows Activation Services)

There are 3 main ways to deploy Windows Communication Foundation – WCF services to consume:

1- IIS
2- Windows Activation Service a.k.a WAS
3- Visual Studio .NET for development and dev testing purposes as part of a visual studio solution.

For full details about Windows Communciation Foundation deployment scenarios, categories and structure please refer to this MSDN article: http://msdn.microsoft.com/en-us/library/cc512374.aspx

This post is focusing on issues and problems faced with WCF running on IIS.

Recently, I had a working WCF service that I wanted to deploy on one of my client’s web servers. The webserver is a simple Windows 2008 web server with obviously web server role turned on.

After publishing the WCF service, I logged on the web server’s IIS 7 management console and started creating the webservice as a separate website. Please note that you may be able to create the web service as a web application under the default website or any website if you want (haven’t tried it before but should work). But do NOT do this if your default website is a Microsoft Dynamics CRM application server. Reason being that if you do add a webservice under Microsoft Dynamics CRM website, you will probably cause problems and major issues with authentication, client policies, cross domains, etc, etc..

So, I created my WCF service as a new website. tryied to browse to the service .svc file (webservice.svc for example) but I got an error 404, no https handler avaialble to process this request. Error details says: “The page you requested has a file name extension that is not recognized, and is not allowed.”

Looking in my handler mappings, I found out that there is no resource Dlls or managed code, to handle responses for *.svc request type. Normally you should have one of three *.svc mappings:
1- svc-Integrated handling *.svc – handler is System.ServiceModel.Activation.HttpHandler
2- svc-ISAPI-2.0-64 handling *.svc – handler this time is IsapiModule
3- svc-ISAPI-2.0 handling *.svc – handler is also IsapiModule.

If you dont have these handler mappings (although you normally should), make sure you add them manually. If you try to add them and can’t find any of the modules: IsapiModule or System.ServiceModel.Activation.HttpHandler, then go to Modules and make sure these two modules are enabled and avaialble.

This fixed my issue. But, you may have another problem:

– Make sure that in windows features, you have both WCF options under .Net framework are ticked. So go to Control Panel –> Programs and Features –> Turn Windows Features ON/Off –> Features –> Add Features –> .NET Framework X.X Features. Make sure that .Net framework says it is installed, and make sure that the WCF Activation node underneath it is selected (checkbox ticked) and both options under WCF Activation are also checked. These are:
* HTTP Activation
* Non-HTTP Activation
Both options need to be selected (checked box ticked).

– Make sure that the website is running as ASP .NET 2.0

– If you are still having problems, try Registering WCF From The Command Prompt . You can do this by running the following command from a command prompt (In Windows 7 you need to run command prompt as administrator – right click on shortcut and then click run as administrator).
To register WCF from the command prompt, use the following commands:

Navigate to WCF folder:

cd %SYSTEMROOT%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation

Where %SYSTEMROOT% is usually by default C:/Windows/

Then run this command:
ServiceModelReg.exe /i /x

Alternatively just run the following command:
%SYSTEMROOT%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe /i /x
– If this still doesn’t work, please try the steps listed in this blog post: http://bloggingabout.net/blogs/jpsmit/archive/2007/01/17/wcf-http-404-when-hosted-in-iis.aspx

I haven’t tried any of these steps before but some people found it useful.
All solutions are provided as is with no guarantees.

Please write a comment with any questions or experience you have with deploying WCF on IIS 7
Hope this helps.

Thanks.