locked
CRM 2011 : Create entity record using Silverlight and SOAP RRS feed

  • Question

  • Hi Forum,

    I have a silverlight page which has a Datagrid containing custome entity records. ( Idea is to crete multiple records at once)

    I want functionality where end user can enter 20 records at once and when user clicks Save button, all 20 records should be created in CRM. I want to do this using SOAP.

    I want to go thru each row of the datagrid and save it as a entity record in CRM.

    I Have looked at the SDK example but that only reads Account entity and not showing CRUD operation using SOAP/Silverlight ( though it has a good example for using REST which I don't want to use).

    Any good resource or link ?

    Cheers


    • Edited by CRM Thirsty Monday, October 10, 2011 3:02 AM
    Monday, October 10, 2011 3:01 AM

Answers

All replies

  • Hi,

    You will need to hold the data from the grid in an observable collection. On the save button click you can loop through the records in the observable collection and create the records one at a time using the SOAP requests.

    HTH

    Sam


    Web: http://www.inogic.com
    Blog: http://inogic.blogspot.com
    Email: news@inogic.com
    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    Monday, October 10, 2011 7:54 AM
  • Hi Sam,

    Following is my code. I am reading value from datagrid and putting into the observable collection(which is of type of my custom class)

     I am not sure how to pass my observable colletion to the request object. Please guide me if this is not the correct way to create CRM records thru SOAP from Silverlight

    Thanks for your time

     private void SaveButton_Click(object sender, RoutedEventArgs e)
            {
    
                ObservableCollection<ContactPoint> obcCP = new ObservableCollection<ContactPoint>();
    
                foreach(ContactPoint cpRow in ConactPointGrid.ItemsSource)   // Contactpoint is my class holding all data. ContactpointGrid is datagrid
                {
                    ContactPoint saveCP = new ContactPoint();
    
                    saveCP.FirsName = cpRow.FirstName;
                    saveCP.LastName = cpRow.LastName;
                    saveCP.Postcode = cpRow.Postcode;
                    
    
                    obcCP.Add(saveCP);
                }
               
    
                OrganizationRequest request = new OrganizationRequest(); //{ RequestName = "Create" };
                request.RequestName = "Create";
                
                // How do I pass my observable collection in this request ?
    
                IOrganizationService service = SilverlightUtility.GetSoapService();  // helper method from SDK
    
                service.BeginExecute(request, new AsyncCallback(SaveButton_ClickCallBack), service);
     
               
            }
    
    // My call back method
    
      private void SaveButton_ClickCallBack(IAsyncResult results)
            {
    
    

     

     

    OrganizationResponse response = ((IOrganizationService

    )results.AsyncState).EndExecute(results);

     

     

     

     

    }  

     





    • Edited by CRM Thirsty Tuesday, October 11, 2011 4:24 AM
    Tuesday, October 11, 2011 12:39 AM
  • In one of my Silverlight WebResource I had used following code

    Here is a local class which I implemented using INotifyPropertyChanged and which hold User Data to be shown in Grid

    private void UpdateUserSettigns(UserSettings userSettings)
            {
                Entity e = new Entity();
    
                e.LogicalName = "usersettings";
    
                e["systemuserid"] = userSettings.SystemUserId;
                 //e.Attributes.Add(new KeyValuePair<string, object>("systemuserid", userSettings.SystemUserId));
    
                //e["systemuserid"] = Guid.NewGuid();
                e["paginglimit"] = userSettings.PagingLimit;
                //e.Attributes.Add(new KeyValuePair<string, object>("paginglimit", userSettings.PagingLimit));
    
    
                if (string.Compare(userSettings.DefaultCalendarView, "Day") == 0)
                {
                    e["defaultcalendarview"] = 0;
                    //e.Attributes.Add(new KeyValuePair<string, object>("defaultcalendarview", 0));
                }
                else if (string.Compare(userSettings.DefaultCalendarView, "Week") == 0)
                {
                    e["defaultcalendarview"] = 1;
                    //e.Attributes.Add(new KeyValuePair<string, object>("defaultcalendarview", 1));
                }
                else if (string.Compare(userSettings.DefaultCalendarView, "Month") == 0)
                {
                    e["defaultcalendarview"] = 2;
                    //e.Attributes.Add(new KeyValuePair<string, object>("defaultcalendarview", 2));
                }
    
                e["getstartedpanecontentenabled"] = userSettings.GetStartedPaneContentEnabled;
    
                e["homepagearea"] = userSettings.HomepageArea;
                e["homepagesubarea"] = userSettings.HomepageSubarea;
    
                e["timezonecode"] = this.timeZoneMasterList.TimeZoneList.Where(a => a.UserInterfaceName == userSettings.TZUserInterfaceName).FirstOrDefault<TimeZone>().TimeZoneCode;
    
                try
                {
                    IOrganizationService service = SilverlightUtility.GetSoapService();
    
                    service.BeginUpdate(e, new AsyncCallback(EntityUpdate_AsyncCallback), service);
                }
                catch (Exception ex)
                {
                    this.ReportError(ex);
                }
            }
    
            private void EntityUpdate_AsyncCallback(IAsyncResult result)
            {
                ((IOrganizationService)result.AsyncState).EndUpdate(result);
    
                this.Dispatcher.BeginInvoke(() => SaveBtn.IsEnabled = true);
            }
    

    HTH


    makeer | myencounterwithcrm.wordpress.com | CRM2011 User Settings Utility | CRM2011 Lookup Preview
    • Proposed as answer by RoohiMVP Tuesday, October 11, 2011 5:20 AM
    Tuesday, October 11, 2011 4:24 AM
  • Hi

    The approach provided by makeer below is the way to go about with it. You need to make an entity object and set its properties similar to the way it used to be done using the Microsoft.SDK.DLL and then call service.begincreate to create the record. In the callback function you need to call the endcreate method and pass teh async result as a parameter. You can also get the Guid of the newly created record in the callback function.

    HTH

    Sam


    Web: http://www.inogic.com
    Blog: http://inogic.blogspot.com
    Email: news@inogic.com
    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    Tuesday, October 11, 2011 5:42 AM
  •  Hi Makeer,

    How you have constructed your class ? because datagrid doesn't accept CRM complex datatypes like Lookups(entityrefernece) and Optionsets(Optionsetvalues).

    I am using same grid to show records and to Create records.  To explain in detail, follwing is the flow of my logic.

    1. user presented with Silverlight Page.

    2. This page has one text box ( to enter search text) and one button to with name "Search" to perfrom query.

    3. Page also has "New" button when user click will show empty grid to enter 10 records.

    4. One datagrid for above 2 purpose.

    4. 'save; button to save 10 records at a time to CRM entered into the grid.

     

    Now, while showing search result I am holding the query result into custom class which has same attributes as actual entity but datatype is all "string" in custom class.

    and doing follwoing

    OrganizationResponse

     

    response = ((IOrganizationService

    )result.AsyncState).EndExecute(result);

     

    EntityCollection results = (EntityCollection)response["EntityCollection"

    ];

     

    if

    (results.Entities.Count != 0)

    {

     

    foreach (Entity ct in

    results.Entities)

    {

     

    ContactPoint ItemCP = new ContactPoint

    ();

     

     

    if (ct .GetAttributeValue<Test.CrmSdk.EntityReference>("new_salespersonid") != null

    )   // Test = Namespace, CrmSdk = SOAP service reference

    {

    ItemCP.Customer = ct .GetAttributeValue<Test.CrmSdk.

    EntityReference>("new_salespersonid").Name; // this is look up value in CRM

    //  Rest of the values goes here....

     

     

    }

    }

    ctList.Add(ItemCP);  // ctlist is getting all the records

    Dispatcher.BeginInvoke(() =>

    {

     

     

    this

    .CTGrid.ItemsSource = ctList;

    });

    =========================================

     

     

    // My custome class to hold records from query and to show it on form

     

     

    public class ContactPoint

    {

     

     

    public string ContactPointName { get; set

    ; }

     

     

    public string FirstName{ get; set

    ; }

     

     

    public string LastName{ get; set

    ; }

     

     

    public string Resident{ get; set

    ; } // this is optionset in CRM record

     

     

    public string Customer { get; set

    ; } // this is Lookup in CRM record

     

     

    public string Primary Contact{ get; set

    ; } // this is look up in CRM record

    }

     

     

    ======================end class===============================

     

     

     

     

     

     

    This works fine and records are showing perfectly OK as per the value entered into the search box.

    Problem starts,when user click on "New" button and same grid appears to enter 10 records. After entering the record when use Click 'Save' button

    Follwoing your approach I have created another class but this time with CRM Datatypes and not string.

    =====================================================

    // Holding classto create records in CRM

     

     

    public class

    CT

    {

     

     

    public CrmSdk.OptionSetValue Resident{ get; set

    ; }

     

     

    public CrmSdk.EntityReference Customer { get; set; }

    ..rest of the values

     

     

    }

    ======================== end class ===========

    Following is a save method to create recrods

    private

     

     

    void SaveButton_Click(object

    sender, RoutedEventArgs e)

    {

     

     

    foreach(CT ctRow in

    CPGrid.ItemsSource) // Exception is thorwn here saying can't convert from type 'ContactPoint' to 'CP' which makes sense as CPGrid.Itemsource is of type 'ContactPoint' while 'ctRow' is of type 'CT'

    {

    Entity cp =

     

    new

    Entity();

    sp.LogicalName =

     

    "new_contactpoint"

    ;

     

    sp[

     

    "new_customerid"] = new EntityReference() { Id = new Guid("{7D1C2E6D-C5F2-DF11-BC1B-000C29B3EC9A}"), LogicalName = "account"

    , Name = ctRow.Customer.Name };

    sp[

     

    "new_resident"] = new OptionSetValue() { Value = ctRow.Resident.Value };

    rest of the values.....

     

    service.BeginCreate(cp,

    new AsyncCallback(SaveButton_ClickCallBack), service);

    }

     

     

    }

    ================ End method ============

    Following is my call back method

    private void SaveButton_ClickCallBack(IAsyncResult results)

    {

    ((

     

    IOrganizationService

    )results.AsyncState).EndCreate(results);

    }

    ====================================================

      

    When debugging, exception is thrown on foreach loop which I have explained in above code line.

    So Issue is while pouplating grid, datagrid can not take CRM specific datatype and while creating record Casting is failed to convert into CRM DataType.

    any idea? ( Alternatively, I can create another grid and toggle it based on the user selection but that's the last resource.)

    Hope I explained it properly.

    Thanks to you and Sam for your time.

    

    

    Tuesday, October 11, 2011 11:28 PM
  • I did not read the whole post but this will not work

     

    ItemCP.Customer = ct .GetAttributeValue<Test.CrmSdk.EntityReference>("new_salespersonid").Name;

    You are trying to assign string to a entityreference or lookup field.

    What I will do , I will create a sepearte method that will return the entityreference by passing the name field

    It will looksomething like

     

    Test.CrmSdk.EntityReference cust; ///// at the top like a public variable

    then call this function getLookupValue(ct .GetAttributeValue<Test.CrmSdk.EntityReference>("new_salespersonid").Name);

    In the callback function it will assign the entityrefrence to the cust variable.

     

     ItemCP.Customer = cust;

    In that getLookupValue function I write a code like querybyattribute then get the id of the record

    and return entityreference by using id and the name.

    But it will be very hard because of async calls you can't get the value straignt away, you need to somehow find out when all the async calls has been finish before you call save method.

    You may use some kind of counter.

    I hope this helps.


    Amreek Singh Senior CRM Consultant CDC Praxa Sydney, Australia [URL=http://mscrmshop.blogspot.com]http://mscrmshop.blogspot.com[/URL]
    • Edited by Amreek Singh Wednesday, October 12, 2011 12:37 AM
    • Proposed as answer by Amreek Singh Wednesday, October 12, 2011 12:37 AM
    Wednesday, October 12, 2011 12:36 AM
  • Hi,

    First of all apologies for such a long and unformatted code posting. It's clearly not readable.

    I will keep this simple and rephrase my question as I am only doing this excercise for my better understanding of SOAP/Silverligt/CRM 2011 combination.

    Now, all I want to do is to create record in CRM when user enter 1 row in datagrid which is in Silverlight page.

    That grid columns contains text field only for data entry  but data entered into that fields are of type  Looksup,Optionset and text values in CRM record.

    How do I read each row of the datagrid and set Entity record value in code as mentioned above by Makeer's code.

    Cheers

    Wednesday, October 12, 2011 1:33 AM
  • Hi Buddy,

    Makker code is not using any lookup field or option fields at all. His fields are string, boolean and integers.

    if it is  an option set and you are adding integers, its simple

    you can use something like

     

    OptionSetValue ops = new OptionSetValue

    ();

    ops.Value =

    integervalue.

    But for entityreference you have to have  a guid.

    I think for you the easiest thing to do is

    In your grid columns add combox or drop down box and fill them with relevent value

    when you select the value you have access to guids, you can do same for optionsets.

    create a seperate class to retrieve all sales man and then use that as datasourcefor the combobox.

    cmbsales.DisplayMemberPath =

     

    "Name";

    cmbsales.SelectedValuePath = "ID";

    When people choose a sales man from the drop down box

    cmbSales.SelectedValue.ToString(); will give you guid for the sales man

    then you can use that guid and entityname to create a entityreference to save it back to CRM

    I hope this helps.

     

     
    Amreek Singh Senior CRM Consultant CDC Praxa Sydney, Australia [URL=http://mscrmshop.blogspot.com]http://mscrmshop.blogspot.com[/URL]
    • Proposed as answer by Amreek Singh Wednesday, October 12, 2011 2:56 AM
    Wednesday, October 12, 2011 2:56 AM
  • For binding Data with SL DataGrid I created a Class which is Populated with Result of SOAP RetrieveMultiple response.

    I had converstion methods for converting DG Itemsource to CRM Entity and Vise Versa.

    Populating of CRM Entity remains same as we do it for Late Binding.

    HTH


    makeer | myencounterwithcrm.wordpress.com | CRM2011 User Settings Utility | CRM2011 Lookup Preview
    • Marked as answer by CRM Thirsty Thursday, October 13, 2011 5:02 AM
    Wednesday, October 12, 2011 3:16 AM
  • Hi Makeer,

    Would you please share your conversion method ?

     

    Thanks.

    Wednesday, October 12, 2011 3:33 AM
  • Hi Amreek,

    The only issue with this is, dropdown list becomes very long in appreance. (from GUI point of view).

    But I like that idea and will use in more fitting situation.

    Thank you.

    Wednesday, October 12, 2011 3:36 AM
  • The silverlight light async callback method make it difficult to retrieve a record in a same method.
    Amreek Singh Senior CRM Consultant CDC Praxa Sydney, Australia http://mscrmshop.blogspot.com
    Wednesday, October 12, 2011 5:53 AM
  • Hi,

    Can someone help a beginer like me ?

    I'm just trying to understand in this uge jungle of information on how to go about using CRM with Silverlight
    I just need a very simple sample example :) Like creating an entity in CRM and just have it shown in a grid in Silverlight

    But I'm facing a huge challenge looking the web, and pieces on forums.  I've tried looking at the sample SoapForsilverlightSample but wow, I don't think this is very simple.

    What is the simpliest way and code example somewhere if any to just populate a SL grid with an entity data and of couse being able update any changes done in the grid

    thank you very much

     


    Marcheur extrême...
    Tuesday, November 8, 2011 7:38 PM