<feed xml:base="http://bloggiovannimodica.azurewebsites.net/" xmlns="http://www.w3.org/2005/Atom"><title type="text">Giovanni's Blog</title><subtitle type="text">Latest blog posts</subtitle><id>uuid:513d992d-9e63-4f22-86de-7d769aa809e8;id=1</id><updated>2026-04-16T02:36:44Z</updated><link href="http://bloggiovannimodica.azurewebsites.net/" /><entry><id>http://bloggiovannimodica.azurewebsites.net/post/using-the-same-visualforce-page-for-both-desktop-and-salesforce1</id><title type="text">Using the Same Visualforce Page for both Browser and Salesforce1 Clients</title><updated>2016-05-01T17:19:16Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/using-the-same-visualforce-page-for-both-desktop-and-salesforce1" /><content type="text">&lt;p&gt;You have probably come up with a scenario where you need to create a custom Visualforce page for a custom object and have that page available for both the browser and the Salesforce1 application. Right now there’s no easy way to tell Salesforce to use a specific page for the browser version and another different page for SF1. Let’s focus the problem from the UI/UX perspective: how to leverage the UI and best practices associated to each specific platform. So basically, if we use the Visualforce tags to build for the browser then the SF1 experience will not be the desired one (it will actually be very ugly!), and if we decide to not use Visualforce tags and instead use pure HTML5 (as recommended by the Salesforce1 practices) then the page will look good in SF1 but for browser users it will look different. We want to create a Visualforce page that will change its look depending on the client used to display it. Here’s an example&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/bb59818d-3fd6-488d-ba27-a8eacd0fb005.png"&gt;&lt;img width="1028" height="339" title="Same page for both browser and SF1" style="display: inline; background-image: none;" alt="Same page for both browser and SF1" src="http://blog.giovannimodica.com/posts/files/561cd6a2-45ad-4e7b-86f0-b5f8f95f2fa9.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;On the image you can see how the UI for each client is maintained. Also notice that in the case of SF1 we are using the standard publisher buttons to work with the page. Same page, same controller, but different UI and UX depending on the client. How we achieve this? Read on.&lt;/p&gt;&lt;h2&gt;An Example&lt;/h2&gt;&lt;p&gt;Let’s use an example to illustrate the problem. In our example we’re developing a questionnaire application: users are able to create questionnaires which will have many questions associated. This is an example of a questionnaire:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/1bf64e03-8a51-4375-a36d-f206e7f00c2e.png"&gt;&lt;img width="644" height="331" title="questionnaire" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="questionnaire" src="http://blog.giovannimodica.com/posts/files/a6c75b21-fb2a-424f-8374-7b6c88def3ad.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The questionnaire could be associated to any object, and we want to be able to answer a specific questionnaire by using both the browser client and the Salesforce1 app. Since the number of questions may vary, we need to build a Visualforce page that dynamically displays the questions associated to a specific questionnaire (we could not do this with a standard layout). Our Visualforce page will have a controller extension associated that will drive the logic of the page. We will associate a questionnaire to a Contact for this example.&lt;/p&gt;&lt;p&gt;Here is our controller extension:&lt;/p&gt;&lt;pre class="brush: java;"&gt;public with sharing class ceContactQuestionnaire {
    private final ApexPages.StandardController controller;
    private final Contact contactRecord;
    
    public ceContactQuestionnaire(ApexPages.StandardController controller) {
        this.controller = controller;
        controller.addFields(new String[] {sObjectType.Contact.fields.Questionnaire__c.Name});        
        this.contactRecord = (Contact)controller.getRecord();
    }
    
    public String questionnaireName {
        get {
            if(questionnaireName == null &amp;amp;&amp;amp; contactRecord.Questionnaire__c != null) {
                List&amp;lt;Questionnaire__c&amp;gt; q = [select Name from Questionnaire__c where Id = :contactRecord.Questionnaire__c];
                if(q.size() &amp;gt; 0) questionnaireName = q[0].Name;
            }
            return questionnaireName;
        }
        private set {
            questionnaireName = value;
        }
    }    

    public List&amp;lt;Contact_Question__c&amp;gt; questions {
        get {
            if(questions == null) {
                questions = new List&amp;lt;Contact_Question__c&amp;gt;();
                for(Contact_Question__c question : [select Id,Question__c,Answer__c from Contact_Question__c where Contact__c = :contactRecord.Id order by Order__c]) {
                    questions.add(question);
                }                    
            }
            return questions;
        }
        set {
            questions = value;
        }
    }
    
    public PageReference save() {
        upsert questions;
        return controller.save();
    }      
}
&lt;/pre&gt;&lt;p&gt;You can see is actually a pretty simple controller: the contact has a questionnaire associated and an auxiliary object with all the questions for the questionnaire. We get those questions and we make it available as a property. The extension also overrides the &lt;font face="Courier New"&gt;save&lt;/font&gt; method to save the answers given to those questions.&lt;/p&gt;&lt;p&gt;Let’s first design the page by using the Visualforce tags that we’ll use on a browser version of the page:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;apex:page standardController="Contact" extensions="ceContactQuestionnaire" &amp;gt;
    
    &amp;lt;apex:pageMessages /&amp;gt;
    &amp;lt;apex:sectionHeader title="{!$ObjectType.Questionnaire__c.Label}: {!questionnaireName}" subtitle="{!Contact.Name}" /&amp;gt;
    &amp;lt;apex:form &amp;gt;
        &amp;lt;apex:pageBlock &amp;gt;
            &amp;lt;apex:pageBlockButtons &amp;gt;
                &amp;lt;apex:commandButton action="{!save}" value="Save" styleClass="btn btn-default" /&amp;gt;
                &amp;lt;apex:commandButton action="{!cancel}" value="Cancel" styleClass="btn btn-default" /&amp;gt;
            &amp;lt;/apex:pageBlockButtons&amp;gt;
            &amp;lt;apex:pageBlockSection columns="1"&amp;gt;
                &amp;lt;apex:repeat var="question" value="{!questions}"&amp;gt;
                    &amp;lt;apex:pageBlockSectionItem &amp;gt;
                        &amp;lt;apex:outputLabel value="{!question.Question__c}" /&amp;gt;
                        &amp;lt;apex:inputTextarea cols="80" rows="3" value="{!question.Answer__c}"/&amp;gt;
                    &amp;lt;/apex:pageBlockSectionItem&amp;gt;
                &amp;lt;/apex:repeat&amp;gt;
            &amp;lt;/apex:pageBlockSection&amp;gt;
        &amp;lt;/apex:pageBlock&amp;gt;
    &amp;lt;/apex:form&amp;gt;
&amp;lt;/apex:page&amp;gt;
&lt;/pre&gt;&lt;p&gt;This is a pretty simple Visualforce page, we just render each question we get from the controller as a label for the question and a text area for the answer. This is how it looks on the browser:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/ea44459f-62a7-47ca-8387-ef94d62ed572.png"&gt;&lt;img width="644" height="350" title="rendering on browser" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="rendering on browser" src="http://blog.giovannimodica.com/posts/files/a907a802-1bf7-4eb0-8738-77ee46b1c685.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;No surprises here: we’re using the familiar UI and look&amp;amp;feel of a Salesforce layout. Let’s make our Visualforce page available for SF1 (edit the page and select the option “Available for Salesforce mobile apps”) so we can open the page in SF1. You’ll notice that the UI and look&amp;amp;feel are pretty ugly:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/9a112bf6-d1ff-440e-881b-2071c21c95dc.png"&gt;&lt;img width="626" height="484" title="rendering on SF1" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="rendering on SF1" src="http://blog.giovannimodica.com/posts/files/95d2022e-4831-4037-97e3-7ae95f958394.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;If we present mobile users with this layout they will probably complain about it and not feel happy. So how do we fix this?&lt;/p&gt;&lt;h2&gt;Determine what Client is Being Used&lt;/h2&gt;&lt;p&gt;We need a way to know which client is using our Visualforce page so we can present the appropriate content and user experience. There is no official way to know this, but there are some tricks. Here I will use the parameters of the page to know whether I’m in a browser or in the SF1 app. We need a property in the controller extension:&lt;/p&gt;&lt;pre class="brush: java;"&gt;public Boolean isSF1 {
    get {                    
        if(String.isNotBlank(ApexPages.currentPage().getParameters().get('sfdcIFrameHost')) ||
            String.isNotBlank(ApexPages.currentPage().getParameters().get('sfdcIFrameOrigin')) ||
            ApexPages.currentPage().getParameters().get('isdtp') == 'p1' ||
            (ApexPages.currentPage().getParameters().get('retURL') != null &amp;amp;&amp;amp; ApexPages.currentPage().getParameters().get('retURL').contains('projectone') )
        ) {
            return true;
        }else{
            return false;
        }
    }
}
&lt;/pre&gt;&lt;p&gt;I will use this property to dynamically adjust the UI of the Visualforce page. &lt;/p&gt;&lt;h2&gt;One Page for All&lt;/h2&gt;&lt;p&gt;For the UI I will use a special version of &lt;a href="http://developer.salesforcefoundation.org/bootstrap-sf1/index.html"&gt;Bootstrap for Salesforce1&lt;/a&gt;, which I have added as a static resource. This is how the page looks now:&lt;/p&gt;&lt;pre class="brush: xml; highlight: [2,4,25];"&gt;&amp;lt;apex:page standardController="Contact" extensions="ceContactQuestionnaire" docType="html-5.0" tabStyle="Questionnaire__c"&amp;gt;
    &amp;lt;apex:stylesheet value="{!URLFOR($Resource.Bootstrap_SF1,'/css/bootstrap-namespaced.min.css')}"/&amp;gt;
    
    &amp;lt;apex:outputPanel rendered="{!!isSF1}"&amp;gt;
        &amp;lt;apex:pageMessages /&amp;gt;
        &amp;lt;apex:sectionHeader title="{!$ObjectType.Questionnaire__c.Label}: {!questionnaireName}" subtitle="{!Contact.Name}" /&amp;gt;
        &amp;lt;apex:form &amp;gt;
            &amp;lt;apex:pageBlock &amp;gt;
                &amp;lt;apex:pageBlockButtons &amp;gt;
                    &amp;lt;apex:commandButton action="{!save}" value="Save" styleClass="btn btn-default" /&amp;gt;
                    &amp;lt;apex:commandButton action="{!cancel}" value="Cancel" styleClass="btn btn-default" /&amp;gt;
                &amp;lt;/apex:pageBlockButtons&amp;gt;
                &amp;lt;apex:pageBlockSection columns="1"&amp;gt;
                    &amp;lt;apex:repeat var="question" value="{!questions}"&amp;gt;
                        &amp;lt;apex:pageBlockSectionItem &amp;gt;
                            &amp;lt;apex:outputLabel value="{!question.Question__c}" /&amp;gt;
                            &amp;lt;apex:inputTextarea cols="80" rows="3" value="{!question.Answer__c}"/&amp;gt;
                        &amp;lt;/apex:pageBlockSectionItem&amp;gt;
                    &amp;lt;/apex:repeat&amp;gt;
                &amp;lt;/apex:pageBlockSection&amp;gt;
            &amp;lt;/apex:pageBlock&amp;gt;
        &amp;lt;/apex:form&amp;gt;
    &amp;lt;/apex:outputPanel&amp;gt;
    
    &amp;lt;apex:outputPanel rendered="{!isSF1}"&amp;gt;
        &amp;lt;div class="bootstrap" style="padding: 10px;"&amp;gt;
            &amp;lt;h1&amp;gt;{!$ObjectType.Questionnaire__c.Label}: {!questionnaireName} &amp;lt;small&amp;gt;{!Contact.Name}&amp;lt;/small&amp;gt;&amp;lt;/h1&amp;gt;
            &amp;lt;apex:form &amp;gt;
                &amp;lt;apex:repeat var="question" value="{!questions}"&amp;gt;
                    &amp;lt;div class="form-group"&amp;gt;
                        &amp;lt;label&amp;gt;{!question.Question__c}&amp;lt;/label&amp;gt;
                        &amp;lt;apex:inputTextarea value="{!question.Answer__c}" rows="3" cols="80" styleClass="form-control"/&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/apex:repeat&amp;gt;
                &amp;lt;span id="submit"&amp;gt;&amp;lt;apex:commandButton action="{!save}" value="Save" styleClass="btn btn-default" /&amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span id="cancel"&amp;gt;&amp;lt;apex:commandButton action="{!cancel}" value="Cancel" styleClass="btn btn-default" /&amp;gt;&amp;lt;/span&amp;gt;                            
            &amp;lt;/apex:form&amp;gt;
        &amp;lt;/div&amp;gt;
        
    &amp;lt;/apex:outputPanel&amp;gt;
&amp;lt;/apex:page&amp;gt;
&lt;/pre&gt;&lt;p&gt;Notice on line 2 how I use the static resource for the Bootstrap for SF1 CSS library. Lines 4 and 25 create two &lt;font face="Courier New"&gt;outputPanel&lt;/font&gt;s that will be rendered based on the property we created in the controller extension to determine if the page is being called from SF1. The first output panel will be rendered for the browser client, and the code and layout is the same we had before. The new part is the second output panel, which will be rendered for the SF1 app. Notice that the code for the SF1 layout doesn’t use page blocks or any of the standard layout tags, but instead uses standard HTML div tags to layout the content. Now the page in the browser still looks as before, but on SF1 it now looks like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/5ced6001-d916-4fc5-b58f-f8c421d6a0a0.png"&gt;&lt;img width="644" height="470" title="rendering on FS1 using Bootstrap" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="rendering on FS1 using Bootstrap" src="http://blog.giovannimodica.com/posts/files/b61f44c0-6271-4954-87fd-7b2d1cc35040.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Definitely better isn’t? But there’s still something that doesn’t fit right into the SF1 experience: the publisher bar. Notice that we still have two buttons for saving and canceling, and that save button on the publisher bar appears disabled. We need to take advantage of the publisher bar and provide a seamless user experience to our SF1 users.&lt;/p&gt;&lt;h2&gt;Taking Care of the Publisher Bar&lt;/h2&gt;&lt;p&gt;Using the publisher bar is pretty easy once you know what to do, of course. Here is the modified section of the page for the SF1 part:&lt;/p&gt;&lt;pre class="brush: xml; highlight: [11,15,18,19,22];"&gt;&amp;lt;apex:outputPanel rendered="{!isSF1}"&amp;gt;
    &amp;lt;div class="bootstrap" style="padding: 10px;"&amp;gt;
        &amp;lt;h1&amp;gt;{!$ObjectType.Questionnaire__c.Label}: {!questionnaireName} &amp;lt;small&amp;gt;{!Contact.Name}&amp;lt;/small&amp;gt;&amp;lt;/h1&amp;gt;
        &amp;lt;apex:form &amp;gt;
            &amp;lt;apex:repeat var="question" value="{!questions}"&amp;gt;
                &amp;lt;div class="form-group"&amp;gt;
                    &amp;lt;label&amp;gt;{!question.Question__c}&amp;lt;/label&amp;gt;
                    &amp;lt;apex:inputTextarea value="{!question.Answer__c}" rows="3" cols="80" styleClass="form-control"/&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/apex:repeat&amp;gt;
            &amp;lt;apex:actionFunction action="{!save}" name="saveForm" /&amp;gt;                
        &amp;lt;/apex:form&amp;gt;
    &amp;lt;/div&amp;gt;
    
    &amp;lt;script src='/canvas/sdk/js/publisher.js'&amp;gt;&amp;lt;/script&amp;gt;

    &amp;lt;script&amp;gt;
        if(sforce.one) {                       
            Sfdc.canvas.publisher.subscribe({name: "publisher.showPanel", onData:function(e) { 
                Sfdc.canvas.publisher.publish({name: "publisher.setValidForSubmit", payload: "true"});                                       
            }});
            Sfdc.canvas.publisher.subscribe({name: "publisher.post", onData:function(e) {
                saveForm();
                Sfdc.canvas.publisher.publish( { name: "publisher.close", payload:{refresh:"false"}}); 
            }});            
        }
    &amp;lt;/script&amp;gt;
    
