Showing posts with label CRM 2013. Show all posts
Showing posts with label CRM 2013. Show all posts

Monday, December 12, 2016

Beware of Legacy forms and how to fix broken case forms after upgrade

Been working with the upgrade of a customer from CRM 2013 to CRM 2016 on-prem and we ran into this weird error. The case form didn't want to work after upgrade if we didn't turn of the turbo forms. For those of you who are not aware of this, in 2015 Spring wave, there was a revision of how forms were loaded, called the turbo forms. After this version there is a setting in the first tab of System Setting where you can turn on "Legacy form rendering" if you want to go back to the old rendering method.

However, we noticed some other strange errors, for instance bool fields with Yes/No values with No as default, were shown as "False" when the form was in create state. Once the form had been saved this error went away.

Another error we saw was that if you tried to save emails, (not send them), you got an error message. The email got saved anyway, but you got a nasty message.

However, if we switched back to turbo forms, both this email error and the bool-error disapeared. Hence, it seems the legacy form controls are not nearly as well quality tested as the turbo form versions so I would strongly suggest that you do not use them unless you have no other option, and then try to move away from them as soon as possible.

So, trying to stick to my paradigm for troubleshooting; "Find where the error is first, then what the error is" - I wanted to go back to the case entity and find out why the turbo forms didn't work.

