locked
SDK 4.0.12 crmsvcutil

    Question

  • Hello,

     

    I'm using the generated classes from crmsvcutil tool with WCF Data Services to access it thru javascript from the crm forms. each time i try to do query projection like /Customers(guid'd29c0486-645e-df11-8444-00155d443e09')/PrimaryContact?$select=FullName

    i get this error: The service does not expose IProjectionProvider interface which is required when projection is requested. Request could not be processed.

    any ideas??

    Thanks

    Sunday, July 4, 2010 1:45 PM

Answers

  • Mohamed, your original example only selected one property FullName so I just reproduced. Here is an example with 3 properties.

    	public class AccountDetails
    {
    public string AccountName { getset; }
    public string AccountNumber { getset; }
    public string MainPhone { getset; }
    }
    		public static void InitializeService(DataServiceConfiguration config)
    {
    config.UseVerboseErrors = true;
    config.SetEntitySetAccessRule("*"EntitySetRights.All);
    config.SetServiceOperationAccessRule("*"ServiceOperationRights.All);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    config.RegisterKnownType(typeof(AccountDetails));
    }
    		[WebGet]
    public IQueryable<AccountDetails> GetAccountDetails(Guid id)
    {
    var details = from a in this.CurrentDataSource.Accounts
    where a.AccountID == id
    select new AccountDetails() 

    AccountName = a.AccountName,
    AccountNumber = a.AccountNumber, 
    MainPhone = a.MainPhone 
    };

    return details;
    }
    There are limitations as the class you project into can only have scalar data types. Hope this helps.
    Tuesday, July 6, 2010 3:19 PM

All replies

  • You are out of luck! $select statements are not supported. This problem is being discussed here http://social.msdn.microsoft.com/Forums/en/adodotnetdataservices/thread/366086ee-dcef-496a-ad15-f461788ae678 and is caused by the fact that CrmDataContext implements the IExpandProvider interface which in turn causes the DataService to lose support for $select projections (as I read it). 

    The generated classed do support LINQ projections into anonymous types on the server so you could extend your service to have operations that "shape" the data as a work around? See http://msdn.microsoft.com/en-us/library/dd744841.aspx .

    Hopefully the next version of the SDK will have this fixed as the CRM DataServices are NOT useful in the current form due to the amount of data transferred!

     

    Monday, July 5, 2010 9:31 PM
  • I was actually counting on this feature to query the server from javascript within crm forms. as some business logic require that. it's much easier to use projection for certain properties. the default implementation will return alot of data. huge amount of data transfered.

    I guess i try to wrap the entities i want in a different context and use the on server projection to get the data i want. not sure how to do that, but i'm gonna try :)

     

    Thanks.

    Monday, July 5, 2010 10:36 PM
  • Here is an example of what I have been doing:

    	public class MSCrm : DataService<Test.MSCrm.DataContext>
    {
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
    config.UseVerboseErrors = true;
    config.DataServiceBehavior.AcceptProjectionRequests = true;
    config.SetEntitySetAccessRule("*"EntitySetRights.All);
    config.SetServiceOperationAccessRule("*"ServiceOperationRights.All);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }

    [WebGet]
    public IQueryable<string> GetAccountName(Guid id)
    {
    var accountName =  from a in this.CurrentDataSource.Accounts

    where a.AccountID == id
    select a.AccountName;

    return accountName;
    }
    }

    I then use the query http://localhost:18489/mscrm.svc/GetAccountName?id=guid'611abfc2-cf57-df11-8010-000c2992ec33'

    Not very nice IMO but it does the trick.

    Monday, July 5, 2010 11:13 PM
  • if you want to just get one property value such as account name. you can just call the property

    http://localhost:13073/EntityService.svc/Customers(guid'd29c0486-645e-df11-81a4-00155d736e09')/Name

    this will work, my problem comes when i want to have 3 different properties.

    Tuesday, July 6, 2010 9:22 AM
  • Mohamed, your original example only selected one property FullName so I just reproduced. Here is an example with 3 properties.

    	public class AccountDetails
    {
    public string AccountName { getset; }
    public string AccountNumber { getset; }
    public string MainPhone { getset; }
    }
    		public static void InitializeService(DataServiceConfiguration config)
    {
    config.UseVerboseErrors = true;
    config.SetEntitySetAccessRule("*"EntitySetRights.All);
    config.SetServiceOperationAccessRule("*"ServiceOperationRights.All);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    config.RegisterKnownType(typeof(AccountDetails));
    }
    		[WebGet]
    public IQueryable<AccountDetails> GetAccountDetails(Guid id)
    {
    var details = from a in this.CurrentDataSource.Accounts
    where a.AccountID == id
    select new AccountDetails() 

    AccountName = a.AccountName,
    AccountNumber = a.AccountNumber, 
    MainPhone = a.MainPhone 
    };

    return details;
    }
    There are limitations as the class you project into can only have scalar data types. Hope this helps.
    Tuesday, July 6, 2010 3:19 PM
  • Ian,

    Can you do a similar workaround to allow yourself to create/update records in CRM through a WCF Data Service? Having issues with this, per this thread: http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/dca50354-28c7-4811-bc99-7b802cc2d3a2/#665f939e-9e45-495e-8b3e-4f400c3a98bb


    Web: http://invoc.net Blog: http://invoc.net/CRM_BPOS_Blog
    Wednesday, August 11, 2010 6:02 PM
  • Anyone knows if this issue is fixed in the new release 4.0.13?
    Sunday, November 28, 2010 7:15 AM