Code Snippet: Set the Parameters Object Before Calling a GenericInvoker

Applies to: SharePoint Server 2010

The following code example shows how to set the Parameters object before calling a GenericInvoker.

Prerequisites:

  • Microsoft SharePoint Server 2010 or Microsoft SharePoint Foundation 2010.

  • Microsoft .NET Framework 3.5 and Microsoft Visual Studio.

To use this example

  1. Start Visual Studio and create a C# Console Application project. Select .NET Framework 3.5 when you create the project.

  2. From the View menu, click Property Pages to bring up the project properties.

  3. In the Build tab, for the Platform target, select Any CPU.

  4. Close the project properties window.

  5. In Solution Explorer, under References, remove all project references except for System and System.Core.

  6. Add the following references to the project:

    1. Microsoft.BusinessData

    2. Microsoft.SharePoint

    3. System.Data

    4. System.Web

    5. System.Xml

  7. Replace the autogenerated code in Program.cs with the code listed at the end of this procedure.

  8. Replace siteUrl, nameSpace, entityName, and methodInstanceName with valid values.

  9. Edit the code for the steps 4, 5, and 6 below as appropriate. The data entered in steps 4, 5, and 6 must match the parameters and types defined for the generic invoker's method in the BDC model.

  10. Press F6 to build the solution.

  11. Press Ctrl+F5 to run the sample.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Web;
using Microsoft.BusinessData.MetadataModel.Collections;
using Microsoft.BusinessData.Infrastructure;

namespace Microsoft.SDK.Sharepoint.Samples
{
    class Program
    {
        static void Main(string[] args)
        {
            string siteURL = "<siteUrl>";
            string entityNS = "<nameSpace>";
            string entityName = "<entityName>";
            string methodInstanceName = "<methodInstanceName>";
            using (SPSite site = new SPSite(siteURL))
            {
                using (new Microsoft.SharePoint.SPServiceContextScope(
                    SPServiceContext.GetContext(site)))
                {
                    BdcService service = 
                        SPFarm.Local.Services.GetValue<BdcService>
                        (String.Empty);
                    IMetadataCatalog catalog = 
                        service.GetDatabaseBackedMetadataCatalog(
                        SPServiceContext.Current);                                      

                    IEntity entity = 
                        catalog.GetEntity(entityNS, entityName);
                    ILobSystemInstance LobSysteminstance = 
                        entity.GetLobSystem().
                        GetLobSystemInstances()[0].Value;

                    // Step 1: Obtain the MethodInstance from Entity.
                    IMethodInstance myGenericInvoker = 
                        entity.GetMethodInstance(
                        methodInstanceName, 
                        MethodInstanceType.GenericInvoker);

                    // Step 2: Obtain the Parameters using the Method.
                    IParameterCollection parameters = 
                        myGenericInvoker.GetMethod().GetParameters();

                    // Step 3: Create the Object[] that needs 
                    // to be passed in.
                    Object[] rawParameters = 
                        new Object[parameters.Count];

                    // Step 4: For simple types and known types you can 
                    // just create the instance and assign it to the 
                    // parameter. 
                    // Known types are the types that are known to you at 
                    // compile time. These are the types that are in .NET Framework,              
                    // BDC, or assemblies in the global assembly cache. The types that are 
                    // defined in your proxy are NOT known types, as BDC 
                    // will generate another proxy for the Web service. 
                    rawParameters[0] = 32;
                    rawParameters[1] = "A";
                    rawParameters[2] = new System.Data.DataTable("X");

                    // Step 5: For "unknown types" (such as types defined 
                    // in your proxy), you need to access to the type 
                    // reflector to instantiate the complex types 
                    // defined in your proxy.
                    ITypeReflector reflector = parameters[3].TypeReflector;
                    ITypeDescriptor rootTypeDescriptor = 
                        parameters[3].GetRootTypeDescriptor();
                    Object instance = reflector.Instantiate(
                        rootTypeDescriptor);
                    // Or if you want to have the instance object 
                    // use default values 
                    // defined in your model, use the following:
                    // Object instance = 
                    //     reflector.Instantiate(
                    //         rootTypeDescriptor, myGenericInvoker); 
                    // Or if the root of the parameter is a collection, 
                    // use the following:
                    // Object instance = 
                    //     reflector.Instantiate(rootTypeDescriptor, 55); 
                    // Or if the root of the parameter is a collection 
                    // and you want to use default values, 
                    // use the following: 
                    // Object instance = 
                    //     reflector.Instantiate(
                    //     rootTypeDescriptor, 55, myGenericInvoker); 

                    rawParameters[3] = instance;

                    // Step 6: To set values in the complex object 
                    // you’ve just created, you can use the Set
                    // method on TypeReflector.
                    ITypeDescriptor child = 
                        rootTypeDescriptor.GetChildTypeDescriptors()[3];
                    // Alternatively you can look over them and 
                    // check the name, 
                    // but since you are using generic invoker, 
                    // it is most likely that you have intimate 
                    // knowledge of the method.
                    // If your object is a structure:
                     reflector.Set(
                        child, rootTypeDescriptor, ref instance, "value"); 
                    // Or if your object is a collection:
                    // reflector.Set(
                    //     child, rootTypeDescriptor, ref instance, 
                    // "value", /*index*/ 2); 
                    // If you want to set values in deeper parts of 
                    // the structure, you’ll need to navigate to the 
                    // relevant type descriptors, 
                    // and provide the corresponding root object, 
                    // parent type descriptor and child type descriptor. 
                    // You can also create instances of deeper 
                    // TypeDescriptors and assign the created instances 
                    // to parts of the structure using the Set method.

                    // NOTE: Repeat steps 5 and 6 for all the values 
                    // you need to create and set.

                }
            }
        }
    }
}

