locked
InvalidCastException 'Unable to cast object of type 'Microsoft.Xrm.Sdk.Entity' to type '.................' RRS feed

  • Question

  • Hi,

    I am a beginner in CRM coding.I am writing a plugin code which is  registered with :SetStateDynamicEntity and I have a linq query which queries the plans and accounts for the client,if the client has active plans/active accounts the client is not allowed to deactivated. 

    Following is the source code :-

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Query;
    using Microsoft.Xrm.Sdk.Client;
    using System.Diagnostics;
    using Microsoft.Xrm.Sdk.Messages;
    using Captrust.CC5.CAPConnect;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    
    
    namespace Captrust.CC5.PlugIn
    {
        /// <summary>
        //Deactivate a client only as a Sysadmin or CS Resp role , and not allowed to deactivate if accounts or plans are active for the called client
        /// </summary>
        /// 
        public class DeactivateClient : IPlugin
        {
            
            public void Execute(IServiceProvider serviceProvider)
            {
                try
                {
                    
                    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                    IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = factory.CreateOrganizationService(context.UserId);
                    OrganizationServiceContext orgcontext = new OrganizationServiceContext(service);
                    //OrganizationServiceProxy proxy = (OrganizationServiceProxy)service;
                    //proxy.EnableProxyTypes(typeof(Captrust.CC5.CAPConnect.Workflow).Assembly);
                    
                    OptionSetValue Inactive = new OptionSetValue(1);
                    Guid accountId = default(Guid);
    
                    if(context.MessageName=="SetStateDynamicEntity")
                    {
                        if (Inactive.Equals(context.InputParameters["State"]))
                        {
                            if ((context.PreEntityImages.Contains("account")))
                            {
    
                                Entity accountimage = context.PreEntityImages["account"];
    
                                accountId =accountimage.GetAttributeValue<Guid>("accountid");
                                OptionSetValue code = new OptionSetValue(0);
    
                                //Checks the user roles - allow to deactivate a client only the roles is Sys Admin or CS Resp
                                if (accountId != null)
                                {
                                    bool permission = false;
                                    EntityCollection roles = GetUserRoles(context.UserId, orgcontext);
                                    if (roles != null)
                                        {
                                             for (int i = 0; i < roles.Entities.Count; i++)
                                             {
                                                 Entity userrole = (Entity)roles.Entities[i]; ;
                                                /* if (userrole.Contains("name"))
                                                 {
                                                     if (userrole["name"].ToString() == "System Administrator" || userrole["name"].ToString() == "CS Resp - Client SErvice Mgr")
                                                    permission = true;
                                                 }*/
                                                 String role = userrole.GetAttributeValue<string>("name");
                                                 if (role.Equals("System Administrator") || role.Equals("CS Resp - Client SErvice Mgr"))
                                                     permission = true;
                                             }
    
                                        }
                                 //if not a system admin or CS Manager,reject close
                                 if (!permission)
                                        throw new InvalidPluginExecutionException("Only System Administrator and CS Resp - Client SErvice Mgr have permission to deactivate this record");
    
                                }
                                
    
                                
                                //populates the accounts and plan for the called client
    
                                //var plan = from p in orgcontext.CreateQuery<Ct_plan>() where p.ct_clientid.Id== accountId select p;
                                
                                
                                IEnumerable<Ct_plan> plan = from p in orgcontext.CreateQuery<Ct_plan>() where p.ct_clientid.Id==accountId select p;
                                IEnumerable<Ct_account> account = from a in orgcontext.CreateQuery<Ct_account>() where a.ct_householdid.Id.Equals(accountId) select a;
                                      
                                //checks if accounts or plan states are active for the called client
                                foreach (Ct_plan p in plan)
                                {
                                    if (p.statecode.Equals(code))
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Plans are open for this client");
                                    }
    
                                } 
                                foreach(Ct_account a in account)
                                {
                                    
                                    if (a.statecode.Equals(code))
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Accounts are open for this client");
                                    }
    
                                }
                             
                                
    
                            }
                        }
                       
                    }
                   
                        
     
    
                }
                catch (InvalidPluginExecutionException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    using (var application = new EventLog("Application"))
                    {
                        application.Source = "MSCRMTracing";
                        application.WriteEntry("Plugin error: " + e.Message + e.StackTrace);
                    }
    
                }
                
            }
            public EntityCollection GetUserRoles(Guid guidUserID, OrganizationServiceContext context)
            {
                try
                {
                    QueryExpression query = new QueryExpression();
                    query.EntityName = "role";
                    query.ColumnSet = new ColumnSet();
    
                    LinkEntity link1 = new LinkEntity();
                    link1.LinkFromEntityName = "role";
                    link1.LinkFromAttributeName = "roleid";
                    link1.LinkToEntityName = "systemuserroles";
                    link1.LinkToAttributeName = "roleid";
    
                    ConditionExpression condition = new ConditionExpression("systemuserid", ConditionOperator.Equal, guidUserID);
    
                    LinkEntity link2 = new LinkEntity();
                    link2.LinkFromEntityName = "systemuserroles";
                    link2.LinkFromAttributeName = "systemuserid";
                    link2.LinkToEntityName = "systemuser";
                    link2.LinkToAttributeName = "systemuserid";
    
                    link2.LinkCriteria = new FilterExpression();
                    link2.LinkCriteria.Conditions.Add(condition);
    
                    link1.LinkEntities.Add(link2);
                    query.LinkEntities.Add(link1);
    
                    RetrieveMultipleRequest request = new RetrieveMultipleRequest();
                    request.Query = query;
    
                    RetrieveMultipleResponse response = (RetrieveMultipleResponse)context.Execute(request);
    
                    if (response.EntityCollection.Entities.Count > 0)
                    {
                        return response.EntityCollection;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception e)
                {
                    Console.Write("error:" + e.ToString());
                    return null;
                }
    
            }
    
        }
    }
            
    

     

    When I change the code to

      IEnumerable<Ct_plan> plan = from p in orgcontext.CreateQuery<Ct_plan>() where p.ct_clientid.Id==accountId select p.ToEntity<ct_plna>();                            

    IEnumerable<Ct_account> account = from a in orgcontext.CreateQuery<Ct_account>() where a.ct_householdid.Id.Equals(accountId) select a.ToEntity<ct_account>();

     

    I get an exception

    'Sequence contains no element'  .... I found that firstordefault() doesnot resolve this problem since one client may have many accounts /plans associated.So,firstordefault...or single() doesnot solve this issue

     

    I highly appreciate your help!

    Thanks,

     Akila

     



    • Edited by CRM Plugins Monday, October 10, 2011 1:54 PM
    Monday, October 10, 2011 1:44 PM