&amp;lt;/apex:outputPanel&amp;gt;
&lt;/pre&gt;&lt;p&gt;To work with the publisher bar we need to reference the publisher API (this is provided by the Salesforce platform). You can see we add a reference to the library in line 15. In line 18 we use the &lt;font face="Courier New"&gt;sforce.one&lt;/font&gt; property to know whether we are in SF1 or not (although this section will not be rendered if we’re not in SF1, it is a good practice to put this check). Notice that we removed the two buttons we had in the previous version for the save and cancel, as we don’t need them anymore since we will use the buttons on the publisher bar instead.&lt;/p&gt;&lt;p&gt;The publisher API works with a publisher/subscriber pattern: it exposes some events that we could subscribe to, or publish, as needed. In line 19 we subscribe to the &lt;font face="Courier New"&gt;publisher.showPanel&lt;/font&gt; event, which will get fired when the page is opened and finished rendering, in which case we need to enable the save button on the bar. We can tell the publisher API to enable the save button by firing the &lt;font face="Courier New"&gt;publisher.setValidForSubmit&lt;/font&gt; event.&lt;/p&gt;&lt;p&gt;In line 22 we subscribe to the &lt;font face="Courier New"&gt;publisher.post&lt;/font&gt; event, which gets fired when the user taps on the save button on the publisher bar. In this case we need to save the form, by calling the action function defined in line 11, which will call the &lt;font face="Courier New"&gt;save&lt;/font&gt; action on the controller extension. And finally we publish the &lt;font face="Courier New"&gt;publisher.close&lt;/font&gt; event to notify the API to dismiss the current page.&lt;/p&gt;&lt;p&gt;This is how the SF1 page looks now with the publisher bar enabled:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/9b63d9b5-e8f5-480b-8d6b-a3860829e926.png"&gt;&lt;img width="644" height="413" title="rendering on FS1 using the publisher bar" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="rendering on FS1 using the publisher bar" src="http://blog.giovannimodica.com/posts/files/3b331d48-0c74-461b-968c-fc959471fe37.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Users can now answer questions and when done tap on the save button to save their changes, and this will all work with the UI/UX of a SF1 application.&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/using-azure-app-services-to-integrate-with-salesforce</id><title type="text">Using Azure App Services to Integrate with Salesforce</title><updated>2016-05-16T21:36:23Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/using-azure-app-services-to-integrate-with-salesforce" /><content type="text">&lt;p&gt;Microsoft recently announced &lt;a href="http://azure.microsoft.com/en-us/services/app-service/"&gt;Azure App Service&lt;/a&gt;, a new Azure service which integrates Web Apps, Mobile Apps, Logic Apps and API Apps in one service. Scott Guthrie’s blog has a very good &lt;a href="http://weblogs.asp.net/scottgu/announcing-the-new-azure-app-service"&gt;article&lt;/a&gt; that explains this new service.&lt;/p&gt;&lt;p&gt;In this article I will talk about how to use Azure App Services to integrate with Salesforce. For this example I will develop a small solution based on a real case scenario. I will assume the reader is more familiarized with Microsoft’s technology so I will spend more time explaining the details about Salesforce.&lt;/p&gt;&lt;h1&gt;The Scenario&lt;/h1&gt;&lt;p&gt;The scenario is the following: suppose that our client is an insurance company that uses Salesforce as its CRM. Insured's call the Call Center department to requests assistances depending on the policy coverage they have contracted, for example: assistance on the road (for automotive policies), or request for professional assistance - e.g. a plumber, locksmith, etc. – at home (for home insurance policies). All assistances are attended by third party service providers (car shops, locksmiths, car towing companies, etc.) The idea is that service requests are made in the CRM, and then third party service providers can attend these requests and mark them as completed once the service has been delivered. It would be ideal that external providers could have access to the CRM to see all the pending requests and do updates directly in the system. However, in our case it won’t be that easy: there are many service providers and we don’t want to buy Salesforce licenses for them (Salesforce licenses are not precisely cheap), and besides, we don’t want external users to have access to our CRM. You could create a Community for this and be done with it, but in this case, and for the sake of illustration, I will instead show how you can develop a small web portal for service providers which we will synchronize with CRM using Azure App Services.&lt;/p&gt;&lt;p&gt;Our solution will have the following flow:&lt;/p&gt;&lt;ol&gt;&lt;li&gt; Call Center users will receive assistance requests by insured’s. These requests will be entered in the CRM (Salesforce)&lt;/li&gt;&lt;li&gt;At regular intervals, the Logic App will get from the CRM all pending requests using a Salesforce Connector. These requests will be sent to the database of the service provider web portal using a SQL Server connector&lt;/li&gt;&lt;li&gt;New requests will appear in the service provider portal&lt;/li&gt;&lt;li&gt;Service providers will take requests and deliver them. Once delivered, they will change the request’s status to completed&lt;/li&gt;&lt;li&gt;At regular intervals the Logic App will get all completed requests and synchronize them back to the CRM using a Salesforce Connector&lt;/li&gt;&lt;li&gt;Finally, CRM users will be able to see all the external service provider deliveries completed&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/a63c3663-e8a9-49a3-81cf-39ec2dbbe6cb.png"&gt;&lt;img width="745" height="510" title="scenario" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="scenario" src="http://blog.giovannimodica.com/posts/files/d0d14d70-ad84-43e7-9b42-143c2f97eaf6.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In the diagram, we can see that we will require a bidirectional synchronization between Salesforce and the web app we will create.&lt;/p&gt;&lt;p&gt;It is worth noting that the goal of this article is to describe how to use Azure App Service to do integrations with Salesforce. The solution we will develop in this article does not pretend to be a complete solution, but a simple solution that will allow us to see the most important aspects to consider when doing these kind of integrations. A complete solution would probable have a better state workflow associated to requests, notifications (email, SMS and/or push) of new assignments to third party providers, notifications to insured’s of the status of their requests, etc. To maintain things simple, and the article not as long, we will focus on the most important aspects and leave some of the details of a real solution as homework.&lt;/p&gt;&lt;h1&gt;Requirements&lt;/h1&gt;&lt;p&gt;In order to follow along and create the solution we will need:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;An Azure subscription. If you don’t have one you can get one free trial from the &lt;a href="http://azure.microsoft.com/en-us/pricing/free-trial/"&gt;Azure web site&lt;/a&gt;&lt;/li&gt;&lt;li&gt;A Salesforce development environment. You can get a free Salesforce Developer instance from the &lt;a href="https://developer.salesforce.com/gettingstarted"&gt;Salesforce Developer’s web site&lt;/a&gt;. When you register you will get an email with information about how to connect to the instance.&lt;/li&gt;&lt;li&gt;Visual Studio 2013 Community Edition (Update 4 at the time if this writing). You can download it free from the &lt;a href="https://www.visualstudio.com/"&gt;Visual Studio web site&lt;/a&gt;. You will also need the &lt;a href="http://azure.microsoft.com/en-us/downloads/"&gt;Azure SDK&lt;/a&gt; (version 2.5.1 at the this of this writing).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h1&gt;Development of the Salesforce Application&lt;/h1&gt;&lt;p&gt;The first thing we’ll do is creating the necessary objects in our Salesforce developer instance. If you requested a new development instance and is the first time you get into Salesforce you will directly enter the Salesforce setup area. From here we can customize the system and create new objects. In our case we want an object called &lt;font face="Courier New"&gt;Assistance&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/91ff65c1-e49f-42a5-a569-341f49da3c6c.png"&gt;&lt;img width="116" height="89" title="salesforce create object" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="salesforce create object" src="http://blog.giovannimodica.com/posts/files/19f6105d-6574-44ae-9c39-c2946aa16a53.png" border="0"&gt;&lt;/a&gt;From the menu on the left, we will go the the “&lt;font face="Segoe UI Black"&gt;Build&lt;/font&gt;” section, then “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;”, and then “&lt;font face="Segoe UI Black"&gt;Objects&lt;/font&gt;”. You can also use the search box on the top and enter a keyword to filter the options available on the menu. On the “&lt;font face="Segoe UI Black"&gt;Custom Objects&lt;/font&gt;” screen click the “&lt;font face="Segoe UI Black"&gt;New Custom Object&lt;/font&gt;” button. On the screen to create the object fill the required data as shown in the following screen. For the rest of the information leave the default value.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/d2b6848a-8440-484e-97c9-c47bc258a067.png"&gt;&lt;img width="624" height="484" title="salesforce new custom object" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce new custom object" src="http://blog.giovannimodica.com/posts/files/cb1068cc-dd0e-48fc-899d-854e7fefa6b4.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Notice the “&lt;font face="Segoe UI Black"&gt;Object Name&lt;/font&gt;” is &lt;font face="Courier New"&gt;Assistance&lt;/font&gt;. Every object in Salesforce has an API Name, which is the name that we will use to identify the object in development. As a rule, Salesforce adds the &lt;font face="Courier New"&gt;__c&lt;/font&gt; suffix to the name of all custom objects. So, the real name of our newly created object is &lt;font face="Courier New"&gt;Assistance__c&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;Click on the “&lt;font face="Segoe UI Black"&gt;Save&lt;/font&gt;” button to create the object. In Salesforce objects are immediately available. We will proceed to create some fields to get the data required for an assistance. On the same screen of the object, on the “&lt;font face="Segoe UI Black"&gt;Custom Fields &amp;amp; Relationships&lt;/font&gt;” section, click the “&lt;font face="Segoe UI Black"&gt;New&lt;/font&gt;” button and launch the new field wizard. We will first create the relationship between assistances and contacts: a contact could have many assistances and an assistance belongs to a unique contact. Salesforce comes out-of-the-box with an object called &lt;font face="Courier New"&gt;Contact&lt;/font&gt; (here the name doesn’t have the &lt;font face="Courier New"&gt;__c&lt;/font&gt; suffix as this is a standard object and not a custom object, all out-of-the-box objects are standard objects). To create the relationship between assistance and contact we need to create a field of type “&lt;font face="Segoe UI Black"&gt;Lookup Relationship&lt;/font&gt;”, we will choose this option on the wizard screen and click “&lt;font face="Segoe UI Black"&gt;Next&lt;/font&gt;”. On the next step, in the “&lt;font face="Segoe UI Black"&gt;Related To&lt;/font&gt;” field choose the &lt;font face="Courier New"&gt;Contact&lt;/font&gt; object. On the next step specify &lt;font face="Courier New"&gt;Contact&lt;/font&gt; as the name of the field, and leave the default values for the rest.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/0ff19e1b-8814-4e4d-aa84-2cc1ef55cf8b.png"&gt;&lt;img width="825" height="341" title="salesforce new field" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce new field" src="http://blog.giovannimodica.com/posts/files/8f8caaeb-acff-44d7-9bc8-edd54911cef0.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Click on “&lt;font face="Segoe UI Black"&gt;Next&lt;/font&gt;” and leave the default options for the rest of the steps and finalize the wizard clicking on “&lt;font face="Segoe UI Black"&gt;Save &amp;amp; New&lt;/font&gt;” to restart the wizard to create a new field. We will repeat the wizard to create all the fields described below:&lt;/p&gt;&lt;table width="802" border="1" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;&lt;strong&gt;Data Type&lt;/strong&gt;&lt;/td&gt;&lt;strong&gt;
&lt;/strong&gt;&lt;td width="200" valign="top"&gt;&lt;strong&gt;Label&lt;/strong&gt;&lt;/td&gt;&lt;strong&gt;
&lt;/strong&gt;&lt;td width="200" valign="top"&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;&lt;strong&gt;
&lt;/strong&gt;&lt;td width="200" valign="top"&gt;&lt;strong&gt;Observations&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Date&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Date&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Date&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;In the field “&lt;font face="Segoe UI Black"&gt;Default Value&lt;/font&gt;” enter the function TODAY()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Text Area (Long)&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Description&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Description&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Text&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Provider&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Provider&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;Enter 50 in the field “&lt;font face="Segoe UI Black"&gt;Length&lt;/font&gt;”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Picklist&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Status&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Status&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;p&gt;In the field “&lt;font face="Segoe UI Black"&gt;Enter values for the picklist&lt;/font&gt;…” enter the following values:&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;New&lt;br&gt;Completed&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Mark the field “&lt;font face="Segoe UI Black"&gt;Use first value as default value&lt;/font&gt;”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;Checkbox&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Synced&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;font face="Courier New"&gt;Synced&lt;/font&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;After you finish creating the fields, these should look as follows:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/04dc8756-3fbd-456d-bf4e-f4bb212ba61b.png"&gt;&lt;img width="644" height="290" title="salesforce assistance fields" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce assistance fields" src="http://blog.giovannimodica.com/posts/files/f219ec9d-964d-4a4f-854d-2a05f9db5ea1.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Note that, as with the name of the custom object, the names of custom fields have also the &lt;font face="Courier New"&gt;__c&lt;/font&gt; suffix. Every object in Salesforce, custom or standard, has two fields called &lt;font face="Courier New"&gt;Id&lt;/font&gt; and &lt;font face="Courier New"&gt;Name&lt;/font&gt;. The first one is the primary key of the object, and the second is a text that works as the descriptor for the record. Both fields do not have the &lt;font face="Courier New"&gt;__c&lt;/font&gt; suffix, as they’re considered standard fields (even in custom objects).&lt;/p&gt;&lt;h2&gt;Test the Application by Creating a Few Records&lt;/h2&gt;&lt;p&gt;We already have our object for assistances. To test it we will create a new assistance. From the top menu choose the tab for “&lt;font face="Segoe UI Black"&gt;Contacts&lt;/font&gt;” to see a list of recent contacts (if it is the first time we use this tab, we will not have any recent contact and the list is empty). To see the list of all contacts, from the “&lt;font face="Segoe UI Black"&gt;View&lt;/font&gt;” dropdown select the “&lt;font face="Segoe UI Black"&gt;All Contacts&lt;/font&gt;” list and click the “&lt;font face="Segoe UI Black"&gt;Go&lt;/font&gt;” button. Select any of the contacts in the list to see his/her details. At the end of the form we should see the section for “&lt;font face="Segoe UI Black"&gt;Assistances&lt;/font&gt;”. Click on the “&lt;font face="Segoe UI Black"&gt;New Assistance&lt;/font&gt;” button to create a new assistance record. Notice how some of the fields are automatically filled based on default values: the &lt;font face="Courier New"&gt;Contact&lt;/font&gt; field gets filled since we created the record from a contact record, the &lt;font face="Courier New"&gt;Date&lt;/font&gt; field has today’s date as a default, and the &lt;font face="Courier New"&gt;Status&lt;/font&gt; is set to &lt;font face="Courier New"&gt;New&lt;/font&gt; as is the first value introduced in the picklist. Enter a name and description and save the assistance.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/a87607e0-9776-44bb-85fb-48a7e2d3074e.png"&gt;&lt;img width="644" height="301" title="selesforce new assistance" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="selesforce new assistance" src="http://blog.giovannimodica.com/posts/files/acff4214-0b50-4a3f-af71-2d76fa2745ad.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Create one or two more assistances so we have enough data for the rest of the tests that will follow.&lt;/p&gt;&lt;p&gt;If we go back to the contact record we should see the requests we just created. However, in the list we only see the name of the request. To see additional fields we need to modify the form. At the top of the page there is a link called “&lt;font face="Segoe UI Black"&gt;Edit Layout&lt;/font&gt;” which opens the form editor.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/02a2a064-08b5-45cc-9a53-3418f49e1026.png"&gt;&lt;img width="244" height="89" title="salesforce edit layout" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="salesforce edit layout" src="http://blog.giovannimodica.com/posts/files/7b4d032a-a04e-45b7-901d-c1b4d4042a4e.png" border="0"&gt;&lt;/a&gt;On the edit layout screen look at the end for the list of assistances and with the mouse hover on the title of the list until a wrench icon appears. When clicking this icon you will see a screen where you can select the fields you want to display on the list. Select fields &lt;font face="Courier New"&gt;Date&lt;/font&gt;, &lt;font face="Courier New"&gt;Status&lt;/font&gt; and &lt;font face="Courier New"&gt;Provider&lt;/font&gt; and then click the “&lt;font face="Segoe UI Black"&gt;OK&lt;/font&gt;” button. To save the layout click the “&lt;font face="Segoe UI Black"&gt;Save&lt;/font&gt;” button at the top of the layout editor, returning back to the contact record. You will now be a able to see more details in the list of assistances:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/c326b0e1-b852-4507-9375-5e0dc2ae4a2e.png"&gt;&lt;img width="721" height="117" title="salesforce assistances" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce assistances" src="http://blog.giovannimodica.com/posts/files/64a28aa9-f10c-4d71-a4d3-7f6bb5ac7c3f.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h1&gt;Development of the External Service Provider’s Portal&lt;/h1&gt;&lt;p&gt;We will now proceed with the creation of the provider’s portal. For this we will create an MVC application using Visual Studio, and later publish it in Azure as a Web App with a SQL Server database.&lt;/p&gt;&lt;p&gt;Open Visual Studio and create a new project of type “&lt;font face="Segoe UI Black"&gt;ASP.Net Web Application&lt;/font&gt;”. I have called mine &lt;font face="Courier New"&gt;ProvidersPortal&lt;/font&gt;. Use the MVC project template and choose “&lt;font face="Segoe UI Black"&gt;Individual User Accounts&lt;/font&gt;” as the authentication method. Once the project is created we will enable Entity Framework Migrations. From the Package Manager console enter the following commands:&lt;/p&gt;&lt;pre&gt;enable-migrations
add-migration Initial
update-database
&lt;/pre&gt;&lt;p&gt;Next, we will create a new entity to represent assistances. In the &lt;font face="Courier New"&gt;Models&lt;/font&gt; directory, add a new class and call the file &lt;font face="Courier New"&gt;Assistance.cs&lt;/font&gt; and overwrite the content of the file with the following code:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
 
namespace ProvidersPortal.Models
{
    public class Assistance
    {
        [MaxLength(20)]
        [Key]
        public string Id { get; set; }
 
        [MaxLength(80)]
        public string Name { get; set; }
 
        public string Description { get; set; }
 
        [MaxLength(50)]
        public string Provider { get; set; }
 
        [MaxLength(20)]
        public string Status { get; set; }
 
        public DateTime? Date { get; set; }
 
        public bool? Synced { get; set;}
    }
}
&lt;/pre&gt;&lt;p&gt;To expose this object to Entity Framework we need to add a property in the class for the context. To keep things simple we will use the same database used by ASP.Net Identity. Open the file &lt;font face="Courier New"&gt;Models\IdentityModels.cs&lt;/font&gt; and add the highlighted line to the class &lt;font face="Courier New"&gt;ApplicationDbContext&lt;/font&gt;:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [13];"&gt;public class ApplicationDbContext : IdentityDbContext&amp;lt;ApplicationUser&amp;gt;
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }
 
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
 
    public DbSet&amp;lt;Assistance&amp;gt; Assistances { get; set; }
}
&lt;/pre&gt;&lt;p&gt;Next, add a new migration for the new object. In the Package Manager console enter the following commands:&lt;/p&gt;&lt;pre&gt;add-migration Assistance
update-database
&lt;/pre&gt;&lt;p&gt;Now, we need a controller and a view for the assistance object. On the &lt;font face="Courier New"&gt;Controllers&lt;/font&gt; folder, add a new controller of type “&lt;font face="Segoe UI Black"&gt;MVC 5 Controller with views, using Entity Framework&lt;/font&gt;”. Fill the data as shown in the following figure:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/aa2c6b65-2f88-4809-8126-aaf31d8488eb.png"&gt;&lt;img width="540" height="322" title="vs add controller" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="vs add controller" src="http://blog.giovannimodica.com/posts/files/0741d70b-be37-4c81-a48d-f8d04d6167dd.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Visual Studio will create (scaffold) files for the controller and the views for the typical CRUD operations. By default the controller is created allowing anonymous access to it, and in our case we want only authenticated users (external service providers) to have access to the assistance requests. Open the controller, the file &lt;font face="Courier New"&gt;Controllers\AssistanceController.cs&lt;/font&gt; and add the &lt;font face="Courier New"&gt;Authorize&lt;/font&gt; attribute to it:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [1];"&gt;[Authorize]
public class AssistancesController : Controller
&lt;/pre&gt;&lt;p&gt;Now all we have left is to add a menu option to access the assistances. Open the file &lt;font face="Courier New"&gt;Views\Shared\_Layout.cshtml&lt;/font&gt; and add a new option to the menu, as shown in the following highlighted code:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [3];"&gt;&amp;lt;ul class="nav navbar-nav"&amp;gt;
    &amp;lt;li&amp;gt;@Html.ActionLink("Home", "Index", "Home")&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;@Html.ActionLink("Assistances", "Index", "Assistances")&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;@Html.ActionLink("About", "About", "Home")&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;@Html.ActionLink("Contact", "Contact", "Home")&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/pre&gt;&lt;p&gt;Compile and execute the application. After registering you should be able to see the assistances screen (which will be empty at the moment):&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/083d10d0-2a20-44e3-8a2d-e84c048949f7.png"&gt;&lt;img width="644" height="183" title="providers portal" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="providers portal" src="http://blog.giovannimodica.com/posts/files/74042e29-73fa-44c2-9d15-731735b9b634.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h2&gt;Publishing of the Portal as a Web App&lt;/h2&gt;&lt;p&gt;Now we’ll proceed to publishing the portal as a Web App in Azure. We will let Visual Studio do all the work for us. In the “&lt;font face="Segoe UI Black"&gt;Solution Explorer&lt;/font&gt;”, on the project node, right click and choose “&lt;font face="Segoe UI Black"&gt;Publish…&lt;/font&gt;”. Select “&lt;font face="Segoe UI Black"&gt;Microsoft Azure Web Apps&lt;/font&gt;” as the target. Visual Studio will ask you for credentials to connect to your Azure subscription. Click on the “&lt;font face="Segoe UI Black"&gt;New…&lt;/font&gt;” button to create a new application. I have called mine &lt;font face="Courier New"&gt;ProvidersPortal&lt;/font&gt;, and to keep things well organized I’ve decided to create a App Service plan as well as a new resource group for this application. We also need a database, so select the option to create a new database server. Click the “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;” button to let Visual Studio create the app in Azure.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/87238a54-a417-4ce0-b86d-b76e8eef2b84.png"&gt;&lt;img width="462" height="484" title="azure web app creation" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="azure web app creation" src="http://blog.giovannimodica.com/posts/files/70a79c03-73b6-42fe-9d48-22cc2cda7a5e.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Write down the name of the App Service plan and the resource group, you will need these when you create the rest of the applications (Logic Apps and API Apps) as they need to have the same plan and group so they can see each other. In my case, both the plan and the group is called &lt;font face="Courier New"&gt;ProvidersPortal&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;Once the web application is created in Azure, the wizard will continue with the publishing. In the “&lt;font face="Segoe UI Black"&gt;Settings&lt;/font&gt;” section make sure you select “&lt;font face="Segoe UI Black"&gt;Execute Code First Migrations (runs on application start)&lt;/font&gt;” in order to provision the Azure database with the schema required by our application.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/67af2d52-3ef8-47c4-b4d2-4cc100e65c90.png"&gt;&lt;img width="453" height="355" title="vs publish wizard" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="vs publish wizard" src="http://blog.giovannimodica.com/posts/files/24277ca1-13d2-4a85-8d1e-5b053bb1c143.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Finally, click the “&lt;font face="Segoe UI Black"&gt;Publish&lt;/font&gt;” button and when the wizard finishes will open the provider’s portal executing on the cloud! Register a user and browse the Assistances menu item so Entity Framework will create the database schemas for the app.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h1&gt;Integration using a Logic App&lt;/h1&gt;&lt;p&gt;We already have our two applications executing independently. Now comes the fun part: the integration of both applications using a Logic App in Azure. We will use the Azure portal to do all the steps that follow.&lt;/p&gt;&lt;p&gt;First, we will create the API Apps that will allow us to connect to Salesforce and SQL Server.&lt;/p&gt;&lt;h2&gt;Creation of API Apps&lt;/h2&gt;&lt;p&gt;We need two API Apps, one for Salesforce and the other for SQL Server. Both apps will be created from the Azure Marketplace.&lt;/p&gt;&lt;h3&gt;Salesforce API App&lt;/h3&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/397398cf-501d-4147-88f4-cc068d77fabb.png"&gt;&lt;img width="83" height="120" title="salesforce connector" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="salesforce connector" src="http://blog.giovannimodica.com/posts/files/9f8f2895-5c6a-4b1e-9f18-74843506bfde.png" border="0"&gt;&lt;/a&gt;On the Azure portal, click on “&lt;font face="Segoe UI Black"&gt;New&lt;/font&gt;”, select “&lt;font face="Segoe UI Black"&gt;Web + Mobile&lt;/font&gt;” and then “&lt;font face="Segoe UI Black"&gt;Azure Marketplace&lt;/font&gt;”. Select the “&lt;font face="Segoe UI Black"&gt;API Apps&lt;/font&gt;” category. On the search field enter “salesforce” and press enter. From the search results click on “&lt;font face="Segoe UI Black"&gt;Salesforce Connector&lt;/font&gt;”. A &lt;em&gt;blade &lt;/em&gt;will open with the details of the connector and with links to its documentation. Click on the “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;” button. A new &lt;em&gt;blade&lt;/em&gt; will open with the properties of the connector. From here select the “&lt;font face="Segoe UI Black"&gt;Package Settings&lt;/font&gt;” section. In this section you can specify the Salesfoce objects you would like to access. Remove the objects that appear by default and enter the name of the object we created in Salesforce: &lt;font face="Courier New"&gt;Assistance__c&lt;/font&gt; (remember the &lt;font face="Courier New"&gt;__c&lt;/font&gt; suffix, which is part of the name):&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/a57b7ebb-e743-40ce-88ab-2562df898286.png"&gt;&lt;img width="488" height="106" title="salesforce connector entities" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce connector entities" src="http://blog.giovannimodica.com/posts/files/3d16979c-cfa9-423d-ba81-e9167e1139d4.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/a57b7ebb-e743-40ce-88ab-2562df898286.png"&gt;&lt;br&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/b630bd7f-c3be-4dfc-b3cc-8b9100e8479e.png"&gt;&lt;img width="161" height="244" title="salesforce connector properties" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="salesforce connector properties" src="http://blog.giovannimodica.com/posts/files/caf5630c-c5ee-4d07-b469-23736621c5e9.png" border="0"&gt;&lt;/a&gt;In the section “&lt;font face="Segoe UI Black"&gt;App Service Plan&lt;/font&gt;” select the plan created before when publishing the web application. The service plan must be the same so all the parts can work together. In my case the service plan is called &lt;font face="Courier New"&gt;ProvidersPortal&lt;/font&gt;. Click on “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;” and let Azure provision the API App. After a minute approximately you will see a notification telling the app is ready.&lt;/p&gt;&lt;p&gt;By the way, if you want to modify the connector configuration parameters later, you need to do it from the Host of the API App (you have a link to the host on the connector details &lt;em&gt;blade&lt;/em&gt;)&lt;/p&gt;&lt;p&gt;&lt;br clear="all"&gt;&lt;/p&gt;&lt;h3&gt;SQL Server API App&lt;/h3&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/e63ffeed-bbf7-4ff5-88c8-cfc2cd1126a9.png"&gt;&lt;img width="85" height="120" title="sqlserver connector" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="sqlserver connector" src="http://blog.giovannimodica.com/posts/files/3e8939b3-e257-4818-806c-3fc04287167c.png" border="0"&gt;&lt;/a&gt;As we did before, from the Azure Marketplace search for “sql” and in the search results click on “&lt;font face="Segoe UI Black"&gt;Microsoft SQL Connector&lt;/font&gt;”. A &lt;em&gt;blade&lt;/em&gt; will open with the connector details and a link to its documentation. Click the “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;” button to open a new &lt;em&gt;blade&lt;/em&gt; with the configuration of the connector. From here select “&lt;font face="Segoe UI Black"&gt;Package Settings&lt;/font&gt;” section. In this section you can specify the connection details to the database. If you have doubts about what are the right values to put here you can look at the connection string that was created in the publishing profile of the web project when we published it to Azure (in Visual Studio, in Solution Explorer, go to &lt;font face="Courier New"&gt;Properties\PublishProfiles\&amp;lt;projectname&amp;gt;.pubxml&lt;/font&gt;). For the “&lt;font face="Segoe UI Black"&gt;Tables&lt;/font&gt;” specify &lt;font face="Courier New"&gt;Assistances&lt;/font&gt;. Make sure to select the same service plan we’ve been using. This is how the properties look in my case:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/98bfcb76-d83a-4707-8c00-c0f0280b3c5d.png"&gt;&lt;img width="256" height="484" title="sql connector properties" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="sql connector properties" src="http://blog.giovannimodica.com/posts/files/2a767cea-bc8e-419e-adf1-68c98c0321b3.png" border="0"&gt;&lt;/a&gt;Click “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;” and let Azure provision the API App. After a minute approximately you will see a notification telling the app is ready. As with the previous API app, if you need to modify the configuration of the connector (because they changed or because you made a mistake) you will have to do it from the Host of the API App.&lt;/p&gt;&lt;p&gt;&lt;br clear="all"&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h1&gt;Creation of the Logic App&lt;/h1&gt;&lt;p&gt;Let’s stop here for a moment and analyze what we want to accomplish. We want a bidirectional synchronization between Salesforce and the SQL Server database.&lt;/p&gt;&lt;p&gt;For the synchronization from Salesforce to SQL Server we want to do the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;First we find all those assistances that are in Salesforce which have not been synced and with a status of “New”&lt;/li&gt;&lt;li&gt;For each one of these assistances we get its details&lt;/li&gt;&lt;li&gt;For each one of these assistances we will add a new record in the provider portal’s database&lt;/li&gt;&lt;li&gt;If the insertion is successful we mark the assistance as synced in Salesforce&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;For the synchronization from SQL Server to Salesforce we want to do the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We will look for all the assistance records that have been completed and have not been synced yet&lt;/li&gt;&lt;li&gt;For each one of these records we will update Salesforce&lt;/li&gt;&lt;li&gt;If the update is successful we will mark the record as synced in the portal&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Since (for the moment) the logic inside Logic Apps is lineal (the current step always depends on the previous) we will need to create two Logic Apps, one for each direction of the synchronization.&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;Note: in this case we will use a boolean field to know what records need to be synced from one system to the other. In a real application this is probably not the best since each record will be synced only once between systems. A better approach would be to base the synchronization on a timestamp field that has the last modification date made to a record.&lt;/font&gt;&lt;/p&gt;&lt;h2&gt;Synchronization from Salesforce to SQL Server&lt;/h2&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/60556146-15f3-4901-bcec-388b75540bc0.png"&gt;&lt;img width="66" height="66" title="logic app" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="logic app" src="http://blog.giovannimodica.com/posts/files/164f59d4-79d5-43a8-ad70-c6c98d60f64c.png" border="0"&gt;&lt;/a&gt;We will now proceed to create the synchronization between both applications. For this we will create a Logic App and use the connectors created before. On the Azure portal, click on “&lt;font face="Segoe UI Black"&gt;New&lt;/font&gt;”, then on “&lt;font face="Segoe UI Black"&gt;Web + Mobile&lt;/font&gt;” and select “&lt;font face="Segoe UI Black"&gt;Logic App&lt;/font&gt;”. A new &lt;em&gt;blade&lt;/em&gt; will open where you can enter the name of the app and select the service plan. Again, make sure to select the same service plan specified in the connectors. I called my logic app &lt;font face="Courier New"&gt;ProvidersPortalLogic&lt;/font&gt;&lt;font face="Segoe UI"&gt; and selected the &lt;font face="Courier New"&gt;ProvidersPortal&lt;/font&gt; plan. Click on “&lt;font face="Segoe UI Black"&gt;Create&lt;/font&gt;” to provision the application. After a minute approximately you will see a notification telling the app is ready.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Open the application and select the section “&lt;font face="Segoe UI Black"&gt;triggers and actions&lt;/font&gt;” to show the canvas to edit the actions for the app. For now, and to be able to develop and test our app, click on the option “&lt;font face="Segoe UI Black"&gt;Run this logic manually&lt;/font&gt;” which will allow us to run the application on demand as we develop it. On the right section of the edition canvas you should see, among others, the two API applications we created in previous steps: the Salesforce and the SQL Server connectors. If you don’t see the connectors you probably didn’t select the appropriate service plans to be all the same.&lt;/p&gt;&lt;p&gt;Let’s start by adding the first step. On the “&lt;font face="Segoe UI Black"&gt;API Apps&lt;/font&gt;” panel click on the Salesforce connector. This will add a step to the logic. You need to authorize, i.e. provide the connection credentials, the connector so it can connect to the Salesforce instance. Click on the “&lt;font face="Segoe UI Black"&gt;Authorize&lt;/font&gt;” button, a screen requesting Salesforce credentials will appear. Enter your credentials and when asked if you want to give access to the Azure Logic App say yes. If everything went ok the connector will get the metadata from Salesforce and will present you with some options:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/1409fe46-e002-4cf9-84a7-8148fcb153c2.png"&gt;&lt;img width="560" height="484" title="logic app salesforce connector" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="logic app salesforce connector" src="http://blog.giovannimodica.com/posts/files/ca9a3043-93a4-4c5d-a1ce-9ff50e1d51e8.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It is possible that you get an error saying the the metadata has not been generate (“&lt;font face="Courier New"&gt;Error fetching swagger api definition&lt;/font&gt;”). You could try remove the step (by clicking on the wrench icon in the upper right menu of the step and selecting “&lt;font face="Segoe UI Black"&gt;Delete this action&lt;/font&gt;”) and try again. If you still get the same error then you can do the following trick: change the editor to the the code view by clicking on the “&lt;font face="Segoe UI Black"&gt;Code View&lt;/font&gt;” icon &lt;a href="http://blog.giovannimodica.com/posts/files/4121f004-2e52-4263-a927-b66a36f5c5bc.png"&gt;&lt;img width="23" height="19" title="code view" style="display: inline; background-image: none;" alt="code view" src="http://blog.giovannimodica.com/posts/files/1c0d132a-1464-484e-8ac3-8350676313f6.png" border="0"&gt;&lt;/a&gt; and remove the Salesforce subscription (the one highlighted on the following image) and then try to add the step again.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/dae7ea67-853f-4639-96ef-afef3b9a67c7.png"&gt;&lt;img width="644" height="128" title="salesforce subscription in code view" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce subscription in code view" src="http://blog.giovannimodica.com/posts/files/38964567-485b-4694-98ff-4add0845bd57.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;If the above trick doesn’t fix the problem the you probably have an error in the configuration of the API App (the connector).&lt;/p&gt;&lt;p&gt;From the step actions click on three dots “&lt;font face="Segoe UI Black"&gt;…&lt;/font&gt;” to get more actions. Select the “&lt;font face="Segoe UI Black"&gt;Execute Query&lt;/font&gt;” action. This action allows you to execute a SOQL query against Salesforce. Enter the following query:&lt;/p&gt;&lt;pre class="brush: sql;"&gt;select Id from Assistance__c where Synced__c = false and Status__c = 'New'