Rickard and I, who were troubleshooting this together, enabled the dev-mode in IE (pressing F12, if you don't know it) and opened a case. The odd thing was that the point where it broke was in one of Microsoft's functions. I have been unable to recreate the error now so I cannot show it. And after some nitty gritty debugging in IE, we found that the script seemed to be missing "productid" and "primarycontactid" or in laymans terms, Product and Contact.

So, I added them to the case form, and magic! It worked.

But the story doesn't end there. As I thought that this might be a good blog article and I wanted to recreate the error to have as a screendump, I removed the fields again... and mark my surprise when the form still worked... twilightzone.

Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Monday, May 18, 2015

Be aware of Synchronous Workflows on incoming emails and Queue items

How synchronous workflows that fail, make emails disappear.

During the last few Days I have been having the not so pleasant experience of trying to find some really nasty errors in incoming emails to a queue in CRM. We are using CRM 2013 SP1 (on prem) and hence are using the Server Side Sync. Everything had been working great and we had developed some neat workflows that did some magic to convert emails to cases (as those features were not available, and not good enough either) when we develop our stuff.

Well, thing stopped working, I tried sending emails to the CRM server, but none were received in CRM. All I got in CRM was a not so descriptive general alert saying:

"An error occurred while creating incoming email in Microsoft Dynamics CRM for the mailbox XYZ. To view the email that failed, see the alerts in the mailbox record."

and in the mailbox:
"An error occurred while creating the incoming email "Test 1512" in Microsoft Dynamics CRM for the mailbox XYZ."

As I am working on my telepathic abilities, I have not yet reached a level where I can understand what is wrong so I had a look in the trace, and I was very happy I was running an on-prem server. It is a bit long, don't worry if you don't understand it all, nobody (I think) does.

[2015-05-15 15:21:13.459] Process:CrmAsyncService |Organization:673c5996-a1fa-e311-93ed-00155d0a831d |Thread:    4 |Category: Platform.Metadata |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId:  | <>c__DisplayClass1.<LoadMetadataContainerFromDatabase>b__0  ilOffset = 0x14
>Multi-org sharable cache loading system and non-system metadata with build number 6.1.0.581 and language 1033
[2015-05-15 15:33:45.132] Process:CrmAsyncService |Organization:00000000-0000-0000-0000-000000000000 |Thread:   26 |Category: Exception |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: cf367175-12a2-4719-a5af-f53f7f254399 | CrmException..ctor  ilOffset = 0x7
 at CrmException..ctor(String message, Exception innerException, Int32 errorCode, Boolean isFlowControlException)  ilOffset = 0x7
 at CrmException..ctor(String message, Exception innerException, Int32 errorCode)  ilOffset = 0x5
 at Exceptions.ThrowIfGuidEmpty(Guid parameter, String name)  ilOffset = 0x18
 at OrganizationSdkServiceInternal.Retrieve(String entityName, Guid id, ColumnSet columnSet, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)  ilOffset = 0x16
 at InprocessServiceProxy.RetrieveCore(String entityName, Guid id, ColumnSet columnSet)  ilOffset = 0x28
 at OrganizationServiceProxy.Retrieve(String entityName, Guid id, ColumnSet columnSet)  ilOffset = 0x4
 at EntityDictionary.TryRetrieveEntity(String key)  ilOffset = 0xF8
 at EntityDictionary.System.Collections.Generic.IDictionary<System.String,Microsoft.Xrm.Sdk.Entity>.get_Item(String key)  ilOffset = 0x1B
 at VisualBasicValue`1.Execute(CodeActivityContext context)  ilOffset = 0x3A
 at ActivityExecutor.ExecuteInResolutionContext(ActivityInstance parentInstance, Activity`1 expressionActivity)  ilOffset = 0x35
 at InArgument`1.TryPopulateValue(LocationEnvironment targetEnvironment, ActivityInstance activityInstance, ActivityExecutor executor)  ilOffset = 0x2F
 at ActivityInstance.InternalTryPopulateArgumentValueOrScheduleExpression(RuntimeArgument argument, Int32 nextArgumentIndex, ActivityExecutor executor, IDictionary`2 argumentValueOverrides, Location resultLocation, Boolean isDynamicUpdate)  ilOffset = 0x16
 at ActivityInstance.ResolveArguments(ActivityExecutor executor, IDictionary`2 argumentValueOverrides, Location resultLocation, Int32 startIndex)  ilOffset = 0x9C
 at ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)  ilOffset = 0x1C
 at ActivityExecutor.OnExecuteWorkItem(WorkItem workItem)  ilOffset = 0x53
 at Callbacks.ExecuteWorkItem(WorkItem workItem)  ilOffset = 0xD
 at Scheduler.OnScheduledWork(Object state)  ilOffset = 0xC5
 at SendOrPostThunk.UnhandledExceptionFrame(Object state)  ilOffset = 0x0
 at PumpBasedSynchronizationContext.DoPump()  ilOffset = 0x2E
 at WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)  ilOffset = 0x23
 at WorkflowInvoker.Invoke(Activity workflow, IDictionary`2 inputs, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)  ilOffset = 0x36
 at SynchronousWorkflowActivityHost.ExecuteWorkflowUsingInvoker(Activity workflow, ICommonWorkflowContext context)  ilOffset = 0xD0
 at SynchronousWorkflowActivityHost.StartWorkflow(WorkflowActivationData activationData, ICommonWorkflowContext context)  ilOffset = 0x73
 at SynchronousWorkflowActivityHost.StartWorkflow(ICommonWorkflowContext context)  ilOffset = 0xBA
 at WorkflowProcessServiceInternalHandler`1.ExecuteSyncWorkflow(Guid workflowId, PipelineExecutionContext pipelineContext, IGenericEventData workflowInstanceData, Boolean isTriggered)  ilOffset = 0x59
 at WorkflowProcessServiceInternalHandler`1.ExecuteTriggeredSyncWorkflow(Guid workflowId, PipelineExecutionContext pipelineContext)  ilOffset = 0x21
 at SyncWorkflowExecutionPlugin.Execute(IServiceProvider provider)  ilOffset = 0x2C
 at V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context)  ilOffset = 0x2A3
 at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at Pipeline.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at MessageProcessor.Execute(PipelineExecutionContext context)  ilOffset = 0x1FB
 at InternalMessageDispatcher.Execute(PipelineExecutionContext context)  ilOffset = 0xE4
 at ExtensiblePlatformMessageDispatcher.Execute(PipelineExecutionContext pluginContext)  ilOffset = 0x0
 at ExtensiblePlatformMessageDispatcher.CreateWithInvocationSource(BusinessEntity entity, Int32 invocationSource, ExecutionContext context)  ilOffset = 0xB4
 at BusinessProcessObject.Create(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0x54
 at GenericActivityServiceBase.Create(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0xA1
 at CommunicationActivityServiceBase.Create(IBusinessEntity entity, ExecutionContext context)  ilOffset = 0x1A
 at EmailService.SetRecipientsAddAdditionalAttributeAndCreate(AddressEntry[][] allResolvedAddressEntries, Email email, Entity emailDeltaEntity, String traceSubject, ExecutionContext context)  ilOffset = 0x1DA
 at EmailService.Deliver(Boolean userPromote, Guid emailId, String messageId, String subject, String from, String to, String cc, String bcc, DateTime receivedOn, String submittedBy, String importance, String body, BusinessEntityCollection attachments, Guid campaignResponseId, Entity emailDeltaEntity, ExecutionContext context, Boolean validateBeforeDeliver)  ilOffset = 0x524
 at EmailService.DeliverIncoming(String messageId, String subject, String from, String to, String cc, String bcc, DateTime receivedOn, String submittedBy, String importance, String body, BusinessEntityCollection attachments, Entity extraProperties, Boolean validateBeforeCreate, ExecutionContext context)  ilOffset = 0xB8
 at RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)  ilOffset = 0xFFFFFFFF
 at RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)  ilOffset = 0x25
 at RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)  ilOffset = 0xCF
 at LogicalMethodInfo.Invoke(Object target, Object[] values)  ilOffset = 0x4F
 at InternalOperationPlugin.Execute(IServiceProvider serviceProvider)  ilOffset = 0x57
 at V5PluginProxyStep.ExecuteInternal(PipelineExecutionContext context)  ilOffset = 0x200
 at VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at Pipeline.Execute(PipelineExecutionContext context)  ilOffset = 0x65
 at MessageProcessor.Execute(PipelineExecutionContext context)  ilOffset = 0x1C5
 at InternalMessageDispatcher.Execute(PipelineExecutionContext context)  ilOffset = 0xE4
 at ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable`1 requestId, Version endpointVersion)  ilOffset = 0x16E
 at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, OrganizationContext context, Boolean returnResponse, Boolean checkAdminMode)  ilOffset = 0x1F1
 at OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)  ilOffset = 0x2D
 at OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode)  ilOffset = 0x26
 at InprocessServiceProxy.ExecuteCore(OrganizationRequest request)  ilOffset = 0x34
 at IncomingEmailProviderBase.DeliverMessageInternal(EmailMessage emailMessage, Boolean validateBeforeCreate)  ilOffset = 0x1B7
 at IncomingEmailProviderBase.DeliverMessage(EmailMessage emailMessage, Boolean validateBeforeCreate)  ilOffset = 0x19
 at GetItemsStep.ProcessResponse()  ilOffset = 0x5AB
 at ExchangeIncomingEmailProviderStep.EndOperation()  ilOffset = 0xFC
 at ExchangeIncomingEmailProvider.ReceiveEmails()  ilOffset = 0x92
 at IncomingActivityProviderBase.Run()  ilOffset = 0x42
 at MailboxEmailOperation.PerformOperation()  ilOffset = 0x2C
 at MailboxOperationBase`1.Execute()  ilOffset = 0xAA
 at MailboxProcessingOperation.PerformOperation()  ilOffset = 0x1A
 at MailboxOperationBase`1.Execute()  ilOffset = 0xAA
 at MailboxOperationCommand.InternalExecute(MailboxAsyncEvent asyncEvent)  ilOffset = 0x64
 at AsyncCallbackHandler`2.ResumeExecution(IAsyncEvent asyncEvent)  ilOffset = 0x56
 at AsyncEventExecutionManager`2.ExecuteHandler(IAsyncEventHandlerFactory handlerFactory)  ilOffset = 0x8A
 at PoolHandler.ProcessAsyncEvent(IAsyncEventExecutionManager asyncEventExecutionManager)  ilOffset = 0x144
 at AsyncEventOperation.<.ctor>b__2(IServiceOperation operation)  ilOffset = 0x0
 at FaultToleranceBehavior.Execute(ServiceOperationAction operation, IServiceOperation operationParameter)  ilOffset = 0x18
 at MonitoredOperation.Execute()  ilOffset = 0xD
 at ThreadPoolQueueExecutionEngine.InvokeNextOperationInThreadPool(Object state)  ilOffset = 0xC
 at ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)  ilOffset = 0x70
 at ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)  ilOffset = 0x4
 at QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()  ilOffset = 0x30
 at ThreadPoolWorkQueue.Dispatch()  ilOffset = 0xA3
>Crm Exception: Message: Expected non-empty Guid., ErrorCode: -2147220989, InnerException: System.ArgumentException: Expected non-empty Guid.
Parameter name: id
[2015-05-15 15:33:45.304] Process:CrmAsyncService |Organization:00000000-0000-0000-0000-000000000000 |Thread:   26 |Category: Platform |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: cf367175-12a2-4719-a5af-f53f7f254399 | ExceptionConverter.ConvertToFault  ilOffset = 0x69
>UNEXPECTED: no fault?


My first thought was that the stack trace was really long... and then there was some mentioning of User with Guid 00000000-0000-0000-0000-000000000000.

Another kind of queue ticket
As the Server Side Sync has something of a rep for not being the most reliable guy in Town, I wasn't really sure if this error really was an error that we had caused or if there was something wrong with the server side sync. As my perception was that we hadn't really changed any thing, I started with the recreating the mailbox, recreated the server profile, ran test and enable and that worked, but when I tried sending my own emails, from different email accounts, as you never know if there is something spooking it with a specific email address, I still never got the queue to read any emails, not even the test emails created by CRM. I was starting to get a bit short on hair by this time, so I resorted to my classical troubleshooting method of backing off as far as possible and seeing if things still were broken, and I hence deactivated all workflows and plugins that were associated to email and Queue item, and gave the user full access and I was once again awarded with this method, emails started arriving in the queue in CRM.

I then revoked admin access and started re-enabling each single workflow/plugin until thing started
breaking again. This turned out to be a painstaking process as the only way I found to test this was to send an email to CRM and then wait for about 5 minutes until it was/or was not pulled into the queue.
It took me more or less a days work just to find the two workflows that were causing the problems.

The actual problems in them selves, arn't really that interesting, it turned out that the error message above was actually quite correct, If you try to set a null-user to an owner field, CRM will respond like this.

What I did notice however was that the workflows that we were using on "queue item" in this case were synchronous (yes, yes, we do have good reasons for it, I hope you do to, Otherwise, please choose asynchronous/background workflows) and as they broke, CRM did two interesting facts that are not very desirable and noteworthy:
  • The mailbox was shut down for further email processing. It had to be "Test and Enabled" to start receiving emails again. I have yet to see a good way to do this in an automated fashion and to be able to monitor the mailboxes to see if they are working as expected.
  • The email that was the cause of the breaking of the workflow, got lost. Even after the mailbox got reactivated, it had marked this email as read and did not read it into CRM despite the fact that it was neither in the queue nor as a lone activity which might have been the case if the Creation of the queue item broke. But obviously the entire process is handled atomically.
Based on this I have the following recommendations:
  1. If possible try to avoid an synchronous logic on receiving email or Creation of queue items. Try to move logic to asynchronous as this will cause errors to be non-fatal, like the two types of effects that are hard to handle above.
  2. If you do need to have synchronous logic on the receiving of emails or Creation of queue items try to add conditions in the beginning that will ensure that the logic only runs in those very specific cases where they are supposed to. Be aware of the fact that queue items can be associated to many different entities, so don't rely on the fact that they should be only connected to something specific. At least take into consideration the fact that they will be connected to emails at some Point in time.
  3. I read an interesting fact today, that the activation of business rules Controls in which order they will be executed. If you are using CRM 2015 with server side (Entity) scope, this could probably cause similar issues if the activation is done haphazardly and causes the execution to be done in a way that can cause a bug and break processing of the queue item or email. I havn't checked if these are run pre- or poststate but I think that depends on the action.
  4. If you get errors, especially when using CRM Online, try to replicate the error in the sandbox Environment and then either move backwards to a Point where it starts working again, or deactive Everything related to emails and queue items, make sure it works, and move forward. When you know where the error is, finding what the error is, is so much easier.

We also found a related bug in CRM today, if you try to create an asynchronous workflow that triggers on a field which has field based rights activated on it, it will break, with some weird error message about not being able to change domain for the user. The simple fix for that is to make the workflow synchronous and to make it run as the user that activates it, that worked. We didn't try to run it as the user who created the workflow, as that is the same logic that is used in asynchronous workflows, I wasn't too keen on trying something that was more likely to fail. If you have tried it, please leave a comment below.

I hope to see a lot of people tomorrow on the 19:th at the Swedish CRM UG Meeting!

Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Tuesday, April 21, 2015

The CRM 2013 Field Guide is out

After a lot of work a huge amount of MVP:s have now managed to achieve the second CRM Field Guide. I have this time had the honor of being among the authors of this very comprehensive title which goes into details of many areas that very few other books do. At almost 1000 pages it is something that you just have to have with you if you are a CRM expert, or claiming to be one. As Bob Stutz, said in his keynote here at eXtreme CRM today, it is impossible to keep all this information in the head, so we have helped you out, we have tried to destill it poured it into this book.

The book is for CRM 2013, which might seem strange, now that CRM 2015 Update 1 is about to be released but keeping up with Microsoft's cadance is not easy. The absolut majority of the things in the book are still true, yes, there might be some new features in CRM 2015 that can be revised in the book, but I guarantee you that if you know the book by heart, you will be one of the best experts in the worlds on Dynamics CRM, even CRM 2015.

And from our perspectives as authors, most of us, like me, are CTO:s, Techical directors, CEO:s, or senior consultants and developers, we take a lot of our time to write this book, as we partly like to share our knowledge, and partly, I guess to be totally truthful, to feed our pride a bit :). However, the CRM market for books is very limited, and the time frame a book is current is very short, making piles and piles of money off a CRM book is almost impossible, it is probably better to go about your daily job. I would hence say that the best way that you can encourage us to write the next version of this book, is to tell us, the people who made it what you thought of it. What is good, what can be made better? Tell us what is useful for you when you are working with a customer, tell us what you lack. The more people showing interest in what we do, the more we feel inclined to make the next version.

To buy your copy, click on the image below. I have 25 discount vouchers, to my readers, so the first 25 people can use the code "Gustaf2013".



Gustaf Westerlund
MVP, Founder and CTO at CRM-konsulterna AB
www.crmkonsulterna.se

Sunday, October 26, 2014

Making CRM stick by using Dr. John Kotter 8 Step method - part 1 - Justification

During the CRM UG Summit I held a presentation on the subject of how to use the method described by Harvard professor John P. Kotter called the 8 Steps of Change to aid in the implementation of CRM in an organization. This is the first blog entry in a series which will discuss this subject. This first post will be on the question of if using this method is even justified?

Many companies do acknowledge that major change in the organization, like a fusion, changing from line to matrix organization, and so on, however, there are many companies that do not acknowledge that the implementation of a new CRM system is a change of such a substantial degree that it does require it to be handled as a change management Project.

If you are not already aware of the failure rates of CRM Projects, do have a look at the following links:

http://www.zdnet.com/blog/projectfailures/crm-failure-rates-2001-2009/4967
http://www.dmnews.com/63-of-crm-initiatives-fail/article/303470/

The numbers vary, if 70% failure or 30%, but the fact is that a substantial amount of Projects do fail and it is important to be humble to this in order to attempt to mitigate the possible risks of derailing the CRM investment.

Forrester researched 150 companies to find out which problems they were facing in their CRM initiatives as described here: http://blogs.forrester.com/william_band/12-03-01-dont_let_crm_pitfalls_trip_you_up

In short the problems can be divided into the following areas:
  • Creating a CRM strategy – 18% strategy,
    • inadequate deployment methodologies (40%)
    • poorly defined business requirements (25%)
    • lack of alignment on objectives (18%)
  • Re-architecting customer-facing processes – 27%
    • including technical/integration difficulties in supporting company processes (48%)
    • poor business process design (31%)
  • Selecting technology – 33%
    • perceived shortcomings in vendor solutions (30%)
    • a lack of skills needed to implement the solution (23%)
    • system performance shortfalls (19%)
  • Implementing customer-centric behaviors – 22%
    • slow user adoption (49%)
    • poor change management and training (36%)
    • difficulties aligning culture with new ways of working (15%) 

Several books could be probably be written based on this. From an implementation perspective, we can note that about 25% the companies, seem to be having no issues major problems with getting their CRM Strategy correct, they have managed to re-architect their processes and the have overcome all Technical issues, but still their issues lie with the implementation of CRM within the organization. If this is not justification enough that CRM is and requires dedicated and very deliberate change management within the organization.

As I Work as a Consultant, often contracted to implement CRM for a Customer, I would also like to note that Managing change within the organization is not something a temporary external party can do, why it is important to assign internal Resources at the implementing organization to drive the change management Project.

A final note, these numbers might be demoralizing if you are looking at starting you CRM Project or have started it, but I would suggest you look at it in another light. By seeing the problems and errors that others have faced and being open and transparent about your own issues you have a better chance of avoiding these pitfalls. I talked to one of the project leaders for one of the biggest infrastructure Projects in Stockholm which will be completed Before time and within budget. I asked her if she could give me one or two reasons why they were doing so well and she answered:
  • We have very senior and technically experienced people in the Project leadership committee
  • We have been very risk aware from the start, and have had weekly risk meetings


Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Tuesday, June 24, 2014

Some aspects of the composite address fields in CRM 2013

Dynamics CRM 2013 has brought many changes and some are great and some might still need some tweeking. I for one am still looking forward to be able to customized some of the new Composite fields with the fly-outs that can be seen for instance in the name of a Contact or the addresses.

There is much to be said about addresses in CRM by the way, I have previously written posts on this
and in CRM 2013 there is still interesting aspects on this as the address names are not set, in the Composite address fields why you need to make sure that these are properly set if you are going to use the address lookup functions that are available in for instance the quote, order or Invoice entity. My strong advice is also that the addresses of account and Contact be defined, for example, account address1 is visiting address and account address2 is postal address. The reason for this is it simplifies searching a lot when everyone knows what address1 is, and you can also have a workflow or Other logic that sets the addressname correspondlingly.

And just to say this again as I too often run into it, do not add fields to the account or Contact entities regarding address as the built in ones are linked by the platform to the Customer address entity and you need to fully understand how this linking is done and be able to mimic its behaviour for new fields before adding a new address field, otherwise you might be painting yourself into a corner, as the saying is in Sweden.

A nice new feature that I noticed when working with the Composite address fields is that they adapt the layout of the address to the country. See the following example:


Setting of the address in the fly-out
Postal address with Swedish format


Postal address with English format, by changing Country/Region to England.
 

Not sure if you can find any formatting information in CRM regarding this that can be used for Reporting or similar, that would be great though so if anyone knows anything about where this formatting is stored, please leave a comment.

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Sunday, June 08, 2014

Unable to publish all in CRM 2013

I am working with a Customer now who is very savvy an wants to do a lot himself, which I generally encourage as this one of the inherent strengths of Dynamics CRM  and it would be sad to take it away. Of course we need a healthy discussion on where the line should be drawn on where he should stop configuring and I continue. In larger systems, you also need to take sandboxing/QA instancing into this perspective which of course makes it a bit trickier but this Customer is not so large so they can, at least for the time being, do their configuring directly in the system. It is always a matter of weighing the costs against the benifits.

However, we suddenly ran into a problem when we couldn't run "Publish All" any more. It just showed a dialog with a cryptic message mentioning object with id [1] missing.

My first thought was that this must be in relation to one specific entity so I started trying to publish one entity at a time (starting with the ones we have changed a lot) and I quite quickly noticed that I got an error when trying to publish Opportunity but not other entities.

I then created a new solution, added Opportunity to this and included all dependencies, and made sure to publish all dependencies Before trying to publish Opportunity, just to make sure that there wasn't some error in CRM:s causality of publishing. After doing this, I finally go an error message which said something useful, it said that a saved Query of a specifc GUID was missing. This probably meant that this Query was being used on a form in a subgrid and had been removed and when trying to publish, it would not, as the view did not exist.

I opened the form, went through all the subgrids and made sure that the selected view was an existing selection, saved and published the form and it worked. After this publish all also worked.

So the general conclusion is that you should be careful when deleting views as these might be used in subgrids, and the second conclusion is that Microsoft hopefuly will add a dependency blocker that disallows the deletion of a view that is being used in a subgrid.

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Friday, May 30, 2014

Issues with the new Plugin Registration tool

As you might have noticed there is a new version of the plugin registration tool out with the new version of the SDK 6.1 released in may 2014. It has gotten a nice facelift in the UI and can now be found in the Tools directory.

However, I have had some issues when working with my on-premise org (it worked fine with online). I got the following error when trying to register a step on a plugin assembly.


Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Assembly file name (CRMKonsulterna.Modelon.Plugins.dll) is in invalid format. Only file name is allowed.
Detail: <OrganizationServiceFault xmlns="
http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <ErrorCode>-2147204719</ErrorCode>
  <ErrorDetails xmlns:a="
http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <Message>Assembly file name (CRMKonsulterna.Modelon.Plugins.dll) is in invalid format. Only file name is allowed.</Message>
  <Timestamp>2014-05-30T06:58:51.0596986Z</Timestamp>
  <InnerFault>
    <ErrorCode>-2147204719</ErrorCode>
    <ErrorDetails xmlns:a="
http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
    <Message>Assembly file name (CRMKonsulterna.Modelon.Plugins.dll) is in invalid format. Only file name is allowed.</Message>
    <Timestamp>2014-05-30T06:58:51.0596986Z</Timestamp>
    <InnerFault i:nil="true" />
    <TraceText i:nil="true" />
  </InnerFault>
  <TraceText i:nil="true" />
</OrganizationServiceFault>

Server stack trace:
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Microsoft.Xrm.Sdk.IOrganizationService.Create(Entity entity)
   at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.CreateCore(Entity entity)
   at Microsoft.Crm.Tools.PluginRegistration.RegistrationHelper.RegisterStep(CrmOrganization org, CrmPluginStep step)
   at Microsoft.Crm.Tools.PluginRegistration.StepRegistrationForm.btnRegister_Click(Object sender, EventArgs e)


I'm including it all here for searchability. I have highlighted the message that is the interesting part.

When retrying it in the older version of Plugin Registration tool, it works just fine, as long as I re-register the assemblyfile. If I keep the assembly file and try to register the step in the older version (6.0.0001.0061) I will still get the error, so I did have to unregister the entire assembly and register it all over. This also only seems to show up when registering to disk (I havn't tried registereing to GAC as I seldom use that).

Also do note that despite right clicking on the assembly-plugin and pressing "Add step" it seems to omit this information in the form for registering the step so make sure that your step is registered on the correct assembly. I got a bit confused and registered quite a few on ActivityFeeds until I noticed this.

For reference, this is for Plugin Registration Tool version 6.1.0.519 and I am testing it on CRM 2013 UR2 Onpremise.

I am also quite sure these bugs will be fixed soon by Microsoft, but it might be a good idea to keep a copy of the older Plugin registration tool just in case.

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Wednesday, November 20, 2013

Bugs and suggestions


What might be unknown to many CRM people is that Microsoft has a tool for managing bugs and suggestions called Connect. This can be found on connect.microsoft.com. So if you have any suggestions on how you think CRM should be enhanced, don't keep it to your self, add it to connect, and tell your friends, blog about it. After you have added a suggestion, other people can vote on an item and the more votes and item gets, the more attention Microsoft will give it.

I added two suggestions today, so feel free to go in and vote!

First, I think it would be a good idea to be able to supportedly change the logo in the left hand corner. This is done by companies today in an unsupported way which of course is bad, so it would be better to do enable a supported way to do it. Not that it is something I generally encourage, but many companies find this important.

I also think that the logic when using multiple forms of the latest form being used, to be the defaulted the next time a record of the entity is opened often is not what is required, why a default form for each role per entity would be very good.

Connect is also the Tools which is used for bugs during the TAP and beta programs if you are part of these.

I am currently in Bellevue close to Seattle on the MVP Summit, meeting the other MVP:s and the CRM Product team which is great! Joel Lindstrom and I held a presentation to the Product team today and they are a great crowd who are really interested in listening to our opinions. We are lucky to have them and they are really working hard to give us an excellent Product so giving them good input on things we feel the Product can be enhanced, is really a just doing our part of the development. It is easy to complain about something not being as you would like it to, but try to be constructive and formulate that into a suggestion instead and register it on connect and you may get it. Do keep in mind that they have a lot of things to try to triage and it might take some time, but if they don't know, you might never get it.

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se

Monday, November 11, 2013

Mobile Client App (MoCA) on non-english CRM 2013

The Mobile Client App (MoCA) that Microsoft have made as part of the CRM 2013 release is really nice but it is still an early version so to get it up and running on a non-English CRM here is what you need to do. As I Work in Swedish, this is based on my experiences in Swedish and you might have different experiences in other languages.

Install MoCA
First of all, the Store in Windows 8 is by default set to only showing Apps in your local language, as the MoCA hasn't been released in Swedish, in my case, I have to change this.

To do this, open the Marketplace from the Tiles-screens, and swipe from the right or put your mouse on the Lower right hand corner. Select settings (or what ever it is called in your language).

You should now see a screen that looks something like this, but in you language:
Store settings - make sure the one about finding apps in your language is set to "No"
There should be two selectors, one with the caption saying something like
  1. Make finding apps in your language easier
  2. Make it easier to find apps which aid disabilities
Make sure that the first one is set to "No".

After this, click on the back-Arrow in the top left-hand corner.

You should now be back in the Store. Just type the following text (without citation marks):
"Microsoft Dynamics CRM" and press enter.

You should now see a list of Apps and the first one should be the right one, or otherwise it should be in the list any way. It looks like this:


The Microsoft Dynamics CRM Mobile Client App (MoCA)
Now, all you have to do is install the app.
 
Add English Language
What I noted was the that MoCA client will not work if you try to connect it to a Swedish version of CRM Online unless you first enable English in it. Hence this is what we have to do.
 
If you are running an On-premise, you will have to install the English MUI-pack/language pack and you will also have to configure your CRM to be Internet Facing (IFD) which I will not go into in this article but is described in the implementation guide in great depth.
 
Before continuing with configuring the MoCA, go back to your CRM and enable English. This is done by going to Settings->Administration->Languages. Select English and then press "Use".
 
A spinner will show and it will take some time until the language has been provisioned for the organization.
 
Adding English to the CRM Organization
 
Configure MoCA
When English has been added, the MoCA can be configured. It will be in English but it will at least work. Let's hope Microsoft will probably release MoCA in other languages soon.
 

Gustaf Westerlund
MVP, CEO and owner at CRM-konsulterna AB
www.crmkonsulterna.se