Answers

  • ClientCredentials creds = new ClientCredentials();
                                creds.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
                                string url = string.Format("http://{0}/{1}/XrmServices/2011/Organization.svc", Properties.Settings.Default.Server, Properties.Settings.Default.Organization);
                                IEnumerable<Ct_plan> plan;
                                IEnumerable<Ct_account> account;
                                using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(new Uri(url), null, creds, null))
                                {
                                    serviceProxy.EnableProxyTypes();
                                    IOrganizationService tempService = (IOrganizationService)serviceProxy;
                                    OrganizationServiceContext tempContext = new OrganizationServiceContext(tempService);
                                    plan = (from p in tempContext.CreateQuery<Ct_plan>() where p.ct_clientid.Id == accountId && p.statecode.Equals(code) select p).AsEnumerable<Ct_plan>();
                                    account = (from a in tempContext.CreateQuery<Ct_account>() where a.ct_householdid.Id.Equals(accountId) select a).AsEnumerable<Ct_account>();
                                    
                                    if (Enumerable.Count(plan)>0)
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Plans are open for this client");
                                    }
                                    if (Enumerable.Count(account) > 0)
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Accounts are open for this client");
                                    }
                                }
    
    


    Akila
    • Marked as answer by CRM Plugins Tuesday, October 18, 2011 8:18 PM
    Tuesday, October 18, 2011 8:18 PM