&lt;/pre&gt;&lt;p&gt;We want the id of the records that have not yet been synchronized and with a status of “New”. When we validate the step we should see something like this.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/7800aebb-6ae8-4477-9952-ce5c65ee9f25.png"&gt;&lt;img width="244" height="207" title="salesforce execute query step" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce execute query step" src="http://blog.giovannimodica.com/posts/files/09ee98dd-4aba-4d0d-b160-3eb4f264b05a.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When this step gets executed we will get all the assistance records that satisfy the criteria, and they will be stored in a property called &lt;font face="Courier New"&gt;result&lt;/font&gt;. Next we will add the second step: get the details of each assistance.&lt;/p&gt;&lt;p&gt;Add a new step by clicking on the Salesforce connector in the “&lt;font face="Segoe UI Black"&gt;API Apps&lt;/font&gt;” panel. Select “&lt;font face="Segoe UI Black"&gt;Get_Assistance__c&lt;/font&gt;” as the action. This action will get all the fields of a particular record. We want this step to be executed by each of the records obtained in the previous step. To achieve this, on the step menu, click on the wrench icon and select “&lt;font face="Segoe UI Black"&gt;Repeat over a list&lt;/font&gt;”. A new field “&lt;font face="Segoe UI Black"&gt;Repeat&lt;/font&gt;” will appear allowing you to specify the list to use to get the records. We will use an expression to get the list. Expressions are specified by adding the &lt;font face="Courier New"&gt;@&lt;/font&gt; character as a prefix. If we want to get the list of records from the previous step we will use the following expression: &lt;/p&gt;&lt;pre&gt;@body(‘salesforceconnector’).result.records
&lt;/pre&gt;&lt;p&gt;The expression means the following: get the &lt;font face="Courier New"&gt;body&lt;/font&gt; of the step called &lt;font face="Courier New"&gt;salesforceconnector&lt;/font&gt; and search for a property called &lt;font face="Courier New"&gt;result.records&lt;/font&gt;. The &lt;font face="Courier New"&gt;body&lt;/font&gt; is formatted as JSON and the &lt;font face="Courier New"&gt;result&lt;/font&gt; property is an object which contains an array property called &lt;font face="Courier New"&gt;records&lt;/font&gt;, containing all the records returned by the query.&lt;/p&gt;&lt;p&gt;By default, the name of each step is the name of the connector plus an index, so for example, the first step of the Salesforce connector is called &lt;font face="Courier New"&gt;salesforceconnector&lt;/font&gt;, the second step is called &lt;font face="Courier New"&gt;salesforceconnector0&lt;/font&gt;, the third is &lt;font face="Courier New"&gt;salesforceconnector1&lt;/font&gt;, and so on.&lt;/p&gt;&lt;p&gt;In the field “&lt;font face="Segoe UI Black"&gt;Record Id&lt;/font&gt;” we will enter the id of the current record in the loop. To get the current record inside the loop we will use the &lt;font face="Courier New"&gt;@repeatItem()&lt;/font&gt; expression. So, if we want the id of the record we will use:&lt;/p&gt;&lt;pre&gt;@repeatItem().Id
&lt;/pre&gt;&lt;p&gt;The step should look like this:&lt;a href="http://blog.giovannimodica.com/posts/files/5dffa35e-c15b-416b-9607-a029f73a0f68.png"&gt;&lt;img width="280" height="484" title="salesforce connector get action" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce connector get action" src="http://blog.giovannimodica.com/posts/files/94cdf46a-fe89-459d-8423-dcf23661add6.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;Note: we could not add this second step to the logic and instead get the required data by specifying it on the query of the first step, but I’ve done it this way to illustrate the concepts.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Now that we have the data for each record the third step is to insert the record in the database of the web application. For this we will use the SQL Server connector. On the “&lt;font face="Segoe UI Black"&gt;API Apps&lt;/font&gt;” panel click on “&lt;font face="Segoe UI Black"&gt;Microsoft SQL Connector&lt;/font&gt;”. This will add a new step to the logic. Select the action “&lt;font face="Segoe UI Black"&gt;Insert into Assistances (JSON)&lt;/font&gt;”. The connector will ask for parameters for each field in the table. As with the previous step, we want this insertion to be made for each record in the list so click on the wrench icon and select “&lt;font face="Segoe UI Black"&gt;Repeat over a list&lt;/font&gt;”. In this case we get the list using the following expression:&lt;/p&gt;&lt;pre&gt;@actions('salesforceconnector0').outputs.repeatItems
&lt;/pre&gt;&lt;p&gt;&lt;font face="Courier New"&gt;salesforceconnector0&lt;/font&gt; is the previous step, from which we want to take the &lt;font face="Courier New"&gt;outputs&lt;/font&gt; property representing the output of the step (this output is actually many records since the step was also executed for a list). From this output we want the &lt;font face="Courier New"&gt;repeatItems&lt;/font&gt; property, which is an array with the result of each record it got in the loop. To get a specific field we will use again the expression &lt;font face="Courier New"&gt;@repeatItem()&lt;/font&gt;:&lt;/p&gt;&lt;pre&gt;@repeatItem().outputs.body.Id
&lt;/pre&gt;&lt;p&gt;The above expression would get the field &lt;font face="Courier New"&gt;Id&lt;/font&gt; from the Salesforce record. If this looks complex to you the best thing is for you to execute the application every time you add a step and analyze the output of each step to see the JSON produced. This will give you an idea on how to get the values you need.&lt;/p&gt;&lt;p&gt;We will repeat the above expression for each field of the table. Remember once again that, because we’re dealing with custom fields, you need to add the &lt;font face="Courier New"&gt;__c&lt;/font&gt; suffix to the field name, except for the &lt;font face="Courier New"&gt;Id&lt;/font&gt; and &lt;font face="Courier New"&gt;Name&lt;/font&gt; fields which are standard fields (even though they belong to a custom object). Fill the fields using the following table:&lt;/p&gt;&lt;table width="800" border="1" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="400" valign="top"&gt;&lt;strong&gt;Field&lt;/strong&gt;&lt;/td&gt;&lt;strong&gt;
&lt;/strong&gt;&lt;td width="400" valign="top"&gt;&lt;strong&gt;Expression&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Id&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;@repeatItem().outputs.body.Id&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;/tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Name&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;@repeatItem().outputs.body.Name&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;/tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Description&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;@repeatItem().outputs.body.Description__c&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;/tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Provider&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;&lt;br&gt;&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;/tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Status&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;@repeatItem().outputs.body.Status__c&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;/tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Date&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;**&lt;/font&gt;&lt;/td&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;/tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;tr&gt;&lt;font face="Courier New"&gt;
&lt;/font&gt;&lt;td width="400" valign="top"&gt;&lt;font face="Courier New"&gt;Synced&lt;/font&gt;&lt;/td&gt;
&lt;td width="400" valign="top"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;** The date field should have the following expression: &lt;font face="Courier New"&gt;@repeatItem().outputs.body.Date__c&lt;/font&gt;, however this value was giving me errors when trying to insert the record in SQL Server, something related with the date format. After trying unsuccessfully with various formats I decided to leave it blank at the moment and later find a solution.&lt;/p&gt;&lt;p&gt;We will leave fields &lt;font face="Courier New"&gt;Provider&lt;/font&gt; and &lt;font face="Courier New"&gt;Synced&lt;/font&gt; blank as these will be filled in the provider’s portal. The step should look as follows:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/cffe4e7a-39ba-4cd1-8725-a8fe2c1523db.png"&gt;&lt;img width="280" height="484" title="sql connector step" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="sql connector step" src="http://blog.giovannimodica.com/posts/files/40fc5572-0088-4a46-9ae5-c89e51e90125.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The last step would be to update the record in Salesforce and mark it as synced so the record would not be considered in subsequent runs of the logic app. Add a new step to the logic by clicking on the Salesforce connector in the “&lt;font face="Segoe UI Black"&gt;API Apps&lt;/font&gt;” panel. For this step select the action “&lt;font face="Segoe UI Black"&gt;Update Assistance__c&lt;/font&gt;”. Make the step execute for a list (select “&lt;font face="Segoe UI Black"&gt;Repeat over a list&lt;/font&gt;” from the step menu). The parameters for fields “&lt;font face="Segoe UI Black"&gt;Repeat&lt;/font&gt;” and “&lt;font face="Segoe UI Black"&gt;Record Id&lt;/font&gt;” are the same as in the previous step. Set the &lt;font face="Courier New"&gt;Synced&lt;/font&gt; field to &lt;font face="Courier New"&gt;true&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/fd2c1475-764a-4495-9365-1841bb5e6a10.png"&gt;&lt;img width="275" height="484" title="salesforce connector update" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce connector update" src="http://blog.giovannimodica.com/posts/files/3f9f54f9-4dea-4e2b-a8e4-8fbbf1596df6.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We have our logic app ready! Make sure to save changes if you haven’t done it yet and close the editor (you could get a message asking if you want to discard your changes even if you have saved them, say yes, your changes are already saved). Execute the application by clicking on the run icon &lt;a href="http://blog.giovannimodica.com/posts/files/9a9ea72a-5fa4-4848-ae9c-d90de10a56a8.png"&gt;&lt;img width="23" height="18" title="run now" style="display: inline; background-image: none;" alt="run now" src="http://blog.giovannimodica.com/posts/files/3db7fe19-fa45-47ac-bdf7-d7c437049ff9.png" border="0"&gt;&lt;/a&gt;. If everything works ok you should be able to see the results of the execution:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/70c32876-a24e-4f54-8908-76717d5b106f.png"&gt;&lt;img width="644" height="189" title="execution results" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="execution results" src="http://blog.giovannimodica.com/posts/files/266c2c54-3ed0-4b1f-bc96-9eb926c05723.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You should also be able to see the assistances you created in Salesforce in the provider’s portal:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/2f676b0a-cc69-4ec2-b586-c5d4f8927033.png"&gt;&lt;img width="644" height="233" title="providers porta with records" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="providers porta with records" src="http://blog.giovannimodica.com/posts/files/ac806db8-2dad-45b6-8988-2d3c34ddb4be.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;And records in Salesforce should be marked as synced:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/77518113-f42e-4acc-a2a3-5ea43d5dfc9c.png"&gt;&lt;img width="644" height="305" title="salesforce synced" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce synced" src="http://blog.giovannimodica.com/posts/files/a98f40ed-c689-4d51-aaf2-8dbaa8c483e7.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;With this we have finished the first part of our solution.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h2&gt;Synchronizing from SQL Server to Salesforce&lt;/h2&gt;&lt;p&gt;For the second part of the solution we will create a new Logic App. The steps are the same as the ones we did for the previous app. I’ll just mention that I will call this app &lt;font face="Courier New"&gt;SalesforceLogic&lt;/font&gt;. Remember to assign the same service plan. To execute this app on demand make sure you select the “&lt;font face="Segoe UI Black"&gt;Run this logic manually&lt;/font&gt;”.&lt;/p&gt;&lt;p&gt;Let’s start with the first step. Add a SQL Server connector to the app and select the action “&lt;font face="Segoe UI Black"&gt;Select from Assistances (JSON)&lt;/font&gt;”. Leave “&lt;font face="Segoe UI Black"&gt;Fields&lt;/font&gt;“ blank to get all the fields of the table. In the “&lt;font face="Courier New"&gt;&lt;font face="Segoe UI Black"&gt;Where&lt;/font&gt;&lt;/font&gt;&lt;font face="Segoe UI"&gt;” add the following condition:&lt;/font&gt;&lt;/p&gt;&lt;pre class="brush: sql;"&gt;Status = 'Completed' and Synced is null
&lt;/pre&gt;&lt;p&gt;The step should look like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/aef97387-f558-4c00-8773-2a77cdeba91a.png"&gt;&lt;img width="275" height="484" title="sql server select step" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="sql server select step" src="http://blog.giovannimodica.com/posts/files/e4dab022-8cb3-4037-b598-7509a3d5545c.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Now add a second step by clicking on the Salesforce connector. Since this is a new logic app you need to authorize it against the Salesforce instance again. Select the action “&lt;font face="Segoe UI Black"&gt;Update Assistance__c&lt;/font&gt;”. We want to execute the update in Salesforce for each one of the records retrieved in the previous step, so we need to execute this step for a list: select the “&lt;font face="Segoe UI Black"&gt;Repeat over a list&lt;/font&gt;” from the step menu. For the list we will use the &lt;font face="Courier New"&gt;body&lt;/font&gt; of the previous step with the expression &lt;font face="Courier New"&gt;@body(‘microsoftsqlconnector’)&lt;/font&gt;, and for the “&lt;font face="Segoe UI Black"&gt;Record Id&lt;/font&gt;” use the expression &lt;font face="Courier New"&gt;@repeatItem().Id&lt;/font&gt;. We need to update the fields &lt;font face="Courier New"&gt;Provider__c&lt;/font&gt; and &lt;font face="Courier New"&gt;Status__c&lt;/font&gt; in Salesforce by using the expressions &lt;font face="Courier New"&gt;@repeatItem().Provider&lt;/font&gt; and &lt;font face="Courier New"&gt;@repeatItem().Status&lt;/font&gt;, respectively. The step should look as follows:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/924de535-a1af-44cb-a1b6-82489f553e4e.png"&gt;&lt;img width="278" height="484" title="salesforce connector update 2" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="salesforce connector update 2" src="http://blog.giovannimodica.com/posts/files/1421f293-35cc-4058-904c-e68e32555a9b.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Finally, we will add a third step using the SQL Server connector to update the &lt;font face="Courier New"&gt;Synced&lt;/font&gt; field in the portal’s database so it will not be considered when the logic app is executed again. For this we will make this step run for the same list of the first step: &lt;font face="Courier New"&gt;@body(‘microsoftsqlconnector’)&lt;/font&gt;&lt;font face="Segoe UI"&gt; and set the &lt;font face="Courier New"&gt;Synced&lt;/font&gt; field to &lt;font face="Courier New"&gt;true&lt;/font&gt;. This step requires a “&lt;font face="Segoe UI Black"&gt;Where&lt;/font&gt;” condition which needs to be dynamic using the following expression:&lt;/font&gt;&lt;/p&gt;&lt;pre class="brush: sql;"&gt;@concat('Id = %27',repeatItem().Id,'%27')
&lt;/pre&gt;&lt;p&gt;Here the trick is to use the URL codification of the &lt;font face="Courier New"&gt;'&lt;/font&gt; character (simple quote) using the code &lt;font face="Courier New"&gt;'%27'&lt;/font&gt;. The reason to do it like this is because we cannot use a simple quote inside a text (even though I have tried different escape sequences). This will produce a condition such as this: &lt;font face="Courier New"&gt;Id = 'xxxxxxx'&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/6871ca8e-62f1-4a58-9721-637f9ff83a8b.png"&gt;&lt;img width="280" height="484" title="sql connector sync" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="sql connector sync" src="http://blog.giovannimodica.com/posts/files/33c7dcf0-2530-49b5-ba4e-addf2775c492.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We have our logic ready! Make sure to save changes and close the editor. &lt;/p&gt;&lt;p&gt;On the provider’s portal select some of the assistances and fill the &lt;font face="Courier New"&gt;Provider&lt;/font&gt; field and change the &lt;font face="Courier New"&gt;Status&lt;/font&gt; to &lt;font face="Courier New"&gt;Completed&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/831b102d-d222-42c8-b807-91f6c2e5bcaa.png"&gt;&lt;img width="376" height="373" title="complete an assistance" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="complete an assistance" src="http://blog.giovannimodica.com/posts/files/a9ef65d8-6d62-484a-a65a-538084f39e29.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Execute the application by clicking on the run icon &lt;a href="http://blog.giovannimodica.com/posts/files/d3ac7cc6-5182-423e-aa21-46c6813ef5dd.png"&gt;&lt;img width="23" height="18" title="run now" style="display: inline; background-image: none;" alt="run now" src="http://blog.giovannimodica.com/posts/files/c676b41d-03cd-40b4-a4a6-b2db79f900f6.png" border="0"&gt;&lt;/a&gt;. If everything works ok you should be able to see the records in Salesforce updated:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/b38c7692-933f-492e-8e5e-7d901f97f253.png"&gt;&lt;img width="786" height="123" title="completed assistances in salesforce" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="completed assistances in salesforce" src="http://blog.giovannimodica.com/posts/files/1a2ff577-7a8c-4923-8c5e-531b8de2437f.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Also you should see records marked as synced in the portal’s database:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/ab33af0a-596e-40a7-84c4-62fdb14f0f7c.png"&gt;&lt;img width="775" height="98" title="synced assistances in sql server" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="synced assistances in sql server" src="http://blog.giovannimodica.com/posts/files/408e8ce9-7f31-4a65-a46f-f7af67343ab1.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/ab33af0a-596e-40a7-84c4-62fdb14f0f7c.png"&gt;&lt;br&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Automatic Execution&lt;/h2&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/664ff898-4f5c-47d6-b371-44df49bca951.png"&gt;&lt;img width="141" height="54" title="recurrence" align="left" style="margin: 0px 10px 0px 0px; float: left; display: inline; background-image: none;" alt="recurrence" src="http://blog.giovannimodica.com/posts/files/7008b7aa-9665-4f44-8f95-85c2a32ef385.png" border="0"&gt;&lt;/a&gt;So far we have executed both Logic Apps manually on demand. On a real application we will execute both applications automatically at regular intervals. For this we need to uncheck the option “&lt;font face="Segoe UI Black"&gt;Run this logic manually&lt;/font&gt;” and use some application with a trigger. The Salesforce connector doesn’t provide any trigger, but the SQL Server connector does. In both cases one option is to use the “&lt;font face="Segoe UI Black"&gt;Recurrence&lt;/font&gt;” application, which will allow use to automatically execute the application using a predefined time interval. The only inconvenience of this is that, if you use the free plan, the minimum time interval you can specify is one hour (one of the reasons why we chose to run the logic on demand for this article).&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h1&gt;Conclusions&lt;/h1&gt;&lt;p&gt;As we’ve seen, Azure App Services is a powerful tool. With a great amount of connectors (which is rapidly growing) and with the escalation possibilities that offers Azure, it is very easy to create solutions such as the one created in this article. Definitely a tool that any Software Architect should have in her tool belt when designing integrations solutions. &lt;/p&gt;&lt;p&gt;It is true that some areas could be improved. Documentation lacks some details, and there are some minor errors when designing the application logic, but I’m pretty sure this will evolve and get fixed (if not already) as time goes by. Also, the logic of an App Logic is very lineal, and although you can get around some scenarios, this limits some other scenarios, but again, I’m pretty sure this will change later as they will add more options to it.&lt;/p&gt;&lt;p&gt;So, things can only get better, so I will be following this service and see how it evolves from here.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h1&gt;Resources&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;Try Azure for free&lt;strong&gt;: &lt;/strong&gt;&lt;a href="http://azure.microsoft.com/en-us/pricing/free-trial/"&gt;http://azure.microsoft.com/en-us/pricing/free-trial/&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Creation of a Salesforce Developer account: &lt;a href="https://developer.salesforce.com/gettingstarted"&gt;https://developer.salesforce.com/gettingstarted&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Documentation and videos of Azure App Services:&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;a href="http://azure.microsoft.com/en-us/documentation/services/app-service/"&gt;http://azure.microsoft.com/en-us/documentation/services/app-service/&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Documentation of Salesforce connector:&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;a href="http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-connector-salesforce/"&gt;http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-connector-salesforce/&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;List and documentation of Azure App Service connectors:&lt;strong&gt; &lt;/strong&gt;&lt;a href="http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-connectors-list/"&gt;http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-connectors-list/&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;List of functions used in expressions:&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;a href="https://msdn.microsoft.com/en-US/library/azure/dn948512.aspx"&gt;https://msdn.microsoft.com/en-US/library/azure/dn948512.aspx&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;You can also see this article in Spanish in the Microsoft MSDN blog for Spain:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/esmsdn/archive/2015/04/13/azure-app-service-integraciones-con-salesforce-1-de-3.aspx"&gt;Azure App Service: Integraciones con Salesforce (1 de 4)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/esmsdn/archive/2015/04/15/azure-app-service-integraciones-con-salesforce-2-de-4.aspx"&gt;Azure App Service: Integraciones con Salesforce (2 de 4)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/esmsdn/archive/2015/04/16/azure-app-service-integraciones-con-salesforce-3-de-4.aspx"&gt;Azure App Service: Integraciones con Salesforce (3 de 4)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/esmsdn/archive/2015/04/17/azure-app-service-integraciones-con-salesforce-4-de-4.aspx"&gt;Azure App Service: Integraciones con Salesforce (4 de 4)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/showing-system-fields-in-a-custom-visualforce-page-an-improved-approach</id><title type="text">Showing System Fields in a Custom Visualforce Page (an improved approach)</title><updated>2015-05-29T16:06:40Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/showing-system-fields-in-a-custom-visualforce-page-an-improved-approach" /><content type="text">&lt;p&gt;In a previous post (&lt;a href="http://blog.giovannimodica.com/post/showing-system-fields-in-a-custom-visualforce-page" target="_blank"&gt;Showing System Fields in a Custom Visualforce Page&lt;/a&gt;) I talked about how to show system information (Created By, Last Modified By, and Owner) in a custom visualforce page. The approach I presented works but it has some shortcomings:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Doesn’t work as well when the object is a detail object in a Master-Detail relationship (there is no owner here for the detail object, as the owner is the one from the master object)&lt;/li&gt;&lt;li&gt;It requires to put some fields (as hidden) in the visualforce page.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I present here a better approach that takes into consideration the above points.&lt;/p&gt;&lt;p&gt;Let’s start by the component controller:&lt;/p&gt;&lt;pre class="brush: java; highlight: [9,10,11,81];"&gt;public class ComponentControllerSystemInformation {
    public sObject recordValue {        
           get {
               return recordValue;
           }
           set {
               recordValue = value;
               
               Schema.DescribeSObjectResult d = recordValue.getSObjectType().getDescribe();
            String soql = 'select CreatedById,CreatedDate,LastModifiedById,LastModifiedDate' + (isMaster?',OwnerId':'') + ' from ' + d.Name + ' where Id = \'' + recordValue.Id + '\'';
            recordValue = Database.query(soql);
           }
    }
     
    public Id recordId {
        get {
            return recordValue.Id;
        }
    } 
        
    public Id createdById {
        get {
            return (Id)recordValue.get('CreatedById');
        }
    } 
     
    public String createdByName {
        get {
            User createdByUser = [select name from user where id = :createdById limit 1];
            return createdByUser == null ? null : createdByUser.Name;
        }
    }
         
    public String convertedCreatedDate {
        get {
            DateTime createdDate = (DateTime)recordValue.get('CreatedDate');
            return createdDate.format();
        }
    }
     
    public Id lastModifiedById {
        get {
            return (Id)recordValue.get('LastModifiedById');
        }
    } 
     
    public String lastModifiedByName {
        get {
            User lastModifiedByUser = [select name from user where id = :lastModifiedById limit 1];
            return lastModifiedByUser == null ? null : lastModifiedByUser.Name;
        }
    }
         
    public String convertedLastModifiedDate {
        get {
            DateTime lastModifiedDate = (DateTime)recordValue.get('LastModifiedDate');
            return lastModifiedDate.format();
        }
    }
         
    public String ownerName {
        get {
            User ownerUser = [select name from user where id = :ownerId limit 1];
            return ownerUser == null ? null : ownerUser.Name;
        }
    }
     
    public String ownerPhoto {
        get {
            try {
                Id ownerId = (Id)recordValue.get('ownerId');
                User owner = [select smallphotourl from user where id = :ownerId limit 1];
                return owner == null ? null : owner.SmallPhotoUrl;
            } catch(System.RequiredFeatureMissingException e) {
                System.debug('Chatter not enabled in organization:' + e.getMessage());
                return null;
            }
        }
    }
    
    public Boolean isMaster {
      get {
        Schema.DescribeSObjectResult d = recordValue.getSObjectType().getDescribe();
        Map&amp;lt;String, Schema.SObjectField&amp;gt; fields = d.fields.getMap();
        Schema.SObjectField field = fields.get('OwnerId');
        return field != null;
      }
    }
    
    public Id ownerId {
      get {
        if(!isMaster) return null;
        
        return (Id)recordValue.get('OwnerId');
      }
    }             
}
&lt;/pre&gt;&lt;p&gt;Notice lines 9-11 where I query the fields that are required by this component to work, removing the requirement I had in the previous solution to include those fields in the visualforce markup. Notice also in line 81 a new property &lt;font face="Courier New"&gt;isMaster&lt;/font&gt; which we will use to show or hide the owner information in the visualforce page.&lt;/p&gt;&lt;p&gt;The component can now be written as follows:&lt;/p&gt;&lt;pre class="brush: xml; highlight: [18,19];"&gt;&amp;lt;apex:component controller="ComponentControllerSystemInformation"&amp;gt;
    &amp;lt;apex:attribute name="record" assignTo="{!recordValue}"
        type="sObject" description="The object for which to display system information" required="true"/&amp;gt;
     
    &amp;lt;apex:pageBlockSection title="{!$Label.SystemInformation}" columns="2"&amp;gt;
        &amp;lt;apex:pageBlockSectionItem &amp;gt;
            &amp;lt;apex:outputLabel value="{!$Label.LastModifiedBy}" /&amp;gt;
            &amp;lt;apex:outputPanel &amp;gt;
                &amp;lt;apex:outputLink id="lastModifiedBy"
                    onblur="LookupHoverDetail.getHover('{!$Component.lastModifiedBy}').hide();"
                    onfocus="LookupHoverDetail.getHover('{!$Component.lastModifiedBy}', '/{!lastModifiedById}/m?retURL={!URLENCODE($CurrentPage.Url)}&amp;amp;isAjaxRequest=1').show();"
                    onmouseout="LookupHoverDetail.getHover('{!$Component.lastModifiedBy}').hide();"
                    onmouseover="LookupHoverDetail.getHover('{!$Component.lastModifiedBy}', '/{!lastModifiedById}/m?retURL={!URLENCODE($CurrentPage.Url)}&amp;amp;isAjaxRequest=1').show();"                      
                 value="{!URLFOR('/' + lastModifiedById)}"&amp;gt;{!lastModifiedByName}&amp;lt;/apex:outputLink&amp;gt;&amp;amp;nbsp;
                &amp;lt;apex:outputText value="{!convertedLastModifiedDate}" /&amp;gt;                                                                        
            &amp;lt;/apex:outputPanel&amp;gt;
        &amp;lt;/apex:pageBlockSectionItem&amp;gt;
        &amp;lt;apex:pageBlockSectionItem rendered="{!NOT(isMaster)}" /&amp;gt;    
        &amp;lt;apex:pageBlockSectionItem rendered="{!isMaster}"&amp;gt;
            &amp;lt;apex:outputLabel for="owner" value="{!$Label.Owner}" /&amp;gt;
            &amp;lt;apex:outputPanel &amp;gt;
                &amp;lt;apex:image value="{!ownerPhoto}" width="16" height="16"/&amp;gt;&amp;amp;nbsp;
                &amp;lt;apex:outputLink id="owner"
                    onblur="LookupHoverDetail.getHover('{!$Component.owner}').hide();"
                    onfocus="LookupHoverDetail.getHover('{!$Component.owner}', '/{!ownerId}/m?retURL={!URLENCODE($CurrentPage.Url)}&amp;amp;isAjaxRequest=1').show();"
                    onmouseout="LookupHoverDetail.getHover('{!$Component.owner}').hide();"
                    onmouseover="LookupHoverDetail.getHover('{!$Component.owner}', '/{!ownerId}/m?retURL={!URLENCODE($CurrentPage.Url)}&amp;amp;isAjaxRequest=1').show();"
                 value="{!URLFOR('/' + ownerId)}"&amp;gt;{!ownerName}&amp;lt;/apex:outputLink&amp;gt;&amp;amp;nbsp;
                &amp;lt;apex:outputLink value="{!URLFOR('/' + recordId + '/a?retURL=' + URLENCODE($CurrentPage.Url))}"&amp;gt;[Change]&amp;lt;/apex:outputLink&amp;gt;
            &amp;lt;/apex:outputPanel&amp;gt;
        &amp;lt;/apex:pageBlockSectionItem&amp;gt;       
        &amp;lt;apex:pageBlockSectionItem &amp;gt;
            &amp;lt;apex:outputLabel value="{!$Label.CreatedBy}" /&amp;gt;
            &amp;lt;apex:outputPanel &amp;gt;
                &amp;lt;apex:outputLink id="createdBy"
                    onblur="LookupHoverDetail.getHover('{!$Component.createdBy}').hide();"
                    onfocus="LookupHoverDetail.getHover('{!$Component.createdBy}', '/{!createdById}/m?retURL={!URLENCODE($CurrentPage.Url)}&amp;amp;isAjaxRequest=1').show();"
                    onmouseout="LookupHoverDetail.getHover('{!$Component.createdBy}').hide();"
                    onmouseover="LookupHoverDetail.getHover('{!$Component.createdBy}', '/{!createdById}/m?retURL={!URLENCODE($CurrentPage.Url)}&amp;amp;isAjaxRequest=1').show();"                      
                 value="{!URLFOR('/' + createdById)}"&amp;gt;{!createdByName}&amp;lt;/apex:outputLink&amp;gt;&amp;amp;nbsp;
                &amp;lt;apex:outputText value="{!convertedCreatedDate}" /&amp;gt;                                                                        
            &amp;lt;/apex:outputPanel&amp;gt;
        &amp;lt;/apex:pageBlockSectionItem&amp;gt;
    &amp;lt;/apex:pageBlockSection&amp;gt;
