Tuesday, September 29, 2009

CRM 4.0 Deploying a custom assembly


The most common and suggested deployment scenario for custom CRM web extensions (i.e. custom web service or web application) is to deploy them under the ISV folder (e.g. ISV / MyApp) and put the application assembly inside the CRMWeb \ bin folder (or wwwroot / bin when deployed on the default website).

As of rollup2 MS also recommends putting the product assemblies of your custom extensions in their own bin folder (i.e. ISV / MyApp / bin). This option also requires you to add an assembly directive

<%assembly name=”MyApp” %>


to all your pages so the asp.net will be able to bind to your server side code behind.

Here is an example:
Test.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="MyApp.Test" %>
<%@ Assembly Name="MyApp" %>


Deployment Tree:

CRMWeb \ wwwroot
|-- ISV
|-- MyApp
|-- bin
|-- MyApp.dll


Looks simple enough but many find that this does not work and produces the error

[HttpException: Could not load type 'MyApp.Test'].


The reason this does not work is that in order for asp.net to recognize and load your assembly the assembly directive must be the first directive in the page e.g.

<%@ Assembly Name="MyApp" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="MyApp.Test" %>


And lastly a few tips to ensure successful deployment for both IFD and On-Premise environments:
Ensure that the MyApp folder is a regular Virtual Directory (not an application) – in other word your app will run under CRMAppPool.
Remove any application level nodes from your application web.config e.g.


14 comments:

BlackWasp said...

Hi,

I just linked through from your response to my question on the CRM forums. My problem is slightly different. I have set up the folder tree as you suggest and have added the assembly declaration at the top of the ASP.NET page. It's a virtual folder, not an application and there is no web.config as there are no custom settings required.

However, the error I get is slightly different. It is...

[FileNotFoundException: Could not load file or assembly 'MyApp' or one of its dependencies.

The MyApp.dll has about a dozen dependencies, all within the same bin folder. I have tried listing just MyApp in an assembly tag and listing all of the dependencies too. In either case, whatever assembly appears first in the list is the one that is not found.

Adi Katz said...

If you put the dependent assemblies in the MyApp bin folder and reference them from MyApp you only need to add the assembly directive to the MyApp.dll (in the aspx file). There is no need to add directives to all the dependencies. Not sure why the file is not found. Did you setup your application directly under isv or is it a new website?

BlackWasp said...

It's just a folder in under ISV:

+ISV
-+MyApp
--+bin

I haven't created a new web site or an application in IIS. Just created the folder and dropped the files in.

Adi Katz said...

I suggest creating a test application with a simple test.aspx that uses the concept in this post. Mark the isv \ test app as a regular virtual directory and put the test app assembly in the isv \ test \ bin folder. Does this work? Are you able to see the test page e.g. http://localhost:5555/orgname/isv/test/test.aspx ?

Craig said...

My custom assembly connects to the database and makes use of the fitlered view tables (since they are easier to use and require less joins). In order to use these tables I have to somehow impersonate a CRM user.

Do you have any suggestions on the best way to accomplish this? There is a way to set up impersonation using the web.config file, but you cannot use the web.config file unless you create it as a seperate "application" in IIS, which is something I wanted to avoid.

Adi Katz said...

If you don't set the VD as application than your app runs under the CRM app pool which means that users are impersonated correctly.

This however will not work with IFD since it uses form authentication so I strongly recommend sticking with CRM SDK / Service.

Adi Katz said...

You can potentially use the Execute as login=‘Domain\username';[sql command];revert; in order to run under IFD.

The user id (systemuserid) should be available through the “User.Identity.Name” or WhoAmI request.

Then query for the user login and use that to build the execute as login statement.

Anonymous said...

Hello,
I would to know what is the best practise for deplying Custom Web Application in ISV folder into CRM website ?

THe scenario describe into the source post (http://mscrm4ever.blogspot.com/2009_09_01_archive.html) does not work on my VPC.

Can you send me a deployed solution into /ISV/MyApp/Bin.

Thanks a lot.

julien.duprat@bewise.fr

Unknown said...

Hi, when I came accross this post I thought my suffer is over, but unfortunately it is not :). I created an asp.net web application and trying to add it under CRM website as virtual directory. The purpose is to enable crm users to have a link(in sales area)to display the default page of the application. The server serves as a crm hosting platform(using IFD). My problem is that when I connect to crm and click the link to my application it asks me again for my credentials. I thought that when I deploy it under the crm site it won't ask again as I have already typed my credentials. I'm stuck with this for a while, any help would be highly appriciated.

Thanks in advance

Anonymous said...

Hi,

setting up VD in IFD environment is not a good idea because it will break the CRMImpersonator functionality + ExtractCRMAuthenticationToken.


But it's working fine for OnPremise Installation.

Thx for this great blog !

Anton said...

Thank you! This is exactly what I needed, trying to prevent the flood of seemingly inexplicable "Unable to load type" errors.

singleinottawa said...

Thanks Adi,

this finally fixed my problem after hours of reading through the guides and trials/errors.

Albarada said...

Hey zarko,

did you find a solution for your problem?

i am facing the same thing!!

Thanks in advance..

Unknown said...

I read your all contain it is very helpful for your service , find some information related custom web applications