When I've been to Denmark, I often saw people saying "Navision turns amateurs into professionals." And it is so true, actually, it happened to me, it turned me from a business analyst into a programmer.
MSCRM is different: although customization became easier in 3.0, it is still hard for a consultant with a non-technical background to learn Visual Studio a C# to do very simple customizations.
For example, if users request that when they open an Opportunity form, they should get a message box if any contacts associated will have a birthday in two weeks, you need to 1) write a web service in Visual Studio, compile and configure it, that reads the data from the database 2) write JScript code to the form to show the message box. It is kind of hard.
So, I think we should start thinking together how to make it easier.
1) Having to use two languages instead of one (Jscript and C#/VB.NET) is hard. We could investigate that whether we could write the compiled part in Jscript.NET. It would bring things closer. In a next post, I will copy a little Jscript.NET tutorial here.
2) Borrowing the idea of the Object Table from Navision, we could investigate the idea of creating custom entities to hold the code. Maybe two entities, Project and Code Object, could be the name, and the code itself in a text field. Then, we could write a service that calls the command-line compiler and maybe even copies the files where they belong. Is it a good idea?
Remember, Visual Studio is great, but you don't need it for 95% of typical CRM/ERP customization requests, usually they are very simple, just reading and writing some data.
Any ideas are welcome.
And Merry Xmas!
Do It Yourself is they key. Standard code might work - your code surely works.0
Comments
http://www.c-sharpcorner.com/JScript/In ... Script.asp
Do It Yourself is they key. Standard code might work - your code surely works.
3.0! It is the one called Duplicate Detection - this is a good example of
typical implementation customizations.
It consists of two parts:
1) A web service in ASP.NET/C# that queries the database for Accounts with a same name as the one you are trying to enter.
2) JScript code in OnSave for calling this service and throwing a nice big
error if it returns true.
It was REALLY hard installing it - clearly, MS CRM is much harder than
Navision for a consultant with a non-technical background. What I managed to find out is ugly and unsafe, but it at leasts works and the later we can harden and refine it.
First, go to sdk samples/fullsamples/duplicatedetection and read the readme.
The important stuff is you DO NOT NEED Visual Studio! The readme just tries to tempt you into buying VS, but you don't actually need it.
What you need is
a) CSC.EXE which you can find on your CRM Server at
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322
b) wsdl.exe, part of .NET Framework Tools which is a command-line tool, either it is install automatically or f.e. one cand find it at:
http://www.epcc.ed.ac.uk/~ogsanet/cours ... ial0_2.htm
Copy the ASPX, the JS file, and wsdl.exe to you CRM server if it's not already there.
From now on, we are working on the server.
c) command line: wsdl.exe /out:Microsoft.Crm.Sdk.Wsdl.cs /namespace:CrmSdk [url=http://]http://[/url]<yourserver>/mscrmservices/2006/crmservice.asmx
Note that it has NOTHING to do with this specific customization: all
webservices you write which want to acces the CRM database through the CRM web service must use this. In other words, you need to do it only once.
In my case, <yourserver> was localhost:5555. (It's a testing system.) You can find out what yours is by Start menu, Run, inetmgr and checking the properties of the web sites there.
D) command line: "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe" /t:library Microsoft.Crm.Sdk.Wsdl.cs
You should have a Microsoft.Crm.Sdk.Wsdl.dll now.
E) Copy it to Program Files\Microsoft CRM\CRMWeb\bin
F) Copy the aspx file somewhere, I copied it to
c:\custom\ISV_DuplicateDetection
G) Start menu, Run, inetmgr, go to the CRM website, New, Virtual Directory. Now, the SDK suggests ISV_DuplicateDetection as a virtualdir name but I was afraid that underscore might be dangerous so I just named it dupdec. I suggest to try this way first. Then selected that it refers to c:\custom\ISV_DuplicateDetection, and granted all rights except for write. Yes, it is unsafe, but get it to work first and harden it later.
H) Restart IIS - go up in the inetmgr to the server, right click, all tasks,
Restart IIS
I) I tried this stuff by typing
localhost:5555/dupdec/checkforduplicateaccount.aspx?name=Test. It did not work. After much guessing and scratchin' head what I finally did is that I went to Program Files\Microsoft CRM\CRMWeb\bin and copied all bloody DLL-s to c:\custom\ISV_DuplicateDetection\bin of
course it is not the right solution, but I dunno how to configure ASP.NET properly. Later we need to find it out I think.
For testing it works and we can refine it later on. After that it worked from the browser, so I went to the Jscript part.
J) Start CRM, copy the JScript code to the OnSave event, save, Publish,
exit, start CRM again, try out and lo and behold!
#TODO:
- find out the minimum required rights for the virtual directory
- find out how to avoid copying DLL-s
The important thing is that you could do it all without Visual Studio.
For developing such stuff, I suggest to download the free ASP.NET Web
Matrix. It contaings syntax coloring and a built-in webserver so you can
test things on-the-fly. You will either need to install it on the server or
on a box with access to the web services provided by the server.
I will now play around with the code of these apps and tell you what I find.
Do It Yourself is they key. Standard code might work - your code surely works.
field mandatory for a business unit only on an Account form.
General impressions
- ad-hoc customizations, especially for one without much technical
background, can be quite hard, however
- code reusability and structurisation are quite good and once one
creates a decent library, things can get easier, it looks like a curve where
the start is hard but if we cleverly generalize developments and build a
good library, it can turn quite easy in the long run. It will be a hard and
slow start and I would expect working much more than was planned in the
first 2-3 projects but afterwards I expect it to become easy.
The important point is that MSCRM, contrary to Navision, can't be
implemented alone - a full-time consultant needs a full-time developer to
build the necessary libraries and services. No other way around.
This example - make a field mandatory for a business unit - I started to
write, I am not finished yet but I can tell the general concepts:
1) The database part: we need a general web service that tells what business stream you are in. I think it's best using the Division Name field for a simple business unit code: f.e. in our company I am in the 273 business stream.
This web service can be more or less copy-pasted from SDK examples: the WhoAmI from the customroles example and the duplicatedetection example which tells how to generally write ASPX pages that query the database and return data.
It is a little bit complicated - I am not sure overriding the Render method
is the simplest way to return data, but it's just a copy-paste and it
works so no problem.
The duplicatedetection SDK example offers an elegant way of communication between the database-querying ASPX pages and the Jscript in the CRM client: returning data in XML. Although I like plain text data better (too much Unix blood running in my veins ) it is easy to see the advantages of this approach: for example, one can return a node like <result>273</result> if the query is successful and return a node like <error>Division Name field is empty in you Business Unit, please contact the system administrator!</error> if there is an error. It's a nice way to handle errors: then the client-side code can check whether there is an error node and if there is, show the
error message and die, and if there is no such node, then process the
results.
It is not very easy, however, when it's finished, we have a general service
that tells what business unit we are in - I think we can use it a lot of
times in the future.
The question is that should one not generalize it? For example, a service
that returns any field from any kind of entity?
2) The client part: we need JScript code to look at this business unit information and check whether the field is populated. If we just try to write this code into the client, it will be a suffering, because it's long and error-prone and have
to republish and restart the client for evey single change, and writing any
code in the form event editor is really hard (TAB does'nt work for
indentation etc.). What we really need is an external JScript library in
a file, something.js and import it - and this is not covered in the SDK! Basically, what this library would provide is a function, that, if we just type
something like import something.js;
CheckFieldForBusinessUnit("273","accountnumber");
Then if we are in the 273 business stream it would check if the account
number is populated and throw an error message if not. I think this is
possible, but I am not quite sure how to import libraries and how to turn a string into an object property - I will tinker with it and tell what I
find.
Note: the most elegant solution would be to create a new entity, where there is a relation to a Business Unit, and dynamic picklists (such as in the
dynamic picklist SDK example, by querying the metadatabase) to choose entity and field, I think it is possible, and then it would be completely
configurable. I think this is possible, but takes some time - one needs to find out how to cycle through XML nodes in JScript to build the picklist and also needs to find out how to cast a string to a method in C#.
Do It Yourself is they key. Standard code might work - your code surely works.