&amp;lt;/apex:component&amp;gt;
&lt;/pre&gt;&lt;p&gt;Notice lines 18 and 19, where we use the new property &lt;font face="Courier New"&gt;isMaster&lt;/font&gt; to show or hide the owner information based on whether this is a detail object in a Master-Detail relationship or not.&lt;/p&gt;&lt;p&gt;With this, the visualforce page is simplified as follows:&lt;/p&gt;&lt;pre class="brush: xml; highlight: [3];"&gt;&amp;lt;apex:page standardController="Contact"&amp;gt;
  &amp;lt;apex:pageBlock mode="mainDetail" &amp;gt;
    &amp;lt;c:ComponentControllerSystemInformation record="{!record}" /&amp;gt;
  &amp;lt;/apex:pageBlock&amp;gt;
&amp;lt;/apex:page&amp;gt;
&lt;/pre&gt;&lt;p&gt;We include the component in line 3 inside a &lt;font face="Courier New"&gt;pageBlock&lt;/font&gt; tag. Our page will show the system information just as in a standard page:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/cf69d74d-1ef6-4694-91d7-d4711d5482ac.png"&gt;&lt;img width="644" height="76" title="systemInformation" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="systemInformation" src="http://blog.giovannimodica.com/posts/files/5319763c-afee-4ac8-b524-fb322cfc116f.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;And finally, for completeness, here is the test for the component:&lt;/p&gt;&lt;pre class="brush: java;"&gt;@isTest
public class SystemInformationComponentTest{
  
    @isTest public static void TestComponent() {
         
        Account record = new Account(Name = 'Test');
        insert record;
        record = [select ownerId,createdById,lastModifiedById,createdDate,lastModifiedDate from account where id = :record.id];
        User owner = [select name,smallPhotoUrl from user where id = :record.ownerId];
             
        ComponentControllerSystemInformation controller = new SystemInformationComponentController();
        controller.recordValue = record;
         
        System.assertEquals(record.Id, controller.recordId);
        System.assertEquals(record.CreatedById, controller.createdById);
        System.assertEquals(record.LastModifiedById, controller.lastModifiedById);
        System.assertEquals(record.OwnerId, controller.ownerId);
        System.assertEquals(record.CreatedDate.format(), controller.convertedCreatedDate);
        System.assertEquals(record.LastModifiedDate.format(), controller.convertedLastMOdifiedDate);
        System.assertEquals(owner.Name, controller.ownerName);
        System.assertEquals(owner.SmallPhotoUrl, controller.ownerPhoto); 
        System.assertEquals(owner.Name, controller.lastModifiedByName);
        System.assertEquals(owner.Name, controller.createdByName);
        System.assertEquals(true, controller.isMaster);
    }
}

