The Challenge

Oftentimes in the world of Dynamics CRM, the need arises for non-CRM users to gain access to CRM data. A common solution is the implementation of a web portal which allows these users to perform certain actions on applicable CRM data. Microsoft offers two portal solutions: the Customer Portal and the Partner Relationship Management Portal. These are managed solutions, can be easily imported into any CRM environment, and come with detailed instructions on how to quickly and efficiently deploy.

However, like any construct that is general in its scope, the aforementioned portal solutions do have some caveats. The two solutions install extraneous features onto CRM that are not necessary for portal development, often confusing CRM users and requiring the need to go back and hide all of the excessive customizations. Furthermore, by default, the two portals both use Windows Live for authentication (requiring users without Windows Live to register for an account for authentication) and are hard to style (more often than not, a portal page should have consistent styling with the rest of a website’s pages).

The Solution

With the lack of modularity and abundance of unrequired features from the Customer Portal and the Partner Relationship Management Portal, I sought a more customizable approach in developing portals for our clients.

Without further ado, here are some of the cool things that you will be able to do after reading this blog post:

  • Use the Portal Controls to create a form that on submit will create a new record in CRM.
  • Allow for form-based authentication against a password field in CRM.
  • Allow for Read and Update Privileges on a form after authentication.

Getting Started:

You will need:

  • Microsoft Visual Studio with .NET Framework 4 (In my example I will be using C#).
  • Microsoft Dynamics CRM 2011/2013 SDK
  • CRM 2011/2013 Organization (In this example I will be using CRM 2011/2013 Online)

Included with the blog post is a copy of the example solution which will contain the source code for my project. Download it here.

  1. Create a new ASP.NET Empty Web Application with .NET Framework 4 as the target framework and Visual C# as the Type for your project:

  2. Right click the project and add references to the following dll’s:
    • Microsoft.Xrm.Sdk.dll
    • Microsoft.Xrm.Portal.dll
    • Microsoft.Xrm.Client.dll
    • System.Runtime.Serialization.dll
    • System.Data.Services.dll
    • System.Data.Services.Client.dll
  3. You will need to use the CrmSvcUtil.exe (located in the CRM 2011 SDK, so if you do not have a copy of the SDK, make sure to download it) to generate the early bound types for CRM. The portal will need early bound types with the Microsoft.Xrm.Client.CodeGeneration.dll extension.
    • From the command prompt, navigate to the sdk/bin/ folder where the CrmSvcUtil is located, and run the following command, replacing the url, domain (if on premise), username, and password.

      CrmSvcUtil.exe /codeCustomization:”Microsoft.Xrm.Client.CodeGeneration.CodeCustomization, Microsoft.Xrm.Client.CodeGeneration” /out:Xrm.cs /url:http://Crm/Contoso/XRMServices/2011/Organization.svc /domain:CONTOSO /username:administrator /password:pass@word1 /namespace:Xrm /serviceContextName:XrmServiceContext /serviceContextPrefix:

    • This command generates the C# source file Xrm.cs in the sdk/bin/ folder.
    • For more information on early bound types, check out this article
  4. Right click the csproject (in my example, the csproject is called BlogWebPortal) and navigate to Add, then to Existing Item. Select the Xrm.cs file that you had previously generated and your Solution Explorer should look like this:

  5. To be able to use the Microsoft Dynamics CRM platform and its different Web Services from the portal, you will need to use a valid, enabled CRM user’s credentials for the connection string in the Web.config file.

    a. As a best practice for security reasons, this user should have the minimum amount of privileges in CRM. In this example, the portal will only be dealing with creating new leads and updating existing leads. So, in your organization, you should create a new user with a new security role whose sole purpose is to serve the portal. While you can get away with using any user with the minimum set of privileges, it is not a best practice and could compromise the security of your environment.

    b. Therefore, in this example, I have created a CRM user—Portal User—whose security role has only the privileges shown below, and this user will be the one used to authenticate against CRM.

    c. In addition to the security settings shown above, the security role that the Portal User is assigned to should have the read privilege enabled on the customization tab for Attribute

    Map, Entity, Field, Relationship, Service Endpoint, and View otherwise the portal will err out:


Use the Portal Controls to create a form that on submit will create a new Lead record in CRM:

  1. The Web.config file should have the minimum configuration; and make sure to replace the connection string with the connection string for your organization: <configuration>     <configSections>         <section name=“microsoft.xrm.client“type=“Microsoft.Xrm.Client.Configuration.CrmSection, Microsoft.Xrm.Client“/>         </configSections>         <connectionStrings> <add name=“PortalDemo“connectionString=“Url=https://blog2013demo.crm.dynamics.com; Username=portaluser@blog2013demo.onmicrosoft.com; Password=pass@word1“/>         </connectionStrings>         <microsoft.xrm.client>         <contexts>             <add name=“PortalDemo“type=“Xrm.XrmServiceContext“ />         </contexts>         </microsoft.xrm.client>         <system.web>             <compilationdebug=“true“targetFramework=“4.0“ />         <pages>         <controls>             <add tagPrefix=“crm“namespace=“Microsoft.Xrm.Portal.Web.UI.WebControls“ assembly=“Microsoft.Xrm.Portal“ />         </controls>     </pages> </system.web> </configuration>
  2. Create a view in CRM for Leads that will specify the fields that will show up on the portal form. The fields will be ordered in the same sequenced on the portal as they are in CRM
    • CRM Lead View (system view named Portal View)

    • Portal Form

  3. Right click on your project. Navigate to Add New and then add a blank aspx page called CreateLead.aspx to the project. Your Solution Explorer should look like this:

  4. On the aspx web page (CreateLead.aspx), you will add two custom controls that have been made available by including the Microsoft.Xrm.Portal.dll as a reference, a CrmDataSource and a CrmEntityFormView that uses the data source. Your resulting aspx code will look something like this:

    <html xmlns=”http://www.w3.org/1999/xhtml”> <head runat=”server”>      <title></title> </head> <body>      <form id=”form1″ runat=”server”>      <div>          <crm:CrmDataSource ID=”WebFormDataSource” runat=”server”/>          <crm:CrmEntityFormView runat=”server” DataSourceID=”WebFormDataSource”  ID=”NewLeadView” EntityName=”lead” SavedQueryName=”Portal View”  ValidationGroup=”validators”>         </crm:CrmEntityFormView>      </div>      </form> </body> </html>

  5. Crm:CrmDataSource is a custom control included as a reference from the Microsoft.Xrm.Portal.dll, so add a reference to the controls on the codebehind file for your aspx page—using Microsoft.Xrm.Portal.Web.UI.WebControls;.
  6. Build first, then navigate to and browse your new form (CreateLead.aspx), fill out the information and submit, and voila! A new lead is created in CRM!

    Portal Form:

    New Lead is Created in CRM (after Submit button click):


Allow for form-based authentication against a password field in CRM:

  1. At a high level, form-based authentication is the notion of checking against a username and password to implement security on certain items. In terms of the portal and CRM, you want to assign a username and password to non-CRM users, so that they can log in, read and update their information (covered later on in this blog post).
  2. For authentication, you will need a username field along with a password field. In this example, since I am dealing only with leads, I can simply create a new username field and a new password field for the lead record. So create new fields for username in password as Single Line of Text for the lead:

  3. To allow for form-based authentication in an ASP.net application, it is necessary then, to explicitly state in the Web.config that this is the case. Under the system.web node, add the following:

    <authentication mode=“Forms“>    <forms name=“.ASPXAUTH” loginUrl=“Login.aspx“ protection=“All” timeout=“30” path=“/“ requireSSL=“false” slidingExpiration=“true“ cookieless=“UseDeviceProfile” domain=“” enableCrossAppRedirects=“false“>      </forms> </authentication> <authorization>      <deny users=“?“/>      <allow users=“*“/> </authorization>

  4. The important bit for the snippet from the Web.config file above indicates that loginUrl=“Login.aspx”. Also, the authorization node indicates that all users will be denied access unless they have passed the form-based authentication. Therefore, it is also necessary to allow users access to the existing page (CreateLead.aspx). To do this, you simply add this snippet after the system.web node:

    <location path=“CreateLead.aspx“>      <system.web>           <authorization>                <allow users=“*“/>           </authorization>      </system.web> </location>

    **As a reference, you can always examine the Web.config included in the project.

  5. Create a new empty web form called Login.aspx (in the same manner as the CreateLead.aspx page). Your Solution Explorer should look something like this:

  6. Add an ASP login control on the Login.aspx page:

    <form id=”form1″ runat=”server”>      <div>           <asp:Login                ID=”Login1″ runat=”server” OnAuthenticate=”Login1_Authenticate”>           </asp:Login>      </div> </form>

  7. Since you have an OnAuthenticate event (Login1_Authenticate) specified for theLogin control, add a method called Login1_Authenticate to the C# code-behind page for the Login.aspx.cs:

    protected void Login1_Authenticate(object sender, System.Web.UI.WebControls.AuthenticateEventArgs e) { }

  8. Now, basically, you want to authenticate against the new fields that you created in CRM, username and password. As those fields were newly added, you will need to regenerate the Xrm.cs file using the CrmSvcUtil tool (Step 3 of Getting Started) which is one caveat of early-bound types, but that is a topic for another day.

    CrmSvcUtil.exe /codeCustomization:”Microsoft.Xrm.Client.CodeGeneration.CodeCustomization, Microsoft.Xrm.Client.CodeGeneration” /out:Xrm.cs /url:http://Crm/Contoso/XRMServices/2011/Organization.svc /domain:CONTOSO /username:administrator /password:pass@word1 /namespace:Xrm /serviceContextName:XrmServiceContext /serviceContextPrefix:Xrm

  9. You need an instance of an IOrganizationService interface to be able to use the CRM Web Services, so the quickstart example from the CRM 2011 SDK contains some methods that will easily allow us to instantiate an OrganizationService which is simply a wrapper class around the IOrganizationService class. Also, you will need to instantiate the OrganizationService across different pages so take this time to create a class called PortalPage which inherits from the aspx page (public class PortalPage : System.Web.UI.Page) which will contain two methods from the quickstart example—GetServiceConfiguration() and isValidConnectionString(). Reference the PortalPage.cs file from the included solution for specific source code. Your Solution Explorer should now look something like this:

  10. Now, navigate back to Login.aspx and modify it to inherit from the PortalPage so that it can use the methods that were added from quickstart. Also you will need to add using directives to some CRM 2011 SDK references along with System.Configuration:

  11. Create a function validateLead which will be triggered On Authenticate of the ASP.net Login control and fetch the username and password to see if it exists or not. For simplicity, we will assume that the combination of a Username and Password is unique. validateLead will fetch the Username and Password from the Lead table and if you return a result then set the event Authenticated flag to true, otherwise set it to false. Reference the Login.aspx.cs file from the included solution for specific source code. There exist two validateLead functions in the source code, the commented out version refers to this version while the uncommented function is used in the next blog section.
  12. That’s it, you’re done! You can play around with your code and test the authentication is working by building and browsing to Login.aspx, putting breakpoints in your code, or try stepping through your code, but in the next section of the blog, you will be able to implement authentication one step further by allowing a portal user to read and update his/her information.


Allow for Read and Update Privileges on a form after Authentication:

  1. Create another blank .aspx web form called EditLead.aspx and have it also inherit from PortalPage and add the same using directives as you did for Login.aspx in the previous blog section:

    Your Solution Explorer should look something like this:

  2. You will need to allow users to update some fields from the lead. To do this, you must modify our existing validateLead function on Login.aspx page which currently returns true or false to return a GUID if it finds the lead record. You can then use this GUID as a part of the query string when you redirect to EditLead.aspx as the criteria for fetching the rest of the lead data. Reference the Login.aspx.cs file from the included solution for specific source code. As previously mentioned, there exist two validateLead functions in the source code, the uncommented capitalized version refers to this function.
  3. You will want to redirect to the EditLead.aspx page with the GUID as a parameter of the query string, as mentioned in the previous step. Therefore, in Login.aspx, first add a using directive to System.Web.Security so that you can use a method from the FormsAuthentications class. Right after the event gets authenticated, set the authentication ticket for the logged in user, and redirect to the EditLead.aspx page:

    if (leadGuid != Guid.Empty) { e.Authenticated = true; FormsAuthentication.SetAuthCookie(Login1.UserName, false); Response.Redirect(“EditLead.aspx?LeadID=” + leadGuid.ToString()); }

  4. In my example, I will display First Name and Last Name as plain text, and allow for the editing of topic in the form of the text box. Therefore you first need to add a First Name label, Last Name Label, Topic Label, Topic Text Box, and a button for update. Add these to the EditLead.aspx page. As always, you can reference the source code for EditLead.aspx

  5. Now that the fields are set on the aspx web page, and the id of the lead is passed as a parameter in query string, you can use that lead id to fetch the fields for the logged in user and to subsequently populate the fields on the EditLead.aspx form. To do this, add a function for Page_Init and in the body of Page_Init, fetch the lead and its fields then populate the First Name Last Name labels and Topic TextBox. Reference the EditLead.aspx.cs file for specific source code. Now, if you try logging with a valid credential, you should be able to see the fields on the portal field. In CRM:

    On Portal Form (after Authentication):

  6. You can now see that the first name and last name labels are being populated with the first name and last name from the lead and the topic text box contains the same information as CRM. This is all good, but now you will add functionality to the Update button so that the Topic field in CRM can be updated to something else. To do this, you’ll need to add an OnClick event for the Update Button and in this event, update the topic for the lead. For good measure, add a new label that will display if the event is successful. Reference EditLead.aspx and EditLead.aspx.cs for specific source code. If you try updating the textbox with Rollerblades instead of Rollerskates, you will see that the record has been updated in CRM.

    On Portal Form (on Update button click):

    In CRM (on Update button click):

    And there it is! You should now be able to do the following:

    • Use the Portal Controls to create a form that on submit will create a new record in CRM.
    • Allow for forms-based authentication against a password field in CRM.
    • Allow for Read and Update Privileges on a form after authentication.

    Feel free to call should you have any questions or comments.

Step-by-Step Guide to Portal Development for Microsoft Dynamics CRM - 摘自网络的更多相关文章

  1. Step by step Dynamics CRM 2011升级到Dynamics CRM 2013

    原创地址:http://www.cnblogs.com/jfzhu/p/4018153.html 转载请注明出处 (一)检查Customizations 从2011升级到2013有一些legacy f ...

  2. Step by step Dynamics CRM 2013安装

    原创地址:http://www.cnblogs.com/jfzhu/p/4008391.html 转载请注明出处   SQL Server可以与CRM装在同一台计算机上,也可安装在不同的计算机上.演示 ...

  3. Step by Step 创建一个新的Dynamics CRM Organization

    原创地址:http://www.cnblogs.com/jfzhu/p/4012833.html 转载请注明出处 前面演示过如何安装Dynamics CRM 2013,参见<Step by st ...

  4. How to set up Dynamics CRM 2011 development environment

    Recently I have been starting to learn Microsoft Dynamics CRM 2011 about implement plugin and workfl ...

  5. Tomcat Clustering - A Step By Step Guide --转载

    Tomcat Clustering - A Step By Step Guide Apache Tomcat is a great performer on its own, but if you'r ...

  6. Step by step guide to set up master and slave machines(转)

    Note: There is no need to install Jenkins on the slave machine. On your master machine go to Manage ...

  7. Step by step guide to set up master and slave machines on Windows

    Note: There is no need to install Jenkins on the slave machine. On your master machine go to Manage ...

  8. Step by Step use OBD2 Scanner Guide

    Learning to use a good automotive OBD2 code reader is one of the best ways you can continually inves ...

  9. Devops step by step

    接着上次分享的devops历程[Followme Devops实践之路], 大家希望能够出一个step by step手册, 那今天我就来和手把手来一起搭建这么一套环境, 演示整个过程! 实验环境需要 ...

随机推荐

  1. Python开发轻量级爬虫

    这两天自学了python写爬虫,总结一下: 开发目的:抓取百度百科python词条页面的1000个网页 设计思路: 1,了解简单的爬虫架构: 2,动态的执行流程: 3,各部分的实现: URL管理器:p ...

  2. MVC5添加控制器总是报“Multiple object sets per type are not supported”

    http://www.asp.net/mvc/tutorials/mvc-5/introduction/creating-a-connection-string 按照上面的指导做练习,  总报小面的错 ...

  3. ASP.NET MVC NHibernate 整合

    请注明转载地址:http://www.cnblogs.com/arhat 在整合这三个技术之前,首先得说明一下整合的步骤,俗话说汗要一口一口吃,事要一件一件做.同理这个三个技术也是.那么在整合之前,需 ...

  4. splay学习笔记

    伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.(来自百科) 伸展树的操作主要是 –rotate(x) 将x旋转到x的父亲的位置 voi ...

  5. Chapter 10 EF 6 Support

    http://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html

  6. poj 3261 Milk Patterns(后缀数组)(k次的最长重复子串)

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7938   Accepted: 3598 Cas ...

  7. leetcode-173:Binary Search Tree Iterator(Java)

    Binary Search Tree Iterator Implement an iterator over a binary search tree (BST). Your iterator wil ...

  8. 【产品体验】eyepetizer开眼

    第一次写博客,内心还有点小激动呢~~本人产品新人,学习中,希望大家多多指教!  先来两张开眼的界面图坐镇——         开眼简介: appetizer for eyes 即 eyepetizer ...

  9. centos SSH配置详解

    基本概念  linux自带的ssh为OpenSSH ssh协议提供两种用户认证方式  1. 基于口令的安全认证:使用用户名.密码的方式对登录用户进行认证 2. 基于密钥的安全认证:使用公钥和私钥对的方 ...

  10. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...