A useful shortcut is to use IMethodInstance.GetMethod().CreateDefaultParameterInstances(IMethodInstance), which will return an Object[] of fully instantiated back-end arguments based on default values in the model, and then override or change these defaults using the TypeReflector as shown in the following code. CreateDefaultParameterInstances() is a shortcut for the previous steps 3 to 5.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Web;

namespace Microsoft.SDK.Sharepoint.Samples
{
    class Program
    {
        static void Main(string[] args)
        {
            string siteURL = ""<siteUrl>";
            string entityNS = "<nameSpace>";
            string entityName = "<entityName>";
            string methodInstanceName = "<methodInstanceName>";
            using (SPSite site = new SPSite(siteURL))
            {
                using (new Microsoft.SharePoint.SPServiceContextScope(
                    SPServiceContext.GetContext(site)))
                {
                    BdcService service = 
                        SPFarm.Local.Services.GetValue<BdcService>(
                        String.Empty);
                    IMetadataCatalog catalog = 
                        service.GetDatabaseBackedMetadataCatalog(
                        SPServiceContext.Current);

                    IEntity entity = catalog.GetEntity(
                        entityNS, entityName);
                    ILobSystemInstance LobSysteminstance = 
                        entity.GetLobSystem().GetLobSystemInstances()
                        [0].Value;

                    // Step 1: Obtain the MethodInstance from the entity.
                    IMethodInstance myGenericInvoker = 
                        entity.GetMethodInstance(
                        methodInstanceName, MethodInstanceType.GenericInvoker);

                    // Step 2: Obtain the Parameters using the Method.
                    IParameterCollection parameters = 
                        myGenericInvoker.GetMethod().
                        CreateDefaultParameterInstances(IMethodInstance);
                }
            }
        }
    }
}

See Also

Reference

BdcService

Services

IMetadataCatalog

GetDatabaseBackedMetadataCatalog(SPServiceContext)

GetEntity(String, String)

IEntity

GetLobSystem()

GetLobSystemInstances()

ILobSystemInstance

GetMethodInstance(String, MethodInstanceType)

IMethodInstance

IParameterCollection

CreateDefaultParameterInstances(IMethodInstance)