&lt;/pre&gt;&lt;p&gt;Now, our custom pages have the same functionality as a standard one.&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/salesforce-workflow-outbound-messages-handled-in-net-with-wcf</id><title type="text">Salesforce Workflow Outbound Messages Handled in .Net with WCF</title><updated>2017-07-20T10:44:38Z</updated><author><name>Giovanni Modica</name></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/salesforce-workflow-outbound-messages-handled-in-net-with-wcf" /><content type="text">&lt;p align="right"&gt;(Puedes ver este artículo en español &lt;a href="http://www.grupolanka.com/mensajes-salientes-del-flujo-de-trabajo-en-salesforce-procesados-en-net-con-wcf/"&gt;aquí&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;A high percentage of the Salesforce projects I’ve seen require some kind of integration with backends systems, such as ERPs, databases, or even other CRMs. Salesforce offers a lot of options to make these integrations possible: workflow outbound messages, SOAP/REST callouts, batch integration with DataLoader, etc. Of course there’s lot of documentations on the topic, but most is based on Java and there is little documentation on using .Net. I’m a .Net developer, so I will provide a few examples on how to integrate with Salesforce using Visual Studio and C#. I can’t cover all the possible integration scenarios in just one article, so I will focus on one scenario that I consider as my first option when I design the architecture of a solution that requires integration: workflow outbound messages.&lt;/p&gt;&lt;h2&gt;The Requirements&lt;/h2&gt;&lt;p&gt;Allow me explain the concepts by using a concrete example: one of our clients required to integrate their Salesforce org with their ERP. Both Salesforce and the ERP manage accounts, but they required Salesforce to be the master system for accounts. The integration was based on the following rules:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Accounts are created in Salesforce (not in the ERP)&lt;/li&gt;&lt;li&gt;Any modification to account data in Salesforce needs to be reflected on the ERP (if the account exists in the ERP)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The above rules translate to the following: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;We can create a trigger on account that does a callout to a web service in the ERP, but there’s an easier way (less code): use a workflow outbound message.&lt;/li&gt;&lt;li&gt;We will use a workflow outbound message in account to fire when the account is created or modified and send some of the fields we need to our ERP.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let’s dive into code!&lt;/p&gt;&lt;h2&gt;Workflow Outbound Message in Salesforce&lt;/h2&gt;&lt;p&gt;In Salesforce, go to “Setup-&amp;gt;Build-&amp;gt;Create-&amp;gt;Workflow &amp;amp; Approvals-&amp;gt;Workflow Rules”. Create a new rule, and base it on the &lt;font face="Courier New"&gt;Account&lt;/font&gt; object:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/cb4e8adc-3ab7-4305-b6b8-8090cf30aceb.jpg"&gt;&lt;img width="244" height="180" title="Workflow account rule" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Workflow account rule" src="http://blog.giovannimodica.com/posts/files/34b9237d-06c1-4a2b-b800-6c0c50538412.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click next. Give it a name (I will use &lt;font face="Courier New"&gt;UpdateAccountOnERP&lt;/font&gt;) and for the evaluation criteria specify “created, and every time it’s edited”. We want this option since we would like to update the account on the ERP every time a modification is made in Salesforce. We want this workflow to be triggered every time, so for the rule criteria, choose “formula evaluates to true”, and specify &lt;font face="Courier New"&gt;true&lt;/font&gt; as the formula. The workflow should look as this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/41beac44-deab-4e39-8f7b-8661aaaa4ddd.jpg"&gt;&lt;img width="450" height="388" title="Workflow account rule details" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Workflow account rule details" src="http://blog.giovannimodica.com/posts/files/b140cc6f-feeb-444c-8b75-28eb13ca8251.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click save and next. On the next screen you will add a workflow action. Click on the “Add Workflow Action” dropdown and select “New Outbound Message”. On the New Outbound Message screen, give it a name and unique name (I will use &lt;font face="Courier New"&gt;SendAccountToERP&lt;/font&gt;), for the endpoint put any url since we don’t have our web service yet, and finally select all the fields that you would like to send to the ERP. When finished, click Done. You will be taken to the workflow rule screen. Make sure you activate the workflow (click on the “Activate” button).&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/fe195a08-eb85-43be-a12d-6618a6687780.jpg"&gt;&lt;img width="539" height="359" title="Account workflow rule summary" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Account workflow rule summary" src="http://blog.giovannimodica.com/posts/files/cfb22eb5-7ab8-44e8-b2d0-85be97702359.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We have created an outbound message that will be triggered when an account is modified, but the outbound message will fail since we have not created a web service to handle it. For this we need to get the WSDL of the outbound message. Click on the outbound message description and you will be taken to Workflow Outbound Message Detail:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/9df0719b-76bc-460c-8ceb-e352c6a74fd3.jpg"&gt;&lt;img width="486" height="336" title="Account outbound message detail" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Account outbound message detail" src="http://blog.giovannimodica.com/posts/files/d074e26a-9cf1-40f1-a156-28205ec7adcf.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click on the hyperlink “Click for WSDL”. A new window with the WSDL will be opened. Save the WSDL to disc (I named it &lt;font face="Courier New"&gt;accountWorkflowOutboundMessage.wsdl&lt;/font&gt;), we will need it in Visual Studio.&lt;/p&gt;&lt;h2&gt;Web Service in Visual Studio (using WCF)&lt;/h2&gt;&lt;p&gt;Now that you have the WSDL for the outbound message, we need to create a web service to handle the message. This &lt;a href="https://developer.salesforce.com/page/Creating_an_Outbound_Messaging_Notification_Service_with_CSharp_and_.Net_Framework_2.0"&gt;article&lt;/a&gt; gives you an overview of how you can create an asmx web service, but I rather work with WCF instead (asmx is kind of old and WCF is supposed to replace it, isn’t?). Also, I will use &lt;a href="http://www.visualstudio.com/"&gt;Visual Studio 2013 Community&lt;/a&gt; edition for this. Open Visual Studio and create a new empty ASP.Net Web Application:&lt;/p&gt;&lt;p&gt;&lt;img width="408" height="285" title="New Asp.Net project" align="left" style="float: left; display: inline; background-image: none;" alt="New Asp.Net project" src="http://blog.giovannimodica.com/posts/files/eda1f59c-08b8-4a85-9624-367638b8a02b.jpg" border="0"&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/61dac3bb-2126-4d13-8e3d-6f3038c97baf.jpg"&gt;&lt;img width="327" height="244" title="Empty Asp.Net project" style="display: inline; background-image: none;" alt="Empty Asp.Net project" src="http://blog.giovannimodica.com/posts/files/26e835b6-adb3-49bd-9a80-8ef60cd4a3a8.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;We will add a WCF service to the project. Right click on the project name in Solution Explorer and choose “Add-&amp;gt;New Item”. Select “WCF Service”:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/38454c5b-5ce6-410b-a7d3-5ea4a95c1dd6.jpg"&gt;&lt;img width="644" height="448" title="New WCF web wervice" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="New WCF web wervice" src="http://blog.giovannimodica.com/posts/files/dc875763-500f-453e-a5f4-a1e87d2718a9.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Visual Studio will add the required assemblies to the project and will create three files: &lt;font face="Courier New"&gt;IAccountNotificationService.cs&lt;/font&gt;, &lt;font face="Courier New"&gt;AccountNotificationService.svc&lt;/font&gt; and the underlying &lt;font face="Courier New"&gt;AccountNotificationService.svc.cs&lt;/font&gt;. We will need to replace the interface definition to match the definition of the outbound message. Add the WSDL file to your project. Open a command prompt on the directory where the WSDL resides (if you have the &lt;a href="https://visualstudiogallery.msdn.microsoft.com/dbcb8670-889e-4a54-a226-a48a15e4cace?SRC=VSIDE"&gt;Productivity Power Tools&lt;/a&gt; extension you can right click on the project in Solution Explorer and choose “Power Commands-&amp;gt;Open Command Prompt”). At the command prompt type the following:&lt;/p&gt;&lt;pre&gt;svcutil /noconfig /out:IAccountNotificationService.cs accountWorkflowOutboundMessage.wsdl
&lt;/pre&gt;&lt;p&gt;The &lt;font face="Courier New"&gt;svcutil&lt;/font&gt; command creates the interface for the web service definition. Here is the output of the command:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/e04f2d5c-a170-49e5-ab5f-bd1cab2ee848.jpg"&gt;&lt;img width="644" height="202" title="svcutil output" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="svcutil output" src="http://blog.giovannimodica.com/posts/files/3641102f-3af3-4e76-b743-c7513da729f5.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Notice that the command replaced the contents of the file &lt;font face="Courier New"&gt;IAccountNotificationService.cs&lt;/font&gt; with the web service definition of the WSDL. You project should now look like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/9118e787-a3b2-4bac-846f-97a2ba778ca0.jpg"&gt;&lt;img width="244" height="155" title="Solution explorer" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Solution explorer" src="http://blog.giovannimodica.com/posts/files/04d81865-fdd6-40de-87cd-a6e16ee6e031.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Now, there are some tricks to make this work. Open &lt;font face="Courier New"&gt;IAccountNotificationService.cs&lt;font face="Segoe UI"&gt; and change the following: &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;font face="Courier New"&gt;&lt;font face="Segoe UI"&gt;Put the whole class inside the namespace of the project (in my case is the name of the project &lt;font face="Courier New"&gt;WorkflowNotificationServices&lt;/font&gt;)&lt;/font&gt;&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face="Courier New"&gt;&lt;font face="Segoe UI"&gt;Change the name of the interface from &lt;font face="Courier New"&gt;NotificationPort&lt;/font&gt; to &lt;font face="Courier New"&gt;IAccountNotificationService&lt;/font&gt;. &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font face="Courier New"&gt;&lt;font face="Segoe UI"&gt;Change the &lt;font face="Courier New"&gt;ConfigurationName&lt;/font&gt; parameter of the &lt;font face="Courier New"&gt;ServiceContractAttribute&lt;/font&gt; attribute from &lt;font face="Courier New"&gt;NotificationPort&lt;/font&gt; to &lt;font face="Courier New"&gt;AccountNotificationService&lt;/font&gt;. &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;&lt;li&gt;Remove the parameter &lt;font face="Courier New"&gt;ReplyAction=”*”&lt;/font&gt; from the &lt;font face="Courier New"&gt;OperationContractAttribute&lt;/font&gt; attribute. This is important in order to make things work.&lt;/li&gt;&lt;li&gt;&lt;font face="Courier New"&gt;&lt;font face="Segoe UI"&gt;At the end of the file, remove the interface &lt;font face="Courier New"&gt;NotificationPortChannel&lt;/font&gt; and the class &lt;font face="Courier New"&gt;NotificationPortClient&lt;/font&gt; (we don’t need these since they are used by a client consuming the web service). &lt;/font&gt;&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The interface should now look as the following (highlighted lines are the one that changed):&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [1,4,5,9];"&gt;namespace WorkflowNotificationServices
{
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://soap.sforce.com/2005/09/outbound", ConfigurationName = "AccountNotificationService")]
    public interface IAccountNotificationService
    {

        // CODEGEN: Generating message contract since the operation notifications is neither RPC nor document wrapped.
        [System.ServiceModel.OperationContractAttribute(Action = "")]
        [System.ServiceModel.XmlSerializerFormatAttribute()]
        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(sObject))]
        notificationsResponse1 notifications(notificationsRequest request);
    }

    /// rest of the code below
}
&lt;/pre&gt;&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font face="Segoe UI"&gt;Next, open the file &lt;font face="Courier New"&gt;AccountNotificationService.svc.cs&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Segoe UI"&gt;, remove the &lt;font face="Courier New"&gt;DoWork&lt;/font&gt; method and implement the &lt;font face="Courier New"&gt;IAccountNotificationService &lt;/font&gt;interface (place the cursor on text for the name of the interface and press &lt;font face="Courier New"&gt;Crtl+.&lt;/font&gt; and choose “Implement interface IAccountNotificationService”).&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Finally, open &lt;font face="Courier New"&gt;web.config&lt;/font&gt; and replace it with the following:&lt;/p&gt;&lt;pre class="brush: xml; highlight: [3,18,19,20];"&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;connectionStrings&amp;gt;
        &amp;lt;add name="ERP" connectionString="Data Source=localhost;Initial Catalog=ERP;Integrated Security=True" providerName="System.Data.SqlClient"/&amp;gt;
    &amp;lt;/connectionStrings&amp;gt;
    &amp;lt;system.web&amp;gt;
        &amp;lt;compilation debug="true" targetFramework="4.5" /&amp;gt;
        &amp;lt;httpRuntime targetFramework="4.5" /&amp;gt;
        &amp;lt;webServices&amp;gt;
            &amp;lt;protocols&amp;gt;
                &amp;lt;clear/&amp;gt;
                &amp;lt;add name="HttpSoap" /&amp;gt;
                &amp;lt;add name="Documentation"/&amp;gt;
            &amp;lt;/protocols&amp;gt;
        &amp;lt;/webServices&amp;gt;
    &amp;lt;/system.web&amp;gt;
    &amp;lt;system.serviceModel&amp;gt;
        &amp;lt;services&amp;gt;
            &amp;lt;service name="WorkflowNotificationServices.AccountNotificationService"&amp;gt;
                &amp;lt;endpoint binding="basicHttpBinding" contract="AccountNotificationService"/&amp;gt;
            &amp;lt;/service&amp;gt;
        &amp;lt;/services&amp;gt;
        &amp;lt;behaviors&amp;gt;
            &amp;lt;serviceBehaviors&amp;gt;
                &amp;lt;behavior name=""&amp;gt;
                    &amp;lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /&amp;gt;
                    &amp;lt;serviceDebug includeExceptionDetailInFaults="false" /&amp;gt;
                &amp;lt;/behavior&amp;gt;
            &amp;lt;/serviceBehaviors&amp;gt;
        &amp;lt;/behaviors&amp;gt;
        &amp;lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /&amp;gt;
    &amp;lt;/system.serviceModel&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;&lt;p&gt;Notice in line 3 I’ve created a connection string to the database for the ERP. I will use this later in the implementation of the web service. Also notice the declaration of the web service in lines 18-20.&lt;/p&gt;&lt;p&gt;&lt;font face="Segoe UI"&gt;You project should compile at this point. Also, we should be able to get the WSDL for our web service. Run the project and using a browser connect to the web service. You should see something like this:&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/f73b4e25-2256-469c-94aa-6d73948025ef.jpg"&gt;&lt;img width="644" height="441" title="Account web service" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Account web service" src="http://blog.giovannimodica.com/posts/files/2c5021ca-d7de-4ee1-b5a2-a0575e1b5899.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Segoe UI"&gt;All we have left is to write the code to update our ERP. In this example I will just call a stored procedure on a SQLServer database to update the ERP (is just an example, you can do here whatever you need to communicate with the backend). My service implementation looks like this:&lt;/font&gt;&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WorkflowNotificationServices
{
    public class AccountNotificationService : IAccountNotificationService
    {
        public notificationsResponse1 notifications(notificationsRequest request)
        {
            notifications notifications1 = request.notifications;

            AccountNotification[] accountNotifications = notifications1.Notification;
            foreach (AccountNotification accountNotification in accountNotifications)
            {
                Account account = (Account)accountNotification.sObject;

                ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["ERP"];
                using (SqlConnection cn = new SqlConnection(connectionString.ConnectionString))
                {
                    using (SqlCommand command = new SqlCommand("salesforce_updateAccount", cn))
                    {
                        command.CommandType = CommandType.StoredProcedure;

                        command.Parameters.Add("@idSalesforce", SqlDbType.VarChar).Value = account.Id;
                        command.Parameters.Add("@name", SqlDbType.VarChar).Value = account.Name;
                        command.Parameters.Add("@number", SqlDbType.VarChar).Value = (object)account.AccountNumber ?? DBNull.Value;
                        command.Parameters.Add("@address", SqlDbType.VarChar).Value = (object)account.BillingStreet ?? DBNull.Value;
                        command.Parameters.Add("@city", SqlDbType.VarChar).Value = (object)account.BillingCity ?? DBNull.Value;
                        command.Parameters.Add("@state", SqlDbType.VarChar).Value = (object)account.BillingState ?? DBNull.Value;
                        command.Parameters.Add("@postalCode", SqlDbType.VarChar).Value = (object)account.BillingPostalCode ?? DBNull.Value;
                        command.Parameters.Add("@country", SqlDbType.VarChar).Value = (object)account.BillingCountry ?? DBNull.Value;

                        cn.Open();
                        command.ExecuteNonQuery();
                    }
                }
            }

            notificationsResponse response = new notificationsResponse();
            response.Ack = true;

            return new notificationsResponse1() { notificationsResponse = response };
        }
    }
}
&lt;/pre&gt;&lt;p&gt;It is important to set the &lt;font face="Courier New"&gt;Ack&lt;/font&gt; variable of the response to &lt;font face="Courier New"&gt;true&lt;/font&gt;, otherwise Salesforce will think there was an error and will keep the outbound message in the queue and retry to send it at regular intervals.&lt;/p&gt;&lt;h2&gt;Testing the Outbound Message&lt;/h2&gt;&lt;p&gt;We need to publish our web service and make it available on the internet. The publishing is outside of the scope of this article. In my case I published it on an IIS server in our DMZ, and the public url is &lt;font face="Courier New"&gt;http://http.grupolanka.com/Salesforce/WorkflowNotificationServices/AccountNotificationService.svc&lt;/font&gt; (don’t try it, it won’t work)&lt;/p&gt;&lt;p&gt;Now I need to go back to Salesforce and change the url of the outbound message I created earlier. In Salesforce go to “Setup-&amp;gt;Build-&amp;gt;Create-&amp;gt;Workflow &amp;amp; Approvals-&amp;gt;Outbound Messages”. Edit the outbound message definition (in the example is &lt;font face="Courier New"&gt;SendAccountToERP&lt;/font&gt;) and edit the “Endpoint URL” field:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/d445c042-6bcc-4249-9962-6eabbaf872bb.jpg"&gt;&lt;img width="644" height="435" title="Account outbound message url" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Account outbound message url" src="http://blog.giovannimodica.com/posts/files/37557b2d-2265-43d1-bfa7-9992cf9d3f7e.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Save it. Open an account and make a modification, Salesforce will now call the web service passing the fields specified in the outbound message definition.&lt;/p&gt;&lt;p&gt;And that’s it! You can now have Salesforce to “talk” to your backend. In a next article I will complicate things a bit and let the web service call back to Salesforce for additional data. You can get the sample project here:&lt;/p&gt;&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%2111200&amp;amp;authkey=AHYSg4EZ70y_We8" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/creating-a-salesforce-external-data-source-using-an-odata-service-created-in-net</id><title type="text">Creating a Salesforce External Data Source using an OData Service Created in .Net</title><updated>2017-01-25T12:35:43Z</updated><author><name>Giovanni Modica</name></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/creating-a-salesforce-external-data-source-using-an-odata-service-created-in-net" /><content type="text">&lt;p align="right"&gt;(Puedes ver este artículo en español &lt;a href="http://www.grupolanka.com/external-data-source-en-salesforce-servicio-odata-net/"&gt;aquí&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;Salesforce allows to access &lt;a href="https://help.salesforce.com/HTViewHelpDoc?id=external_data_source_define.htm&amp;amp;language=en_US"&gt;external data sources&lt;/a&gt; using &lt;a href="http://www.odata.org"&gt;OData&lt;/a&gt; protocol. This feature is actually one of the most useful feature when designing and integration strategy with backend systems. Instead of using web services or the DataLoader to put the data into Salesforce, we can get up-to-date data directly from the third-party system by using an external data source. By using an external data source, and the external object it creates, we can access information located outside Salesforce as if it were stored inside Salesforce. The only disadvantage at the moment is that an external data source is read only, so we cannot use it to update data on third-party system. But still, this opens a whole lot of integration scenarios for us.&lt;/p&gt;&lt;p&gt;Let’s see an example of when this might come useful. I recently worked on a project where an integration between Salesforce and the ERP was required. Sales executives needed to see Account administrative alerts (e.g. “client has pending bills”, or “client has a claim on its latest bill”, etc.) in Salesforce. These alerts were generated in the ERP by the administrative users. Clearly we needed to bring those alerts to Salesforce.&lt;/p&gt;&lt;p&gt;One approach would be to use the DataLoader to upload alerts to Salesforce in batch, with a predefined frequency (once a day for example). This solution is quick and easy, but requires a lot of steps: creating the Alerts object in Salesforce, setting up the DataLoader command line mode to retrieve the data directly from the ERP and do an upsert in Salesforce, and using a scheduler program to do execute the DataLoader job at regular intervals. But it turns out there is an easier way! Well, easier if you read this post :-)&lt;/p&gt;&lt;p&gt;Instead of putting the data into Salesforce, we will let Salesforce retrieve the data dynamically from the ERP. For this we will use an external data source and create an external object. You can create an external object based in OData (unfortunately only version 2.0, although at the time of writing this OData is at version 4.0). Let’s see how we can use Visual Studio and .Net to expose the data from the ERP.&lt;/p&gt;&lt;h2&gt;Setting up the Example&lt;/h2&gt;&lt;p&gt;I will use a pretty simple example. I will simulate the ERP as a SQLServer database. We have an account table and an alert table that defines the alerts for our accounts. Our ERP will look like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/9b62fdcc-3d82-4dbb-9229-5e606564ea3e.jpg"&gt;&lt;img width="244" height="123" title="Database" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Database" src="http://blog.giovannimodica.com/posts/files/76937d13-cc09-41d3-adff-152278633313.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Use the following script to create the database and the tables:&lt;/p&gt;&lt;pre class="brush: sql;"&gt;/****** Object:  Database [ERP]    Script Date: 12/30/2014 17:22:48 ******/
CREATE DATABASE [ERP] ON  PRIMARY 
( NAME = N'ERP', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\ERP.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'ERP_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\ERP_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

USE [ERP]

/****** Object:  Table [dbo].[Account]    Script Date: 12/30/2014 17:22:49 ******/
CREATE TABLE [dbo].[Account](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Alert]    Script Date: 12/30/2014 17:22:49 ******/
CREATE TABLE [dbo].[Alert](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [accountId] [int] NOT NULL,
    [alertText] [varchar](50) NULL,
 CONSTRAINT [PK_Alert] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  ForeignKey [FK_Alert_Account]    Script Date: 12/30/2014 17:22:49 ******/
ALTER TABLE [dbo].[Alert]  WITH CHECK ADD  CONSTRAINT [FK_Alert_Account] FOREIGN KEY([accountId])
REFERENCES [dbo].[Account] ([id])
GO
ALTER TABLE [dbo].[Alert] CHECK CONSTRAINT [FK_Alert_Account]
GO
&lt;/pre&gt;&lt;p&gt;And populate the database with the following script:&lt;/p&gt;&lt;pre class="brush: sql;"&gt;insert into Account values('ModicaTech')
insert into Account values('Microsoft')
insert into Account values('Salesforce')
insert into Alert values(1,'Client requesting support')
insert into Alert values(2,'Client has pending receipts')
&lt;/pre&gt;&lt;h2&gt;Creating the OData Web Service&lt;/h2&gt;&lt;p&gt;Using &lt;a href="http://www.visualstudio.com"&gt;Visual Studio 2013 Community&lt;/a&gt; edition, create a new empty ASP.Net Web project. We will add an Entity Framework data model to this project. Right click on the project name and choose “Add New Item”. Select “ADO.ET Entity Data Model” and name it &lt;font face="Courier New"&gt;ErpModel&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/4b667f2f-23bf-4828-b431-182e5af6a515.jpg"&gt;&lt;img width="644" height="447" title="New ADO.Net data model" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="New ADO.Net data model" src="http://blog.giovannimodica.com/posts/files/d3a65ebf-82b8-488b-9270-2f082d896a4d.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;On the Entity Data Model Wizard, select “EF Designer from database” and click Next. Create a new connection to the SQLServer and the ERP database:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/46c724e5-fbc1-4cf8-a713-df21509f0b31.jpg"&gt;&lt;img width="326" height="343" title="New connection" style="display: inline; background-image: none;" alt="New connection" src="http://blog.giovannimodica.com/posts/files/01b9cbb9-cdee-472b-adf5-c06f393257cc.jpg" border="0"&gt;&lt;/a&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/f4a651a0-0527-4d64-b746-f11be4393039.jpg"&gt;&lt;img width="442" height="400" title="ERP connection" style="display: inline; background-image: none;" alt="ERP connection" src="http://blog.giovannimodica.com/posts/files/4ebadd8d-5e05-468f-b369-2f66c93967bb.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click Next and make sure you select “Entity Framework 5.0” as the version of Entity Framework to use, and click Next. Select both tables:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/f3c9ece3-f04c-4057-a5f4-b6f86277dac1.jpg"&gt;&lt;img width="533" height="484" title="EF select tables" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="EF select tables" src="http://blog.giovannimodica.com/posts/files/d0b88e34-ff1b-463c-b639-e4f7f947fa4f.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click Finish. The Wizard will generate the code to connect to the database. We will now add the OData service to the project. Right click on the project name and choose “Add New Item…". Select “WCF Data Service 5.6” and name it &lt;font face="Courier New"&gt;ErpService.svc&lt;/font&gt;:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/1f532b82-e3de-4b1e-bbe5-a1d90e36e110.jpg"&gt;&lt;img width="644" height="447" title="New OData service" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="New OData service" src="http://blog.giovannimodica.com/posts/files/d8cccce6-1084-4bde-98e3-fbf6f10d5d1b.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The wizard will create the &lt;font face="Courier New"&gt;ErpService.svc.cs&lt;/font&gt; file and open it on the editor. Replace the text in the TODO for the name of the entity data model. The file should look like this:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [11,16,18];"&gt;using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace ErpODataService
{
    public class ErpService : DataService&amp;lt;ERPEntities&amp;gt;
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Notice line 11 where we specify the name of our entity data model. Line 16 specifies read access for all our entities. Finally, line 18 sets the version of OData to 2.0 (the one required by Salesforce). If you run the project you should see something like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/82476717-0238-43f7-b9de-a002f1e5d4b2.jpg"&gt;&lt;img width="644" height="263" title="OData service" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="OData service" src="http://blog.giovannimodica.com/posts/files/5051e11e-5b03-4b04-b7a5-44bf8cf8608d.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Publish the web service to a public internet URL. I have published in an IIS in our DMZ with the URL http://www.grupolanka.com/Salesforce/ErpODataService/ErpService.svc (don’t try, it wont work)&lt;/p&gt;&lt;h2&gt;Creating the External Data Source in Salesforce&lt;/h2&gt;&lt;p&gt;Go to Salesforce, then go to “Setup-&amp;gt;Build-&amp;gt;Develop-&amp;gt;External Data Sources” and click on the “New External Data Source” button. Specify a label and name and make sure you select “Lighting Connect: OData 2.0” as the type. In the server url put the url to access the OData service we created, and in the format select AtomPub. Specify anonymous as the authentication since we haven’t specify any security on the OData service (for simplicity). The external data source should like like the following:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/dfe44b9d-0bb4-4f9d-abe8-3fb0584e7ff7.jpg"&gt;&lt;img width="644" height="413" title=" External data source" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt=" External data source" src="http://blog.giovannimodica.com/posts/files/64684cfb-8fd7-46c3-bf34-9e0f124c1923.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When you save it, you will click on “Validate and Sync” button:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/8edabe68-62dd-4305-a7f7-03cf98a576dc.jpg"&gt;&lt;img width="644" height="390" title="Validate and sync external data source" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Validate and sync external data source" src="http://blog.giovannimodica.com/posts/files/f88bd8b8-e4ca-4e4d-bef1-5148d3df1493.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Select the Alerts object and click the Sync button. Salesforce will create the &lt;font face="Courier New"&gt;Alerts__x&lt;/font&gt; object. Click on it to see its properties:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/a352828b-1286-4c3c-8794-b470cf6f3bcd.jpg"&gt;&lt;img width="644" height="353" title="Alerts object" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Alerts object" src="http://blog.giovannimodica.com/posts/files/614b5598-1d4b-40f9-9bae-17992531cf87.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We will now create a relationship between this external object and the &lt;font face="Courier New"&gt;Account&lt;/font&gt; object to link alerts to accounts. But first we need to create a custom field on &lt;font face="Courier New"&gt;Account&lt;/font&gt; and mark it as an external id in order to make the relationship. Go to “Setup-&amp;gt;Build-&amp;gt;Customize-&amp;gt;Accounts-&amp;gt;Fields“ and in the “Account Custom Fields &amp;amp; Relationships” create a new custom field called &lt;font face="Courier New"&gt;External_ID&lt;/font&gt;. Make sure to mark it as “Unique” and “External ID”:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/43853c87-1010-40cd-9cc0-5d48a4444ff2.jpg"&gt;&lt;img width="644" height="392" title="External id" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="External id" src="http://blog.giovannimodica.com/posts/files/2db4bce8-5cc6-4445-bd5c-cfd188f5ff2b.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Go to back to the &lt;font face="Courier New"&gt;Alerts&lt;/font&gt; external object (“Setup-&amp;gt;Build-&amp;gt;Develop-&amp;gt;External Objects”). On the “Custom Fields &amp;amp; Relationships” section click on New. Choose “Indirect Lookup Relationship” as the field data type. Next select Accounts in the “Related To” field:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/3cf4e282-7766-40e5-82c1-33c1cf4113f4.jpg"&gt;&lt;img width="644" height="247" title="Related to" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Related to" src="http://blog.giovannimodica.com/posts/files/455ebe9e-6553-4480-9257-0e85a61e8e4a.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click Next. In the target field select custom field for account we created before (&lt;font face="Courier New"&gt;External_ID__c&lt;/font&gt;)&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/06f7f2a8-2ed3-4f6e-9549-7a4a631a2a3a.jpg"&gt;&lt;img width="644" height="251" title="Target field" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Target field" src="http://blog.giovannimodica.com/posts/files/66e5614e-d9de-423d-b4eb-8993bb137f41.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; Click Next. Enter a label and name for the field. Make sure you specify &lt;font face="Courier New"&gt;accountId&lt;/font&gt; as the “External Column Name”. This is the field in the external data source that contains the foreign key to account.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/f424f7ec-87f1-4a51-b93b-72ce64100d72.jpg"&gt;&lt;img width="623" height="484" title="Indirect lookup relationship properties" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Indirect lookup relationship properties" src="http://blog.giovannimodica.com/posts/files/74eac5d5-a9e4-49fb-99cd-0ada26a4b5ce.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click Next on the rest of the Wizard.&lt;/p&gt;&lt;p&gt;We now need to create a Tab for the new object and add it to an application. Go to “Setup-&amp;gt;Build-&amp;gt;Create-&amp;gt;Tabs” and create a new tab for the &lt;font face="Courier New"&gt;Alerts&lt;/font&gt; object. Select a theme. Then assign the tab to an application. You should now see something like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/f0c2423d-6eb1-46a2-b9ec-4293c9da9359.jpg"&gt;&lt;img width="644" height="125" title="Alerts tab" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Alerts tab" src="http://blog.giovannimodica.com/posts/files/b3273c56-8308-44e7-85e1-d28ab26ca497.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click on one of the records to see its details:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/e35e9d28-cdda-4271-a2dd-b30add981ef8.jpg"&gt;&lt;img width="644" height="316" title="Alert detail" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Alert detail" src="http://blog.giovannimodica.com/posts/files/f8599152-e400-4e25-8963-0168b36508cb.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h2&gt;Seeing the External Data on a Salesforce Object&lt;/h2&gt;&lt;p&gt;Now, let’s open an account (any account). Specify a value for the field “External Id”. Use 1 as the value so we will get all the alerts associated to the account with id 1&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/ee6b251d-30c9-4f6d-9677-554315278004.jpg"&gt;&lt;img width="1028" height="750" title="accountDetail" style="display: inline; background-image: none;" alt="accountDetail" src="http://blog.giovannimodica.com/posts/files/9906b79c-75a9-4d91-bc34-6e53f7f1c574.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Notice that you will need to edit the layout for the related list to show the &lt;font face="Courier New"&gt;alertText&lt;/font&gt; field.&lt;/p&gt;&lt;p&gt;And this is it! We can dynamically see the data from our ERP in Salesforce. Let’s do a test. Insert a new alert for the account with id 1:&lt;/p&gt;&lt;pre class="brush: sql;"&gt;insert into Alert values(1,'This thing works!')
&lt;/pre&gt;&lt;p&gt;Refresh the account in Salesforce, you should see the new alert:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/661541ce-e0b4-4bc9-87e6-313ab737f9a5.jpg"&gt;&lt;img width="617" height="131" title="New alert" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="New alert" src="http://blog.giovannimodica.com/posts/files/bf5e3163-24a0-4a4d-87e9-b91a4a726330.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;You can find the Visual Studio project here:&lt;/p&gt;&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%2111216&amp;amp;authkey=ABnpajCf03NJYyg" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/f424f7ec-87f1-4a51-b93b-72ce64100d72.jpg"&gt;&lt;br&gt;&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/call-a-net-webapi-service-from-salesforce</id><title type="text">Call a .Net WebAPI Service from Salesforce</title><updated>2015-01-26T16:51:37Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/call-a-net-webapi-service-from-salesforce" /><content type="text">&lt;p align="right"&gt;(Puedes ver este artículo en español &lt;a href="http://www.grupolanka.com/como-llamar-un-servicio-webapi-de-net-desde-salesforce-2/"&gt;aquí&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;In a previous article, &lt;a href="http://blog.giovannimodica.com/post/call-a-net-wcf-service-from-salesforce" target="_blank"&gt;Call a .Net WCF Service from Salesforce&lt;/a&gt;, I explained how to make an external call in a Salesforce trigger to get data from a third party system by using a custom web service created in .Net WCF. This approach was using SOAP as the messaging protocol between Salesforce and our web service. We all know the advantages and disadvantages of SOAP compared to REST, but the truth is that REST is the preferred choice when it comes to creating web services. So, in this article I will modify the example presented in the previous post to use REST instead. &lt;/p&gt;&lt;p&gt;Allow me to refresh the problem we were trying to solve: our client wants to create sales quotes in Salesforce, but wants the price of products to come from the ERP. Our solution was to create a web service (a SOAP web service) in .Net WCF that given a product identifier returned the price of the product, we then called this service from a trigger defined in the &lt;font face="Courier New"&gt;QuoteLineItem&lt;/font&gt; object in Salesforce. We will keep the same architecture to the solution (the trigger and the web service) but this time we will use REST. I suggest you read the &lt;a href="http://blog.giovannimodica.com/post/call-a-net-wcf-service-from-salesforce" target="_blank"&gt;previous article&lt;/a&gt; to get a better understanding of what we would like to accomplish.&lt;/p&gt;&lt;h2&gt;The WebAPI Service&lt;/h2&gt;&lt;p&gt;Let’s start by creating our REST service. We will use an MVC WebAPI project in Visual Studio for this. I will use &lt;a href="http://visualstudio.com/" target="_blank"&gt;Visual Studio Community Edition&lt;/a&gt; to do this. Open Visual Studio and create a new “ASP.Net Web Application” name &lt;font face="Courier New"&gt;ErpApiService&lt;/font&gt;. Select “Web API” as the template and make sure you select “No Authentication” from the “Change Authentication” button (for simplicity we will not deal with security in this article).&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/6d7c6ad2-16ea-4971-a091-39baddc8b472.jpg"&gt;&lt;img width="417" height="291" title="New Asp.Net project" style="display: inline; background-image: none;" alt="New Asp.Net project" src="http://blog.giovannimodica.com/posts/files/b3e935d0-c587-488d-870c-78ad1aab5871.jpg" border="0"&gt;&lt;/a&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/34005c35-f51d-4f37-8f09-fd57f622969e.jpg"&gt;&lt;img width="404" height="302" title="New Web API project" style="display: inline; background-image: none;" alt="New Web API project" src="http://blog.giovannimodica.com/posts/files/c2386d9c-9d25-4777-a4bc-0ed3447903c0.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Visual Studio will create a sample Web API project with a sample controller. Go to the &lt;font face="Courier New"&gt;Controllers&lt;/font&gt; folder and rename the file &lt;font face="Courier New"&gt;ValuesController.cs&lt;/font&gt; to &lt;font face="Courier New"&gt;ProductController.cs&lt;/font&gt;. If Visual Studio asks you to apply the rename to all references in code select yes. Replace the contents of the ProductController.cs file with the following:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [17];"&gt;using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace ErpApiService.Controllers
{
    public class ProductController : ApiController
    {
        // GET api/product/getPriceForCustomer?id={id}
        public decimal GetPriceForCustomer(string id)
        {
            try
            {
                ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["ERP"];
                using (SqlConnection cn = new SqlConnection(connectionString.ConnectionString))
                {
                    using (SqlCommand command = new SqlCommand("salesforce_getProductPrice", cn))
                    {
                        command.CommandType = CommandType.StoredProcedure;

                        command.Parameters.Add("@productId", SqlDbType.VarChar).Value = (object)id ?? DBNull.Value;
                        SqlParameter priceParameter = command.Parameters.Add("@price", SqlDbType.Money);
                        priceParameter.Direction = ParameterDirection.Output;

                        cn.Open();
                        command.ExecuteNonQuery();

                        return (decimal)command.Parameters["@price"].Value;
                    }
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.Message);
                return 0;
            }
        }
    }
}

&lt;/pre&gt;&lt;p&gt;The highlighted line is the most important in this example, it defines the signature of the REST resource. By convention, if a method starts with Get (as in our example) the WebAPI engine will use the HTTP GET method to call it. The rest of the code is just ADO.Net boilerplate code to call a stored procedure in a database (in this case a SQLServer database).&lt;/p&gt;&lt;p&gt;Publish this web service to a public URL. In my case I published it to an IIS server in the DMZ and the URL is the following: http://www.grupolanka.com/Salesforce/ErpApiService/api/Product?id={id} (don’t try it, it won’t work). Now, we are ready to consume this REST service from Salesforce.&lt;/p&gt;&lt;h2&gt;Calling the REST Service from Salesforce&lt;/h2&gt;&lt;p&gt;Go to Salesforce and using the Developer Console let’s create an anonymous code to test our service. Type the following APEX code:&lt;/p&gt;&lt;pre class="brush: java;"&gt;String url = 'http://www.grupolanka.com/Salesforce/ErpApiService/api/Product?id=PADAP20001';

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod('GET');
HttpResponse res = h.send(req);

system.debug('Price: ' + res.getBody());
&lt;/pre&gt;&lt;p&gt;You should be able to see the price sent from the ERP in the log. &lt;/p&gt;&lt;p&gt;Now let’s change the class we had from our &lt;a href="http://blog.giovannimodica.com/post/call-a-net-wcf-service-from-salesforce" target="_blank"&gt;previous article&lt;/a&gt; to do the REST call instead of SOAP. On the Developer Console, open the class &lt;font face="Courier New"&gt;QuoteLineItemProcesses&lt;/font&gt; class and replace the code with the following:&lt;/p&gt;&lt;pre class="brush: java;"&gt;global with sharing class QuoteLineItemProcesses {
    @future (callout = true)
    public static void updateLinePrice(List&amp;lt;Id&amp;gt; lineItemIds) {
        Boolean changed = false;
        
        QuoteLineItem[] lineItems = [select QuoteId,Product2Id,UnitPrice from QuoteLineItem where Id in :lineItemIds];
        for(QuoteLineItem lineItem : lineItems) {
            Quote quote = [select q.AccountId from Quote q where Id = :lineItem.QuoteId];
            Product2 product = [select External_Id__c from Product2 where Id = :lineItem.Product2Id];
            
            String productCode = product.External_Id__c;    
            
            Decimal price = GetPrice(productCode);
            
            if(price &amp;gt; 0)
            {
                lineItem.UnitPrice = price;
                changed = true;
            }    
        }
        
        if(changed) update lineItems;
    }
    
    private static Decimal GetPrice(String productCode) {
        String url = 'http://www.grupolanka.com/Salesforce/ErpApiService/api/Product?id=' + productCode;

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');
        HttpResponse res = h.send(req);
        
        return Decimal.valueOf(res.getBody());
    }
}
&lt;/pre&gt;&lt;p&gt;The callout to a REST service from a trigger follows the same principles we outlined in our previous article: it needs to be called from a class marked with the &lt;font face="Courier New"&gt;@future&lt;/font&gt; tag (for asynchronous call), it needs to be a static void method, and the trigger needs to be a &lt;font face="Courier New"&gt;after insert&lt;/font&gt; trigger.&lt;/p&gt;&lt;p&gt;You can now test the call by adding a new line item to an existing quote, Salesforce should call the REST service and assign the product price from the ERP to the line item.&lt;/p&gt;&lt;p&gt;You can get the sample code from here:&lt;/p&gt;&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%2111546&amp;amp;authkey=AONni6nqa7pJZl4" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/consuming-salesforce-data-using-the-rest-api-from-a-net-wcf-message-handler</id><title type="text">Consuming Salesforce Data using the REST API from a .NET WCF Message Handler</title><updated>2017-07-20T10:39:58Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/consuming-salesforce-data-using-the-rest-api-from-a-net-wcf-message-handler" /><content type="text">&lt;p align="right"&gt;(Puedes ver este artículo en español &lt;a href="http://www.grupolanka.com/obtener-datos-de-salesforce-usando-el-api-rest-desde-un-servicio-web-en-net/"&gt;aquí&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;In a previous article, &lt;a href="http://blog.giovannimodica.com/post/a-net-wcf-service-handler-for-salesforce-workflow-outbound-messages-that-calls-back-to-salesforce-using-soap-api"&gt;A .Net WCF Service Handler for Salesforce Workflow Outbound Messages that Calls Back to Salesforce using SOAP API&lt;/a&gt;, I explained how to create a .Net WCF service to handle an outbound message and how to get additional data from Salesforce using the SOAP API. In this article I use the same example but instead of using the SOAP API I will use the REST API. You might wonder why do I need to change my SOAP code to use REST instead, and the answer is simple: you might have the SOAP API disabled (because of the Salesforce edition you have) in your organization and only have the REST API available.&lt;/p&gt;&lt;p&gt;Allow me to refresh what we would like to accomplish: our client wants to integrate accounts in Salesforce with accounts in their ERP, so every time a new opportunity is marked as “Closed Won” in Salesforce the account is created on the ERP. I suggest you to read the &lt;a href="http://blog.giovannimodica.com/post/a-net-wcf-service-handler-for-salesforce-workflow-outbound-messages-that-calls-back-to-salesforce-using-soap-api"&gt;previous article&lt;/a&gt; which explains how to set things up for the workflow and the Visual Studio project to create the WCF service that handles the workflow outbound message.&lt;/p&gt;&lt;p&gt;Salesforce is able to expose its metadata as a REST service. As we did in the case of SOAP, we could use the REST API to query the account information, but this could be simplified by exposing an APEX class as a REST service. Salesforce makes this very simple. You can follow the steps explained in the &lt;a href="https://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#CSHID=apex_classes_restful_http.htm|StartTopic=Content%2Fapex_classes_restful_http.htm|SkinName=webhelp"&gt;Force.com Apex Code Developer's Guide&lt;/a&gt; for an overview on how to do this. In this article I will expose an APEX class as a REST service and then I will consume this service from our message handler created in .Net&lt;/p&gt;&lt;h2&gt;Exposing the REST Service in Salesforce&lt;/h2&gt;&lt;p&gt;This is actually very simple, all you need to do is open the Salesforce Developer Console and from the menu select “File-&amp;gt;New-&amp;gt;Apex Class”. Name it &lt;font face="Courier New"&gt;AccountRestService&lt;/font&gt; and replace the code with the following:&lt;/p&gt;&lt;pre class="brush: java; highlight: [1,3];"&gt;@RestResource(urlMapping='/Account/*')
global with sharing class AccountRestService {
    @HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        Account result = [SELECT Id, Name, BillingStreet, BillingCity, BillingState, BillingPostalCode FROM Account WHERE Id = :accountId];
        return result;
    }
}
&lt;/pre&gt;&lt;p&gt;Notice in line 1 that we use the special &lt;font face="Courier New"&gt;@RestResource&lt;/font&gt; to tell Salesforce that this is actually a REST service. In line 3 we specify that the &lt;font face="Courier New"&gt;doGet&lt;/font&gt; method will be called by HTTP GET. The URL for this service will be the following:&lt;/p&gt;&lt;pre&gt;https://{instanceName}.salesforce.com/services/apexrest/Account/{accountId}

&lt;/pre&gt;&lt;p&gt;The &lt;font face="Courier New"&gt;https://{instanceName}.salesforce.com/services/apexrest&lt;/font&gt; is the URL base address for all REST services, and the &lt;font face="Courier New"&gt;/Account/{accountId}&lt;/font&gt; is specified by our class definition in the &lt;font face="Courier New"&gt;urlMapping&lt;/font&gt; parameter of the &lt;font face="Courier New"&gt;@RestResource&lt;/font&gt; tag. For example you could use the following URL to get the details for a specific account:&lt;/p&gt;&lt;pre&gt;https://eu5.salesforce.com/services/apexrest/Account/00124000002uzps

&lt;/pre&gt;&lt;p&gt;There is one thing we haven’t considered yet: security. If you put the above URL into a browser you will get an &lt;font face="Courier New"&gt;INVALID_SESSION_ID&lt;/font&gt; error. If you read the documentation you will learn that the HTTP request issued against the REST service needs an &lt;font face="Courier New"&gt;Authorization&lt;/font&gt; HTTP header. You could create a connected app and use OAuth to call the login REST service and get a session id, but this is actually complex (I will explain it in a future article) but in our case, since we are calling this service from an outbound message handler, we already have the session id. Remember from the &lt;a href="http://blog.giovannimodica.com/post/a-net-wcf-service-handler-for-salesforce-workflow-outbound-messages-that-calls-back-to-salesforce-using-soap-api"&gt;previous article&lt;/a&gt; that we marked the outbound message to “Send Session ID”:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/93cc922e-1b39-4ced-846e-af06194081b1.jpg"&gt;&lt;img width="644" height="379" title="Outbound message" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Outbound message" src="http://blog.giovannimodica.com/posts/files/51b3c94c-7378-4dc9-bee6-2178c08540d9.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;So, all we need to do is to build the right HTTP request from our WCF message handler to call our REST service.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h2&gt;Calling the REST Service from Visual Studio&lt;/h2&gt;&lt;p&gt;Open the Visual Studio project you created in the &lt;a href="http://blog.giovannimodica.com/post/a-net-wcf-service-handler-for-salesforce-workflow-outbound-messages-that-calls-back-to-salesforce-using-soap-api"&gt;previous article&lt;/a&gt; (you can get a sample from &lt;a href="https://onedrive.live.com/redir.aspx?cid=0e2c2c34f932a441&amp;amp;resid=E2C2C34F932A441!11207&amp;amp;parId=E2C2C34F932A441!11206&amp;amp;authkey=!AAS6AdQFN74Dtik"&gt;here&lt;/a&gt;). We will use &lt;a href="http://restsharp.org/" target="_blank"&gt;RestSharp&lt;/a&gt; as our REST client to call the service. Using NuGet, add the &lt;a href="http://www.nuget.org/packages/RestSharp/" target="_blank"&gt;RestSharp package&lt;/a&gt; to your project. RestSharp can automatically transform the JSON text returned from a REST service to a strong typed object. Let’s create a model to encapsulate the data returned from the REST service: in Visual Studio, create a &lt;font face="Courier New"&gt;Model&lt;/font&gt; folder and add a class named &lt;font face="Courier New"&gt;Account&lt;/font&gt; to it. Replace the code with the following:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;namespace WorkflowNotificationServices.Model
{
    public class Account
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string AccountNumber { get; set; }
        public string BillingStreet { get; set; }
        public string BillingCity { get; set; }
        public string BillingState { get; set; }
        public string BillingPostalCode { get; set; }
        public string BillingCountry { get; set; }
    }
}
&lt;/pre&gt;&lt;p&gt;We have defined an account class that encapsulates the data from the account object in Salesforce. Notice that for simplicity we have named the properties the same as the object fields in Salesforce (you don’t have to name things the same, you could use &lt;a href="http://james.newtonking.com/json" target="_blank"&gt;JSON.Net&lt;/a&gt; to get around it, but is not a topic we would like to do in this article).&lt;/p&gt;&lt;p&gt;Now, open the file &lt;font face="Courier New"&gt;OpportunityNotificationService.svc.cs&lt;/font&gt; and change the method &lt;font face="Courier New"&gt;CreateAccount&lt;/font&gt; with the following code:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [6,7,8,9,10,12];"&gt;private bool CreateAccount(string url, string sessionId, WorkflowNotificationServices.Opportunity opportunity)
{
    int recordsAffected = 0;

    Uri uri = new Uri(url);
    RestClient restClient = new RestClient(new Uri(String.Format("https://{0}", uri.Host)));
    RestRequest request = new RestRequest("services/apexrest/Account/{id}");
    request.AddUrlSegment("id", opportunity.AccountId);
    request.AddHeader("Authorization", String.Format("Bearer {0}", sessionId));
    IRestResponse&amp;lt;Model.Account&amp;gt; response = restClient.Execute&amp;lt;Model.Account&amp;gt;(request);

    Model.Account account = response.Data;

    ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["ERP"];
    using (SqlConnection cn = new SqlConnection(connectionString.ConnectionString))
    {
        using (SqlCommand command = new SqlCommand("salesforce_crearCliente", cn))
        {
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add("@idSalesforce", SqlDbType.VarChar).Value = account.Id;
            command.Parameters.Add("@name", SqlDbType.VarChar).Value = account.Name;
            command.Parameters.Add("@number", SqlDbType.VarChar).Value = (object)account.AccountNumber ?? DBNull.Value;
            command.Parameters.Add("@address", SqlDbType.VarChar).Value = (object)account.BillingStreet ?? DBNull.Value;
            command.Parameters.Add("@city", SqlDbType.VarChar).Value = (object)account.BillingCity ?? DBNull.Value;
            command.Parameters.Add("@state", SqlDbType.VarChar).Value = (object)account.BillingState ?? DBNull.Value;
            command.Parameters.Add("@postalCode", SqlDbType.VarChar).Value = (object)account.BillingPostalCode ?? DBNull.Value;
            command.Parameters.Add("@country", SqlDbType.VarChar).Value = (object)account.BillingCountry ?? DBNull.Value;

            cn.Open();
            recordsAffected = command.ExecuteNonQuery();
        }
    }

    return recordsAffected &amp;gt; 0;
}
&lt;/pre&gt;&lt;p&gt;The lines highlighted are the important ones. Notice in line 6 how we use the URL we got from the SOAP message sent by Salesforce to our WCF service and we get the host (and thus the instance name) we need to send the HTTP request to. In line 7 we create an HTTP request using RestSharp and specify the endpoint of our REST service, as explained before. In line 8 we specify the account Id we got from the SOAP of the outbound message on opportunity. In line 9 we set the security part we need to make this work. We need to set the &lt;font face="Courier New"&gt;Authorization&lt;/font&gt; header to the value &lt;font face="Courier New"&gt;Bearer {sessionId}&lt;/font&gt;&lt;font face="Segoe UI"&gt;. The session id we get it again from the SOAP of the outbound message sent by Salesforce (remember we marked the “Send session ID” field in the outbound message definition). Finally, in line 12 we make the HTTP call and tell RestSharp to convert the result to our &lt;font face="Courier New"&gt;Account&lt;/font&gt; object we created before. The rest of the code is just the same, using the values returned by the REST service (now strongly typed into a class) to call a stored procedure on the ERP.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h2&gt;Testing the Call Back&lt;/h2&gt;&lt;p&gt;To test our web service we just follow the same steps outlined in the previous article. Notice that we only changed the API used to obtain data from Salesforce: we were using SOAP before and now we use REST&lt;/p&gt;&lt;p&gt;You can get the sample project here:&lt;/p&gt;&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%2111547&amp;amp;authkey=AJPbRmp8y8s1HR8" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/call-a-net-wcf-service-from-salesforce</id><title type="text">Call a .Net WCF Service from Salesforce</title><updated>2017-08-08T14:19:33Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/call-a-net-wcf-service-from-salesforce" /><content type="text">&lt;p align="right"&gt;&lt;font size="2"&gt;(Puedes ver este artículo en español &lt;/font&gt;&lt;a href="http://www.grupolanka.com/llamada-un-servicio-web-wcf-de-net-desde-salesforce/" target="_blank"&gt;&lt;font size="2"&gt;aquí&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;)&lt;/font&gt;&lt;/p&gt;&lt;p&gt;In the web you can find information on how to call a web service from Salesforce, but there is little information on how to call web service created in .Net. The examples you find are based on asmx web services mostly. In this article I will explain how to call a .Net WCF web service created with &lt;a href="http://www.visualstudio.com"&gt;Visual Studio 2013 Community&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;To make things more exciting I will call this web service from a trigger and explain how to code things in Salesforce to make this possible.&lt;/p&gt;&lt;h2&gt;The WCF Service&lt;/h2&gt;&lt;p&gt;Let’s start by creating the web service. We will simulate the following scenario: when we create a quote in Salesforce and add products to it we want the product price to be dynamically assigned by the ERP and not by Salesforce (Salesforce manages Price Books for this, but we don’t want this in this example).&lt;/p&gt;&lt;p&gt;Start Visual Studio and create a new empty ASP.Net Web Application and call it &lt;font face="Courier New"&gt;ErpService&lt;/font&gt;. Add a WCF Service to it and call it &lt;font face="Courier New"&gt;ProductService.svc&lt;/font&gt;. Visual Studio will add the required assemblies to the project and create three files: &lt;font face="Courier New"&gt;IProductService.cs&lt;/font&gt;, &lt;font face="Courier New"&gt;ProductService.svc&lt;/font&gt; and &lt;font face="Courier New"&gt;ProductService.svc.cs&lt;/font&gt;. &lt;/p&gt;&lt;p&gt;Modify your &lt;font face="Courier New"&gt;web.config&lt;/font&gt; file to add the service definition:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;connectionStrings&amp;gt;
        &amp;lt;add name="ERP" connectionString="Data Source=localhost;Initial Catalog=ERP;Integrated Security=True" providerName="System.Data.SqlClient"/&amp;gt;
    &amp;lt;/connectionStrings&amp;gt;
    &amp;lt;system.web&amp;gt;
        &amp;lt;webServices&amp;gt;
            &amp;lt;protocols&amp;gt;
                &amp;lt;clear/&amp;gt;
                &amp;lt;add name="HttpSoap" /&amp;gt;
                &amp;lt;add name="Documentation"/&amp;gt;
            &amp;lt;/protocols&amp;gt;
        &amp;lt;/webServices&amp;gt;
        &amp;lt;compilation debug="true" targetFramework="4.5" /&amp;gt;
        &amp;lt;httpRuntime targetFramework="4.5" /&amp;gt;
    &amp;lt;/system.web&amp;gt;
    &amp;lt;system.serviceModel&amp;gt;
        &amp;lt;services&amp;gt;
            &amp;lt;service name="ErpService.ProductService"&amp;gt;
                &amp;lt;endpoint binding="basicHttpBinding" name="Product" contract="ErpService.IProductService"/&amp;gt;
            &amp;lt;/service&amp;gt;
        &amp;lt;/services&amp;gt;
        &amp;lt;behaviors&amp;gt;
            &amp;lt;serviceBehaviors&amp;gt;
                &amp;lt;behavior name=""&amp;gt;
                    &amp;lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /&amp;gt;
                    &amp;lt;serviceDebug includeExceptionDetailInFaults="false" /&amp;gt;
                &amp;lt;/behavior&amp;gt;
            &amp;lt;/serviceBehaviors&amp;gt;
        &amp;lt;/behaviors&amp;gt;
        &amp;lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /&amp;gt;
    &amp;lt;/system.serviceModel&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;&lt;p&gt;Open &lt;font face="Courier New"&gt;IProductService.cs&lt;/font&gt; and replace it with the following code:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ErpService
{
    [ServiceContract]
    public interface IProductService
    {
        [OperationContract]
        decimal GetPriceForCustomer(string productId);
    }
}
&lt;/pre&gt;&lt;p&gt;Our web service exposes just one method to get the price of a product given its Id. Open &lt;font face="Courier New"&gt;ProductService.svc.cs&lt;/font&gt; and replace it with the following code:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ErpService
{
    public class ProductService : IProductService
    {
        public decimal GetPriceForCustomer(string productId)
        {
            try
            {
                ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["ERP"];
                using (SqlConnection cn = new SqlConnection(connectionString.ConnectionString))
                {
                    using (SqlCommand command = new SqlCommand("salesforce_getProductPrice", cn))
                    {
                        command.CommandType = CommandType.StoredProcedure;

                        command.Parameters.Add("@productId", SqlDbType.VarChar).Value = (object)productId ?? DBNull.Value;
                        SqlParameter priceParameter = command.Parameters.Add("@price", SqlDbType.Money);
                        priceParameter.Direction = ParameterDirection.Output;

                        cn.Open();
                        command.ExecuteNonQuery();

                        return (decimal)command.Parameters["@price"].Value;
                    }
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.Message);
                return 0;
            }
        }
    }
}
&lt;/pre&gt;&lt;p&gt;The implementation of our web service is pretty straightforward: it uses ADO.Net to connect to our ERP (a SQLServer database) and call a stored procedure passing the id of the product.&lt;/p&gt;&lt;p&gt;Our web service is ready. You need to publish this web service on the internet for Salesforce to see. The publication is outside the scope of this article. In my case I published it on an IIS server in our DMZ and the URL to reach it is: http://www.grupolanka.com/Salesforce/ErpService/ProductService.svc (don’t try it, it won’t work).&lt;/p&gt;&lt;p&gt;We need the WSDL for the web service. Go to the web service and click on the link for the singleWsdl:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/d079d588-72b6-406f-b552-e9845ef8efd2.jpg"&gt;&lt;img width="538" height="484" title="Web service" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Web service" src="http://blog.giovannimodica.com/posts/files/8ddcc467-d422-4504-a2e0-bb99313cd930.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I saved the WSDL locally with the name of &lt;font face="Courier New"&gt;productService.wsdl&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;Now that we have our web service, let’s go back to Salesforce to create a class to call it.&lt;/p&gt;&lt;h2&gt;Adding the Web Service in Salesforce&lt;/h2&gt;&lt;p&gt;In Salesforce go to “Setup-&amp;gt;Build-&amp;gt;Develop-&amp;gt;Apex Classes”, and click on the button “Generate from WSDL”. Salesforce will ask you for the WSDL file. Click on the “Choose File” button and select the &lt;font face="Courier New"&gt;productService.wsdl&lt;/font&gt; file and then click on “Parse WSDL”. You will get the following error:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/1c613b18-fdc5-41dd-afcf-1efc9b1fcf33.jpg"&gt;&lt;img width="644" height="208" title="Parse WSDL error" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Parse WSDL error" src="http://blog.giovannimodica.com/posts/files/b3ed5b77-afb5-4479-bc55-216fdd748e30.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Here comes the tricky part, we need to modify our WSDL for Salesforce to parse it without errors. Using an XML editor (I use &lt;a href="https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0CB0QFjAA&amp;amp;url=http%3A%2F%2Fnotepad-plus-plus.org%2F&amp;amp;ei=3cKiVNHkIoOqU57qgrgL&amp;amp;usg=AFQjCNH20Y39KL3umNlz40yN398ALm0wKg&amp;amp;sig2=P24d5QmRQry1RQAwiooa1w&amp;amp;bvm=bv.82001339,d.d24"&gt;Notepad++&lt;/a&gt; with the &lt;a href="http://sourceforge.net/projects/npp-plugins/files/XML%20Tools/"&gt;XML tools plugin&lt;/a&gt;), locate and remove the following chunck of XML:&lt;/p&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/"&amp;gt;
            &amp;lt;xs:element name="anyType" nillable="true" type="xs:anyType"/&amp;gt;
            &amp;lt;xs:element name="anyURI" nillable="true" type="xs:anyURI"/&amp;gt;
            &amp;lt;xs:element name="base64Binary" nillable="true" type="xs:base64Binary"/&amp;gt;
            &amp;lt;xs:element name="boolean" nillable="true" type="xs:boolean"/&amp;gt;
            &amp;lt;xs:element name="byte" nillable="true" type="xs:byte"/&amp;gt;
            &amp;lt;xs:element name="dateTime" nillable="true" type="xs:dateTime"/&amp;gt;
            &amp;lt;xs:element name="decimal" nillable="true" type="xs:decimal"/&amp;gt;
            &amp;lt;xs:element name="double" nillable="true" type="xs:double"/&amp;gt;
            &amp;lt;xs:element name="float" nillable="true" type="xs:float"/&amp;gt;
            &amp;lt;xs:element name="int" nillable="true" type="xs:int"/&amp;gt;
            &amp;lt;xs:element name="long" nillable="true" type="xs:long"/&amp;gt;
            &amp;lt;xs:element name="QName" nillable="true" type="xs:QName"/&amp;gt;
            &amp;lt;xs:element name="short" nillable="true" type="xs:short"/&amp;gt;
            &amp;lt;xs:element name="string" nillable="true" type="xs:string"/&amp;gt;
            &amp;lt;xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte"/&amp;gt;
            &amp;lt;xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt"/&amp;gt;
            &amp;lt;xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong"/&amp;gt;
            &amp;lt;xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort"/&amp;gt;
            &amp;lt;xs:element name="char" nillable="true" type="tns:char"/&amp;gt;
            &amp;lt;xs:simpleType name="char"&amp;gt;
                &amp;lt;xs:restriction base="xs:int"/&amp;gt;
            &amp;lt;/xs:simpleType&amp;gt;
            &amp;lt;xs:element name="duration" nillable="true" type="tns:duration"/&amp;gt;
            &amp;lt;xs:simpleType name="duration"&amp;gt;
                &amp;lt;xs:restriction base="xs:duration"&amp;gt;
                    &amp;lt;xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?"/&amp;gt;
                    &amp;lt;xs:minInclusive value="-P10675199DT2H48M5.4775808S"/&amp;gt;
                    &amp;lt;xs:maxInclusive value="P10675199DT2H48M5.4775807S"/&amp;gt;
                &amp;lt;/xs:restriction&amp;gt;
            &amp;lt;/xs:simpleType&amp;gt;
            &amp;lt;xs:element name="guid" nillable="true" type="tns:guid"/&amp;gt;
            &amp;lt;xs:simpleType name="guid"&amp;gt;
                &amp;lt;xs:restriction base="xs:string"&amp;gt;
                    &amp;lt;xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"/&amp;gt;
                &amp;lt;/xs:restriction&amp;gt;
            &amp;lt;/xs:simpleType&amp;gt;
            &amp;lt;xs:attribute name="FactoryType" type="xs:QName"/&amp;gt;
            &amp;lt;xs:attribute name="Id" type="xs:ID"/&amp;gt;
            &amp;lt;xs:attribute name="Ref" type="xs:IDREF"/&amp;gt;
        &amp;lt;/xs:schema&amp;gt;
&lt;/pre&gt;&lt;p&gt;This seems to confuse the Salesforce parser so we will remove it (don’t worry, it will work even without this). Save the WSDL and try to parse it wit Salesforce again. Now you should get something like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/537244c4-01f5-47fb-8184-4f5098ecb0ad.jpg"&gt;&lt;img width="644" height="224" title="Parsed WSDL" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Parsed WSDL" src="http://blog.giovannimodica.com/posts/files/8349b0ac-73f2-4e7b-913d-5728aa22198c.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Specify a valid name for the Apex Class (I used &lt;font face="Courier New"&gt;ProductService&lt;/font&gt; as the class name). Click on “Generate Apex code” button. Salesforce should create the apex class with no errors. Now let’s test it before we continue. Open the Developer Console and press &lt;font face="Courier New"&gt;Crtl+E&lt;/font&gt; to open the Execute Anonymous window. Enter the following code:&lt;/p&gt;&lt;pre class="brush: java;"&gt;ProductService.Product productService = new ProductService.Product();
Decimal price = productService.GetPrice('PADAP20001');
system.debug(price);
&lt;/pre&gt;&lt;p&gt;We’re calling our web service and if you open the log and watch for debug messages you should see the price we got back from the ERP.&lt;/p&gt;&lt;h2&gt;Creating the Trigger with a Web Service Callback&lt;/h2&gt;&lt;p&gt;Now we now that Salesforce can call our web service. Having a trigger to call it might not be obvious. Although you can find information on the web on how to do this, I will explain it here for completeness.&lt;/p&gt;&lt;p&gt;A trigger cannot directly call a web service. This is a way for Salesforce to guarantee that a trigger will not get stuck in some external call (for which they’re not responsible) and thus compromise the execution of the trigger. To avoid this a trigger can call a web service in an asynchronous way. For a trigger to call a web service you need to create a class with a static method marked with the special &lt;font face="Courier New"&gt;@future&lt;/font&gt; tag. Using the Developer Console in Salesforce, create a new Apex Class and call it &lt;font face="Courier New"&gt;QuoteLineItemProcesses&lt;/font&gt;. Enter the following code:&lt;/p&gt;&lt;pre class="brush: java; highlight: [2,12,13];"&gt;global with sharing class QuoteLineItemProcesses {
    @future (callout = true)
    public static void updateLinePrice(List&amp;lt;Id&amp;gt; lineItemIds) {
        Boolean changed = false;
        
        QuoteLineItem[] lineItems = [select QuoteId,Product2Id,UnitPrice from QuoteLineItem where Id in :lineItemIds];
        for(QuoteLineItem lineItem : lineItems) {
            Product2 product = [select ProductCode from Product2 where Id = :lineItem.Product2Id];
            
            String productCode = product.ProductCode;    
            
            ProductService.Product productService = new ProductService.Product();
            Decimal price = productService.GetPrice(productCode);
            
            if(price &amp;gt; 0)
            {
                lineItem.UnitPrice = price;
                changed = true;
            }    
        }
        
        if(changed) update lineItems;
    }        
}
&lt;/pre&gt;&lt;p&gt;Notice line 2 where we specify the &lt;font face="Courier New"&gt;@future&lt;/font&gt; tag for the method and we tell that the method will do a callout. The method needs to be a &lt;font face="Courier New"&gt;static void&lt;/font&gt; method. Lines 12 and 13 are doing the callout (just as we did when testing the web service). The method takes a list of Ids as a parameter, corresponding to the Ids that are being processed in the trigger. For each Id we get the line item and the product code for the line and then do the callout.&lt;/p&gt;&lt;p&gt;For the trigger, create a new trigger associated to &lt;font face="Courier New"&gt;QuoteLineItem&lt;/font&gt; and call it &lt;font face="Courier New"&gt;OnQuoteLineItemAdded&lt;/font&gt;:&lt;/p&gt;&lt;pre class="brush: java;"&gt;trigger OnQuoteLineItemAdded on QuoteLineItem (after insert) {
    List&amp;lt;Id&amp;gt; quoteLineItemIds = new List&amp;lt;Id&amp;gt;();

    for (QuoteLineItem quoteLineItem: Trigger.new) {
        quoteLineItemIds.add(quoteLineItem.Id);
    }
    
    if (quoteLineItemIds.size() &amp;gt; 0) {
        QuoteLineItemProcesses.updateLinePrice(quoteLineItemIds);
    }        
}
&lt;/pre&gt;&lt;p&gt;The trigger needs to be an &lt;font face="Courier New"&gt;after insert&lt;/font&gt; trigger since we need the Id of the record in order to do the asynchronous update after the callout. Notice how we use the best practices to process batch records. We create an array of Ids and pass it to the class we created above.&lt;/p&gt;&lt;p&gt;And this is it! we are now ready to test it: create an opportunity and add a quote to it, then add a line item to the quote. After adding the line, refresh the quote (remember that it is asynchronous) you should now see the price from the ERP.&lt;/p&gt;&lt;p&gt;Here you can find the project I used to create the web service:&lt;/p&gt;&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%2111211&amp;amp;authkey=AO7alWSID0JLPnI" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/a-net-wcf-service-handler-for-salesforce-workflow-outbound-messages-that-calls-back-to-salesforce-using-soap-api</id><title type="text">A .Net WCF Service Handler for Salesforce Workflow Outbound Messages that Calls Back to Salesforce using SOAP API</title><updated>2015-03-03T07:16:50Z</updated><author><name /></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/a-net-wcf-service-handler-for-salesforce-workflow-outbound-messages-that-calls-back-to-salesforce-using-soap-api" /><content type="text">&lt;p align="right"&gt;&lt;font size="2"&gt;(Puedes ver este artículo en español &lt;a href="http://www.grupolanka.com/uso-de-servicios-wcf-en-net-para-procesar-los-mensajes-de-los-flujos-de-trabajo-de-salesforce/" target="_blank"&gt;aquí&lt;/a&gt;)&lt;/font&gt;&lt;/p&gt;&lt;p&gt;In a previous post &lt;a title="Salesforce Workflow Outbound Messages Handled in .Net with WCF" href="http://blog.giovannimodica.com/post/salesforce-workflow-outbound-messages-handled-in-net-with-wcf"&gt;Salesforce Workflow Outbound Messages Handled in .Net with WCF&lt;/a&gt; I explained how to create a .Net WCF service to handle workflow outbound messages from Salesforce. In this article I will add a twist to it by making the web service call back to Salesforce to retrieve additional data.&lt;/p&gt;&lt;h2&gt;The Requirements&lt;/h2&gt;&lt;p&gt;Allow me to explain the concepts by using a concrete example: one of our client required to integrate their Salesforce org with their ERP. The integration is based on the following rule:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Accounts (creations and modifications) are maintained in Salesforce&lt;/li&gt;&lt;li&gt;Accounts will be created in the ERP only when an opportunity associated with the account is won&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The above rules translate to the following&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We can create a workflow on opportunity that triggers only when the stage of the opportunity is “Closed Won”&lt;/li&gt;&lt;li&gt;The workflow will have an outbound message that calls a web service in the ERP&lt;/li&gt;&lt;li&gt;Since the outbound message can only send fields of the object it is based on, we cannot send account fields using an outbound message for the opportunity. We can send the account Id (a field in the opportunity) and then have the web service in the ERP to connect back to Salesforce and retrieve the account fields using the account Id.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let’s dive into code!&lt;/p&gt;&lt;h2&gt;The Workflow Outbound Message&lt;/h2&gt;&lt;p&gt;Let’s start with the workflow definition. I won’t provide too many details on how to create the workflow since I already talked about this in the article &lt;a title="Salesforce Workflow Outbound Messages Handled in .Net with WCF" href="http://blog.giovannimodica.com/post/salesforce-workflow-outbound-messages-handled-in-net-with-wcf"&gt;Salesforce Workflow Outbound Messages Handled in .Net with WCF&lt;/a&gt; (please read this first if you need more details).&lt;/p&gt;&lt;p&gt;In Salesforce go to “Worflow &amp;amp; Approvals” and create a new workflow rule based on the &lt;font face="Courier New"&gt;Opportunity&lt;/font&gt; object. Give it a name (I called &lt;font face="Courier New"&gt;CreateAccountOnERP&lt;/font&gt;) and make sure that the evaluation criteria is set to “created, and any time it’s edited to subsequently meet criteria”. We want this option since we only want to call the web service if the opportunity stage is “Closed Won”. Now specify the rule criteria and make sure that both “&lt;font face="Courier New"&gt;Opportunity : Closed&lt;/font&gt;” and “&lt;font face="Courier New"&gt;Opportunity : Won&lt;/font&gt;” fields are true. Your workflow rule should&amp;nbsp; look like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/0023ae9c-7b70-4885-a561-9d153a9201c2.jpg"&gt;&lt;img width="621" height="484" title="Opportunity workflow rule" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Opportunity workflow rule" src="http://blog.giovannimodica.com/posts/files/2267403b-12b5-47a1-ac5a-90286c975487.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Now, add an outbound message action to the workflow. When creating the outbound message, make sure you mark “Send Session Id” (I will explain this later), and also to include the &lt;font face="Courier New"&gt;AccountId&lt;/font&gt; field as the fields to send. We still don’t have the web service url so put anything in the “Endpoint URL” field:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/129213c6-4c87-4724-8433-208e7034038a.jpg"&gt;&lt;img width="617" height="484" title="Opportunity outbound message" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Opportunity outbound message" src="http://blog.giovannimodica.com/posts/files/23b0381f-67df-472d-9654-9eb181f98dbd.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Web Service in Visual Studio (using WCF)&lt;/h2&gt;&lt;p&gt;Now, get the WSDL for the outbound message and save it locally on disk (I named the file &lt;font face="Courier New"&gt;opportunityWorkflowOutboundMessage.wsdl&lt;/font&gt;), we will use this later to create our service definition inside Visual Studio.&lt;/p&gt;&lt;p&gt;In Visual Studio, create a new empty ASP.Net Web Application and name it &lt;font face="Courier New"&gt;WorkflowNotificationServices&lt;/font&gt; (the following steps are basically the same explained in the article &lt;a title="Salesforce Workflow Outbound Messages Handled in .Net with WCF" href="http://blog.giovannimodica.com/post/salesforce-workflow-outbound-messages-handled-in-net-with-wcf"&gt;Salesforce Workflow Outbound Messages Handled in .Net with WCF&lt;/a&gt;). Add the WSDL to the project. Add a new “WCF Service” to the project and name it &lt;font face="Courier New"&gt;OpportunityNotificationService.svc&lt;/font&gt;. Visual Studio will add three files to your project: &lt;font face="Courier New"&gt;IOpportunityNotificationService.cs&lt;/font&gt;, &lt;font face="Courier New"&gt;OpportunityNotificationService.svc&lt;/font&gt; and the implementation &lt;font face="Courier New"&gt;OpportunityNotificationService.svc.cs&lt;/font&gt;.&lt;/p&gt;&lt;p&gt;Now open a command prompt (if you have the &lt;a href="https://visualstudiogallery.msdn.microsoft.com/dbcb8670-889e-4a54-a226-a48a15e4cace?SRC=VSIDE"&gt;Productivity Power Tools&lt;/a&gt; extension you can right click on the project in Solution Explorer and choose “Power Commands-&amp;gt;Open Command Prompt”) and type the following:&lt;/p&gt;&lt;pre&gt;svcutil /noconfig /out:IOpportunityNotificationService.cs opportunityWorkflowOutboundMessage.wsdl
&lt;/pre&gt;&lt;p&gt;Open the &lt;font face="Courier New"&gt;IOpportunityNotificationService.cs&lt;/font&gt; file and make sure you make these changes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Put the whole class inside the namespace of the project (in my case is the name of the project &lt;font face="Courier New"&gt;WorkflowNotificationServices&lt;/font&gt;)&lt;li&gt;Change the name of the interface from &lt;font face="Courier New"&gt;NotificationPort&lt;/font&gt; to &lt;font face="Courier New"&gt;IOpportunityNotificationService&lt;/font&gt;. &lt;li&gt;Change the &lt;font face="Courier New"&gt;ConfigurationName&lt;/font&gt; parameter of the &lt;font face="Courier New"&gt;ServiceContractAttribute&lt;/font&gt; attribute from &lt;font face="Courier New"&gt;NotificationPort&lt;/font&gt; to &lt;font face="Courier New"&gt;OpportunityNotificationService&lt;/font&gt;. &lt;li&gt;Remove the parameter &lt;font face="Courier New"&gt;ReplyAction=”*”&lt;/font&gt; from the &lt;font face="Courier New"&gt;OperationContractAttribute&lt;/font&gt; attribute.
&lt;li&gt;At the end of the file, remove the interface &lt;font face="Courier New"&gt;NotificationPortChannel&lt;/font&gt; and the class &lt;font face="Courier New"&gt;NotificationPortClient&lt;/font&gt; (we don’t need these since they are used by a client consuming the web service). &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The interface should now look as the following (highlighted lines are the one that changed):&lt;pre class="brush: csharp; highlight: [1,4,5,7];"&gt;namespace WorkflowNotificationServices
{
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://soap.sforce.com/2005/09/outbound", ConfigurationName = "OpportunityNotificationService")]
    public interface IOpportunityNotificationService
    {
        [System.ServiceModel.OperationContractAttribute(Action = "")]
        [System.ServiceModel.XmlSerializerFormatAttribute()]
        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(sObject))]
        notificationsResponse1 notifications(notificationsRequest request);
    }

    /// rest of the code below
}
&lt;/pre&gt;&lt;p&gt;Next, open the file &lt;font face="Courier New"&gt;OpportunityNotificationService.svc.cs&lt;/font&gt;, remove the &lt;font face="Courier New"&gt;DoWork&lt;/font&gt; method and implement the &lt;font face="Courier New"&gt;IOpportunityNotificationService&lt;/font&gt; interface (place the cursor on text for the name of the interface and press &lt;font face="Courier New"&gt;Crtl+.&lt;/font&gt; and choose “Implement interface IOpportunityNotificationService”).&lt;/p&gt;&lt;p&gt;And finally, edit the &lt;font face="Courier New"&gt;web.config&lt;/font&gt; and replace it with the following:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;connectionStrings&amp;gt;
        &amp;lt;add name="ERP" connectionString="Data Source=localhost;Initial Catalog=Hiperantena;Integrated Security=True" providerName="System.Data.SqlClient"/&amp;gt;
    &amp;lt;/connectionStrings&amp;gt;
    &amp;lt;system.web&amp;gt;
        &amp;lt;compilation debug="true" targetFramework="4.5" /&amp;gt;
        &amp;lt;httpRuntime targetFramework="4.5" /&amp;gt;
        &amp;lt;webServices&amp;gt;
            &amp;lt;protocols&amp;gt;
                &amp;lt;clear/&amp;gt;
                &amp;lt;add name="HttpSoap" /&amp;gt;
                &amp;lt;add name="Documentation"/&amp;gt;
            &amp;lt;/protocols&amp;gt;
        &amp;lt;/webServices&amp;gt;
    &amp;lt;/system.web&amp;gt;
    &amp;lt;system.serviceModel&amp;gt;
        &amp;lt;services&amp;gt;
            &amp;lt;service name="WorkflowNotificationServices.OpportunityNotificationService"&amp;gt;
                &amp;lt;endpoint binding="basicHttpBinding" contract="OpportunityNotificationService"/&amp;gt;
            &amp;lt;/service&amp;gt;
        &amp;lt;/services&amp;gt;
        &amp;lt;behaviors&amp;gt;
            &amp;lt;serviceBehaviors&amp;gt;
                &amp;lt;behavior name=""&amp;gt;
                    &amp;lt;serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /&amp;gt;
                    &amp;lt;serviceDebug includeExceptionDetailInFaults="false" /&amp;gt;
                &amp;lt;/behavior&amp;gt;
            &amp;lt;/serviceBehaviors&amp;gt;
        &amp;lt;/behaviors&amp;gt;
        &amp;lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /&amp;gt;
    &amp;lt;/system.serviceModel&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;&lt;p&gt;The project should compile at this point and if we run it we should be able to get the WSDL for this web service.&lt;/p&gt;&lt;h2&gt;The Call Back to Salesforce&lt;/h2&gt;&lt;p&gt;The outbound message we defined earlier for the opportunity will send two important pieces of information: the id of the account, and the session id. We will use these to connect to Salesforce and get the data for the account that is required in the ERP. For this we will use the Salesforce SOAP API.&lt;/p&gt;&lt;p&gt;Go back to Salesforce, and go to “Setup-&amp;gt;Build-&amp;gt;Develop-&amp;gt;API”, you will get the API WSDL screen:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/8511d7f7-991c-4f62-8692-6dd2a3fefad1.jpg"&gt;&lt;img width="644" height="258" title="Salesforce API" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Salesforce API" src="http://blog.giovannimodica.com/posts/files/9399c80e-4963-4bd5-8f69-687dd7c0dfdc.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We need to get the Enterprise WSDL (for a difference between Enterprise and Partner WSDL see this &lt;a href="https://help.salesforce.com/apex/HTViewSolution?id=000004760&amp;amp;language=en_US"&gt;article&lt;/a&gt;). Save the WSDL on disk (I named it &lt;font face="Courier New"&gt;enterprise.wsdl&lt;/font&gt;) and add it to your Visual Studio project. We will create a proxy for this WSDL using Visual Studio.&lt;/p&gt;&lt;p&gt;In the Solution Explorer, right click the References node and choose “Add Service Reference”. Specify the full path to the enterprise WSDL and click Go. Make sure you specify &lt;font face="Courier New"&gt;Salesforce&lt;/font&gt; as the namespace:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/35f37577-cb0b-41b9-b7a9-685cbbeac6a1.jpg"&gt;&lt;img width="424" height="343" title="Add service reference" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Add service reference" src="http://blog.giovannimodica.com/posts/files/0eb6b1e1-37ab-4202-8279-fffbec4e46b6.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Click OK. Visual Studio will create the proxy to call the Salesforce SOAP API and make the required modifications in &lt;font face="Courier New"&gt;web.config&lt;/font&gt;. Open the &lt;font face="Courier New"&gt;OpportunityNotificationService.cs&lt;/font&gt; file and replace the code with the following:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [24,25,54,55,56,58,61];"&gt;using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using WorkflowNotificationServices.Salesforce;

namespace WorkflowNotificationServices
{
    public class OpportunityNotificationService : IOpportunityNotificationService
    {

        public notificationsResponse1 notifications(notificationsRequest request)
        {
            bool result = true;

            notifications notifications1 = request.notifications;

            string sessionId = notifications1.SessionId;
            string url = notifications1.EnterpriseUrl;

            OpportunityNotification[] opportunityNotifications = notifications1.Notification;
            foreach (OpportunityNotification opportunityNotification in opportunityNotifications)
            {
                WorkflowNotificationServices.Opportunity opportunity = (WorkflowNotificationServices.Opportunity)opportunityNotification.sObject;

                try
                {
                    if (!CreateAccount(url, sessionId, opportunity))
                        result = false;
                }
                catch (Exception e)
                {
                    Trace.TraceError(e.Message);
                    result = false;
                }
            }

            notificationsResponse response = new notificationsResponse();
            response.Ack = result;

            return new notificationsResponse1() { notificationsResponse = response };
        }

        private bool CreateAccount(string url, string sessionId, WorkflowNotificationServices.Opportunity opportunity)
        {
            int recordsAffected = 0;

            EndpointAddress address = new EndpointAddress(url);
            SoapClient soapClient = new SoapClient("Soap", address);
            SessionHeader session = new SessionHeader() { sessionId = sessionId };

            string query = String.Format("select Id, Name, AccountNumber, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry from account where id = '{0}'", opportunity.AccountId);

            QueryResult result;
            soapClient.query(session, null, null, null, query, out result);

            if (result.size &amp;gt; 0)
            {
                Account account = result.records[0] as Account;

                ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["ERP"];
                using (SqlConnection cn = new SqlConnection(connectionString.ConnectionString))
                {
                    using (SqlCommand command = new SqlCommand("salesforce_createAccount", cn))
                    {
                        command.CommandType = CommandType.StoredProcedure;

                        command.Parameters.Add("@idSalesforce", SqlDbType.VarChar).Value = account.Id;
                        command.Parameters.Add("@name", SqlDbType.VarChar).Value = account.Name;
                        command.Parameters.Add("@number", SqlDbType.VarChar).Value = (object)account.AccountNumber ?? DBNull.Value;
                        command.Parameters.Add("@address", SqlDbType.VarChar).Value = (object)account.BillingStreet ?? DBNull.Value;
                        command.Parameters.Add("@city", SqlDbType.VarChar).Value = (object)account.BillingCity ?? DBNull.Value;
                        command.Parameters.Add("@state", SqlDbType.VarChar).Value = (object)account.BillingState ?? DBNull.Value;
                        command.Parameters.Add("@postalCode", SqlDbType.VarChar).Value = (object)account.BillingPostalCode ?? DBNull.Value;
                        command.Parameters.Add("@country", SqlDbType.VarChar).Value = (object)account.BillingCountry ?? DBNull.Value;

                        cn.Open();
                        recordsAffected = command.ExecuteNonQuery();
                    }
                }

            }

            return recordsAffected &amp;gt; 0;
        }
    }
}
&lt;/pre&gt;&lt;p&gt;There are a few important things here to notice: In lines 24 and 25 we get the session id and the url that comes from the outbound message from Salesforce. These two parameters are needed to connect back to Salesforce. Remember that when we created the outbound message in Salesforce we marked the “Send Session ID” field. We use this information in lines 54-56 to create a &lt;font face="Courier New"&gt;SessionHeader&lt;/font&gt; object. In line 58 we build a SOQL query to get the information from account and we use the &lt;font face="Courier New"&gt;AccountId&lt;/font&gt; field sent in the outbound message. We then use the session header in line 61 to send the query to Salesforce. The rest of the code just process the information we got back from Salesforce and we send this to the ERP (in this example I’m calling a SQLServer stored procedure to simulate the ERP).&lt;/p&gt;&lt;h2&gt;Testing the Call Back&lt;/h2&gt;&lt;p&gt;We need to publish our web service and make it available on the internet. The publishing is outside of the scope of this article. In my case I published it on an IIS server in our DMZ, and the public url is &lt;font face="Courier New"&gt;http://www.grupolanka.com/Salesforce/WorkflowNotificationServices/OpportunityNotificationService.svc&lt;/font&gt; (don’t try it, it won’t work).&lt;p&gt;Now we need to go back to Salesforce and change the url of the outbound message we created earlier. Edit the outbound message definition (in the example is &lt;font face="Courier New"&gt;SendOportunityToERP&lt;/font&gt;) and edit the “Endpoint URL” field with the URL.&lt;p&gt;Now, create a new account and create an opportunity. Change the stage of the opportunity to “Closed Won” and save it. Salesforce will trigger the workflow and call the web service we defined, and this will call back to Salesforce to retrieve the information from the account.&lt;p&gt;You can get the sample project here:&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%2111207&amp;amp;authkey=AAS6AdQFN74Dtik" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;</content></entry><entry><id>http://bloggiovannimodica.azurewebsites.net/post/how-to-use-multilingual-app-toolkit-in-universal-apps</id><title type="text">How to use Multilingual App Toolkit in Universal Apps</title><updated>2016-04-27T05:38:56Z</updated><author><name>Giovanni Modica</name></author><link rel="alternate" href="http://bloggiovannimodica.azurewebsites.net/post/how-to-use-multilingual-app-toolkit-in-universal-apps" /><content type="text">&lt;p&gt;Everyone is excited about the new Universal Apps. I can now have a new type of project, called a Shared project, where I can put all the common files shared between a Windows 8.1 and Windows Phone 8.1 project. This is a better way around the “Add as a Link” option we had before. But universal apps is more than just a shared project. It seems that the APIs used by both Windows and Windows Phone are converging into one. Granted there still a lot of work to do and I’m not sure if there will be a 100% compatibility between the two frameworks, but this is a great step.&lt;/p&gt;&lt;p&gt;I’m going to talk about how to localize a universal app. In my article &lt;a href="http://blog.giovannimodica.com/post/internationalization-of-a-cross-platform-application"&gt;Internationalization of a Cross Platform Application&lt;/a&gt; I explain how to use the Multilingual App Toolkit in a PCL project to localize an application targeted for multiple platforms (Windows, Windows Phone, Android and iOS). But when I tried to apply the steps in the article to a Universal App I run into some problems. I will still base my localization on resource files, the thing is where do I put these? Should I put them in the new Shared project? or should I keep using PCL projects? Let’s first review our main goals: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;To have a single place where we can specify strings and have these strings shared by all the platform projects.&lt;/li&gt;&lt;li&gt;Strings can be used in the UI as well as programmatically&lt;/li&gt;&lt;li&gt;Use the Multilingual App Toolkit to handle all the translations&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;Resource files in Shared project&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;When I knew about the new shared project type I thought “great, now I can put my resource files in the shared project”. Well, it turns out you can, but this is not the best approach. To explain why let’s see how our goals stand when we use resource files in shared projects.&lt;/p&gt;&lt;p&gt;As mentioned before, universal apps are basically three projects: a project for Windows 8.1, a project for Windows Phone 8.1 and a Shared project. By putting resource files in the shared project they will be shared by both the Windows and Windows Phone projects. Our first goal is ok.&lt;/p&gt;&lt;p&gt;The convergence of the frameworks between Windows and Windows Phone is also applied to the use of resources. Windows apps (aka Windows Store or WinRT apps) use the &lt;font face="Courier New"&gt;.resw&lt;/font&gt; resource type. On the other hand, Windows Phone Silverlight apps (the “Silverlight” suffix was added to differentiate them from the new Windows Phone apps which use the WinPRT framework) use &lt;font face="Courier New"&gt;.resx&lt;/font&gt; resource files. Now, both Windows 8.1 and Windows Phone 8.1 use &lt;font face="Courier New"&gt;.resw&lt;/font&gt; files.&lt;font face="Courier New"&gt;.resw&lt;/font&gt; files can be used in XAML by specifying the &lt;font face="Courier New"&gt;x:Uid&lt;/font&gt; attribute in XAML components (this was not possible with &lt;font face="Courier New"&gt;.resx&lt;/font&gt; files), but these resource files do not have a strong type associated to them (as in the case of &lt;font face="Courier New"&gt;.resx&lt;/font&gt; resource files). This means that we cannot use resource strings programmatically. You can create a strong type associated to &lt;font face="Courier New"&gt;.resw&lt;/font&gt; files by using &lt;a title="ResW File Code Generator" href="https://reswcodegen.codeplex.com/"&gt;ResW File Code Generator&lt;/a&gt;, but it turns out that this extension doesn’t work if the resource is in the shared project. So, our second goal doesn’t stand.&lt;/p&gt;&lt;p&gt;The Multilingual App Toolkit cannot be enabled for shared projects. You have to enable MAT in both Windows and Windows Phone projects. It turns out that the decision of the MAT team regarding universal app was that they “decided to enable MAT based on the specific project instead of the shared project” (see &lt;a href="http://blogs.msdn.com/b/matdev/archive/2014/04/14/announcing-multilingual-app-toolkit-v3-0.aspx"&gt;this blog post&lt;/a&gt; for details). This means that I would have to do translations twice, one for each project. When you enable MAT in both projects you’re solution will be something like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/bf242266-5a79-4461-876d-d8a98ba3b509.jpg"&gt;&lt;img width="250" height="356" title="Universal app with MAT" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Universal app with MAT" src="http://blog.giovannimodica.com/posts/files/52c47b2f-c762-4649-b798-d8ef9f6903e6.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;.xlf&lt;/font&gt; files are duplicated. So, yes we can use MAT on universal app (our third goal is ok) but since we can’t use it on the shared project our first goal doesn’t stand.&lt;/p&gt;&lt;p&gt;Finally, our goals stand as this:&lt;/p&gt;&lt;ul&gt;&lt;!--StartFragment--&gt;
&lt;li&gt;To have a single place where we can specify strings and have these strings 
shared by all the platform projects: &lt;font color="#c0504d"&gt;No&lt;/font&gt;&lt;/li&gt;
&lt;li&gt;Strings can be used in the UI as well as programmatically: &lt;font color="#c0504d"&gt;No&lt;/font&gt;&lt;/li&gt;
&lt;li&gt;Use the Multilingual App Toolkit to handle all the translations: &lt;font color="#008000"&gt;Yes&lt;/font&gt;&lt;/li&gt;&lt;!--EndFragment--&gt;&lt;/ul&gt;&lt;p&gt;In summary, having a resource file in the shared project means that I will not be able to use resource strings programmatically and also that I will have to deal with duplicate translations and manual steps to keep these translations up to date. So, resource files in shared projects: not the best approach.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;br&gt;&lt;/strong&gt;&lt;/p&gt;&lt;h3&gt;Resource files in PCL project&lt;/h3&gt;&lt;p&gt;Our second option is to put resource files in a PCL project. Let’s see how this options stands with our goals. You can perfectly add a PCL project to a universal app solution:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/9a0f4b2d-d55c-4a87-a3da-41a2a18ac920.jpg"&gt;&lt;img width="546" height="381" title="PCL for universal app" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="PCL for universal app" src="http://blog.giovannimodica.com/posts/files/33bbfbac-8c50-424f-b478-2520c0a7d243.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When you do this Visual Studio automatically sets the targets for the PCL project to “Windows 8.1” and “Windows Phone 8.1”:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/3adaedb5-8ab9-4628-b499-760eb9b79e9a.jpg"&gt;&lt;img width="402" height="205" title="PCL project properties" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="PCL project properties" src="http://blog.giovannimodica.com/posts/files/7e120ce4-1bd0-47b0-aa1c-c6e9969346fa.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I suggest to change the “Default namespace” of the PCL project to match the default namespace of the other projects as well. In the PCL project, create a folder structure that is compatible with the project’s default language, in my case “en-US”. Add a new resource (&lt;font face="Courier New"&gt;.resw&lt;/font&gt;) file to the folder. You should have something like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/119d2f58-ef4a-4366-97e9-aef8b9ce84e0.jpg"&gt;&lt;img width="244" height="140" title="PCL folder structure" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="PCL folder structure" src="http://blog.giovannimodica.com/posts/files/a0ba377b-0aac-4688-8dfc-d2e7284d5147.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;(note: you can change the PCL default language by editing the PCL project file. Look for the node &lt;font face="Courier New"&gt;DefaultLanguage&lt;/font&gt;)&lt;/p&gt;&lt;p&gt;It is required for the resource file to be inside a folder with a name that matches the project default language, otherwise MAT will not find any strings and the &lt;font face="Courier New"&gt;.xlf&lt;/font&gt; files will not be generated.&lt;/p&gt;&lt;p&gt;Since the targets for the PCL are “Windows 8.1” and “Windows Phone 8.1” the resource files you can add are of type &lt;font face="Courier New"&gt;.resw&lt;/font&gt;. We already explained that &lt;font face="Courier New"&gt;.resw&lt;/font&gt; resources do not have an associated strong type and we cannot use strings programmatically. To work around this we will use &lt;a title="ResW File Code Generator" href="https://reswcodegen.codeplex.com/"&gt;ResW File Code Generator&lt;/a&gt;: in the &lt;font face="Courier New"&gt;.resw&lt;/font&gt; file properties we will specify values for the properties “Custom Tool” and “Custom Tool Namespace” to be “ReswFileCodeGenerator” and the namespace of our project, respectively:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/7af3ca06-ace1-419e-b7fd-0ee8df4073d0.jpg"&gt;&lt;img width="281" height="181" title="resw file properties" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="resw file properties" src="http://blog.giovannimodica.com/posts/files/a0287097-0a01-4bf2-91f8-3fc6051d9cb3.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This will generate a strong type associated with the resource file at compile time. &lt;/p&gt;&lt;p&gt;You can follow the approach explained in &lt;a href="http://blog.giovannimodica.com/post/how-to-use-the-multilingual-app-toolkit-mat-in-a-portable-class-library-pcl-project"&gt;How to use the Multilingual App Toolkit (MAT) in a Portable Class Library (PCL) project&lt;/a&gt; to see how to use MAT on a PCL:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Enable MAT for the PCL project&lt;/li&gt;&lt;li&gt;Add translation languages to the project (in my case I’m adding “es” and “it”)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Your PCL project should now look as this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/eec7bf7e-d6e0-426a-99f9-4f681899c985.jpg"&gt;&lt;img width="244" height="178" title="PCL with MAT" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="PCL with MAT" src="http://blog.giovannimodica.com/posts/files/5f8a1bcf-b95a-479e-abe9-6ab732176cc0.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;At this point, when you compile the PCL project, all the strings in the default resource file will be copied to the &lt;font face="Courier New"&gt;.xlf&lt;/font&gt; files by MAT. You can now start translating using MAT.&lt;/p&gt;&lt;p&gt;There are some steps we need to do in order to finish this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Make sure you add the PCL project as a reference to both Windows and Windows Phone projects&lt;/li&gt;&lt;li&gt;In the shared folder, create a structure such as the following:&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://blog.giovannimodica.com/posts/files/df7874b0-a754-4202-b8a2-a53c6c6bf77d.jpg"&gt;&lt;img width="284" height="229" title="Shared folder structure" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" alt="Shared folder structure" src="http://blog.giovannimodica.com/posts/files/0bb48e35-a200-4392-bc29-03af26c7ba39.jpg" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Basically you need to create a resource file for each language you support and this resource file needs to be inside a folder with the name of the locale. The &lt;font face="Courier New"&gt;.resw&lt;/font&gt; files in this shared folder structure can be empty. This is a requirement of both Windows and Windows Phone projects in order to know that the application supports all those languages. At this point you can start using resource strings in the UI as well as programmatically (see more details about how to use PCL resources in cross platform apps by reading the article &lt;a href="http://blog.giovannimodica.com/post/internationalization-of-a-cross-platform-application"&gt;Internationalization of a Cross Platform Application&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;Let’s review if we have accomplished our goals:&lt;/p&gt;&lt;ul&gt; &lt;li&gt;To have a single place where we can specify strings and have these strings  shared by all the platform projects: &lt;font color="#008000"&gt;Yes&lt;/font&gt;&lt;/li&gt;&lt;li&gt;Strings can be used in the UI as well as programmatically: &lt;font color="#008000"&gt;Yes&lt;/font&gt;&lt;/li&gt;&lt;li&gt;Use the Multilingual App Toolkit to handle all the translations: &lt;font color="#008000"&gt;Yes&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h4&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&lt;/h4&gt;&lt;font color="#000000"&gt;&lt;h3&gt;&lt;font style="font-weight: normal;"&gt;Sample App&lt;/font&gt;&lt;/h3&gt;&lt;p&gt;You can find a sample VS project here:&lt;/p&gt;&lt;p&gt;&lt;iframe width="98" height="120" src="https://onedrive.live.com/embed?cid=0E2C2C34F932A441&amp;amp;resid=E2C2C34F932A441%218025&amp;amp;authkey=ANBKp6dZuQuLTMY" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;/font&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;&lt;font color="#000000"&gt;In summary, having our resources in a PCL project is still the best option. Shared projects is an excellent idea, but it still lacks support for some other features, as in this case, to be able to handle resource files using MAT and to have &lt;font face="Courier New"&gt;.resw&lt;/font&gt; files generate a strong type. Let’s hope that the guys in the MAT team provide a way to use MAT in shared projects in the future. In the meantime, let them know that we need this by voting on the &lt;a href="http://multilingualapptoolkit.uservoice.com/forums/231158-general/suggestions/6020951-provide-an-example-using-the-mat-in-the-shared-sec"&gt;user voice idea&lt;/a&gt;.&lt;/font&gt;&lt;/p&gt;</content></entry></feed>