All replies

  • Did it really say '........' or did it say what it was trying to cast to when it failed.

    You should try to the debug a plugin and see what type the other class you are trying to convert to is.  That should shed some light on how to fix the problem

    http://msdn.microsoft.com/en-us/library/gg328574.aspx


    Jamie Miley
    Check out my about.me profile!
    http://mileyja.blogspot.com
    Linked-In Profile
    Follow Me on Twitter!
    Monday, October 10, 2011 4:23 PM
    Moderator
  • The select will return an enumerable entity set.  This cannot be cast to an Entity.  The statement should be

    (from a in orgcontext.CreateQuery<Ct_account>() where a.ct_householdid.Id == accountId select a).AsEnumerable<Ct_account>()

    which you can then check for the appropriate entity(s).

    Monday, October 10, 2011 7:02 PM
  • Unable to cast object of type ''Microsoft.Xrm.Sdk.Entity' to type 'Captrust.CC5.CAPConnect.Ct_plan'

    I debugged and this is the snapshot


    Akila
    Monday, October 10, 2011 8:32 PM
  • Is that some kind of add-in?  I am not familiar with CapConnect.  I understand why you can't convert to Entity though since that is a CRM specific object type.
    Jamie Miley
    Check out my about.me profile!
    http://mileyja.blogspot.com
    Linked-In Profile
    Follow Me on Twitter!
    Monday, October 10, 2011 8:41 PM
    Moderator
  • I don't think CRM Linq can make a direct conversion to the typed plan variable as you are trying.  Try:

    var plan = from p in orgcontext.CreateQuery<Ct_plan>() where p.ct_clientid.Ic == accountId select p

    if (Enumerable.Count(plan) > 0)

        plan[0].GetAttributeValue<T>("myAttribute")

    Monday, October 10, 2011 8:54 PM
  • Hi

    There are a number of ways to achieve this 1st is below (late binding) but here you dont need to convert to Entity because you have set the IEnumerable to specific entity so your query should be as below

    PS: ACCOUNT is default entity so no need to use Ct_ unless you have custom entity

    LATE BINDING

    IEnumerable<ct_Plan> plans = (from p in orgcontext.CreateQuery<ct_Plan>() where p.ct_clientid.Id.Equals(accountId) select p);                   

    IEnumerable<ct_Account> accounts = (from a in orgcontext.CreateQuery<ct_Account>() where a.ct_householdid.Id.Equals(accountId) select a);


    OR

    Use EARLY BINDING uses EntitySets for example AccountSet, ContactSet etc.... 

    IEnumerable<ct_plan> plans = (from p in orgcontext.ct_planSet where p.ct_clientid.Id.Equals(accountId) select p);   

    IEnumerable<ct_Account> accounts = (from a in orgcontext.ct_AccountSet where a.ct_householdid.Id.Equals(accountId) select a);

    PS: Check your entity names

     

     


    Hope this helps. Amar

    CRM Forum Guidance on how to Help Us Help You



    Monday, October 10, 2011 8:56 PM
  • after I changed to asenumerable the code worked once ...the plan had the populated plan values ...but the next time I debugged it said

    function timedout.I am unable to debug.Without denbugging the code just deactivates the client even though the client has active plans.

    I have been working on this code for the past two weeks.I just cannot figure out why this query doesnt seem to work.

     


    Akila
    Tuesday, October 11, 2011 2:25 PM
  • I tried this but plan[0] doesnot show the method getattributevalue ..

     


    Akila
    Tuesday, October 11, 2011 2:26 PM
  • I am doing early binding ..but orgcontext.  is not showing the ct_planSet ...?
    Akila
    Tuesday, October 11, 2011 2:27 PM
  • Are you running your plugin in the Sandbox?  If so, the debug process tends to make the CRM Sandbox exe switch to a different thread after about 30 seconds.  There is a registry setting you can change to allow more time in debugging Sandbox code:

    HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MSCRM/SandboxDebuhPlugins

    Set the value to 1, then restart the Sandbox Service on the CRM Server.

    -JayB

    Tuesday, October 11, 2011 3:00 PM
  • I chose None when I register the plugin ...Is that what you are talking about?


    Akila
    Tuesday, October 11, 2011 3:38 PM
  • If you want to use early bind entities in your plugin you must compile this line in your plugin assembly:

    [assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()]


    Gonzalo | gonzaloruizcrm.blogspot.com

    Tuesday, October 11, 2011 3:42 PM
    Moderator
  • Yes, but if you're not running in a sandbox environment, you should not have a problem maintaining the thread for debugging.  Your actual query seems simple enough.  Will it work if you switch from Linq to QueryExpression?

    http://msdn.microsoft.com/en-us/library/gg328300.aspx

    or FetchXml?

    http://msdn.microsoft.com/en-us/library/gg328332.aspx

    Tuesday, October 11, 2011 3:52 PM
  • I no more have the error .But the client get deactivated since the plan doesnot popluate the values .
    Akila
    Tuesday, October 11, 2011 4:03 PM
  • Hi All,

    I changed the line of code to

    IEnumerable<ct_plan> plan = (from p in tempContext.CreateQuery<Ct_plan>() where p.ct_clientid.Id == accountId && p.statecode.Equals(code) select p).AsEnumerable<Ct_plan>();
    IEnumerable<ct_account> account = (from a in tempContext.CreateQuery<Ct_account>() where a.ct_householdid.Id.Equals(accountId) select a).AsEnumerable<Ct_account>();
    
    if (Enumerable.Count(plan)>0)
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Plans are open for this client");
                                    }
    if (Enumerable.Count(account) > 0)
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Accounts are open for this client");
                                    }


    Since my interest is to know if any active plan exists the above code meets the buisness requirement but I would be interested in finding out how to cast the entity type to ct_plan type which is still a mystery.

    Thanks for all your responses! All your responses helped me dig more.

    Gratefuly,

    Akila

     

     


    Akila
    Wednesday, October 12, 2011 1:22 PM
  • Feel free to come back and mark them all as helpful then.  ;)
    Jamie Miley
    Check out my about.me profile!
    http://mileyja.blogspot.com
    Linked-In Profile
    Follow Me on Twitter!
    Wednesday, October 12, 2011 6:52 PM
    Moderator
  • ClientCredentials creds = new ClientCredentials();
                                creds.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
                                string url = string.Format("http://{0}/{1}/XrmServices/2011/Organization.svc", Properties.Settings.Default.Server, Properties.Settings.Default.Organization);
                                IEnumerable<Ct_plan> plan;
                                IEnumerable<Ct_account> account;
                                using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(new Uri(url), null, creds, null))
                                {
                                    serviceProxy.EnableProxyTypes();
                                    IOrganizationService tempService = (IOrganizationService)serviceProxy;
                                    OrganizationServiceContext tempContext = new OrganizationServiceContext(tempService);
                                    plan = (from p in tempContext.CreateQuery<Ct_plan>() where p.ct_clientid.Id == accountId && p.statecode.Equals(code) select p).AsEnumerable<Ct_plan>();
                                    account = (from a in tempContext.CreateQuery<Ct_account>() where a.ct_householdid.Id.Equals(accountId) select a).AsEnumerable<Ct_account>();
                                    
                                    if (Enumerable.Count(plan)>0)
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Plans are open for this client");
                                    }
                                    if (Enumerable.Count(account) > 0)
                                    {
                                        throw new InvalidPluginExecutionException("Client cannot be deactivated : Accounts are open for this client");
                                    }
                                }
    
    


    Akila
    • Marked as answer by CRM Plugins Tuesday, October 18, 2011 8:18 PM
    Tuesday, October 18, 2011 8:18 PM
  • I'm a little late to the party on this thread - however it's worth saying you will get this error on linq queries using early bound types. To prevent this error add the following line up near the top of your code, where the context and factory objects are being set:

      ((IProxyTypesAssemblyProvider)context).ProxyTypesAssembly = typeof(Contact).Assembly;

    Where "Contact" is any type from your early bound class file.

    Also note that you need to do the same in any custom workflow assemblies too. Unfortunately though the ProxyTypesAssembly property is not public on the workflow context object. It can be set with a nifty bit of reflection. See : http://blog.orangegecko.com.au/2011/12/05/custom-workflow-activities-and-early-bound-entity-classes/ for details on this.


    Paul Dowman, CRM Developer

    Tuesday, December 18, 2012 4:13 PM