Friday 18 September 2009

SAP to Microsoft .NET Integration - Fixes required to WSDL after referencing SAP BAPI WSDLs to work with .NET Service References in Visual Studio 2008

After referencing a Web Service that is based on a SAP BAPI (as opposed to a SAP Enterprise Service), you may need to save and modify the WSDL so to remove reserved words in the file. Otherwise, you will get compile-time errors from the Service Reference generated code such as:


An object reference is required for the non-static field, method, or property 'SharePointCustomLookup.CostCentreSearchService.Bapiret2.System.get'


Solution/Fix:
1. Save the WSDL from the HTTP location to your local machine (you can get this WSDL location if it is already set up from transaction /soamanager in SAP GUI). Open up the wsdl in your fave text editor.
2. Replace all instances of “System” with “SYSTEM” (To avoid conflicts with the System namespace in .NET)
3. Replace all instances of “parameters” with “parameter” so that parameters are read correctly by Visual Studio 2008.
4. Update your service reference to use the locally modified WSDL (which should have the correct endpoints to the web services on your SAP PI/ECC Server )

These modifications to the WSDL is not required for all BAPI Web Service calls - only ones which exhibit the compile-time issue.




One other important thing to note is that if your BAPI has an input parameter, then you have to instantiate the parameter AND all the lists and arrays which make up that input parameter - otherwise you won't get a return result.

e.g. For calling a Project Definition GetList BAPI, you have to instantiate parameter and the Project Definition List with a zero-sized array - otherwise you will NOT get any values back - and yet receive no error.


//You must instantiate the input parameter and any lists/arrays within that
//parameter for any results to be returned
Z_BAPI_PROJECTDEF_GETLISTClient client = new Z_BAPI_PROJECTDEF_GETLISTClient();
ProjectdefGetlist parameter = new ProjectdefGetlist();
parameter.ProjectDefinitionList = new Bapiprexp[0];
ProjectdefGetlistResponse response = client.ProjectdefGetlist(parameter);

Fix For SharePoint 2007 Workflow - "WorkflowValidationFailedException: The workflow failed validation."

If your workflow fails and goes to a status of "Failed on Start (retrying)", and you have declarative rule conditions in your workflow (or RuleSets), it is likely that your workflow cannot be loaded due to a validation error like the one below:

Engine RunWorkflow: System.Workflow.ComponentModel.Compiler.WorkflowValidationFailedException: The workflow failed validation.

FULL EXCEPTION FROM ULS:
08/31/2009 11:54:56.68 w3wp.exe (0x10DC) 0x047C Windows SharePoint Services Workflow Infrastructure 936l High Engine RunWorkflow: System.Workflow.ComponentModel.Compiler.WorkflowValidationFailedException: The workflow failed validation. at System.Workflow.Runtime.WorkflowDefinitionDispenser.ValidateDefinition(Activity root, Boolean isNewType, ITypeProvider typeProvider) at System.Workflow.Runtime.WorkflowDefinitionDispenser.LoadRootActivity(Type workflowType, Boolean createDefinition, Boolean initForRuntime) at System.Workflow.Runtime.WorkflowDefinitionDispenser.GetRootActivity(Type workflowType, Boolean createNew, Boolean initForRuntime) at System.Workflow.Runtime.WorkflowRuntime.InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance) at System.Workflow.Runtime.WorkflowRuntime.Load(Guid key, CreationContext con... 08/31/2009 11:54:56.68* w3wp.exe (0x10DC) 0x047C Windows SharePoint Services Workflow Infrastructure 936l High ...text, WorkflowInstance workflowInstance) at System.Workflow.Runtime.WorkflowRuntime.GetWorkflowExecutor(Guid instanceId, CreationContext context) at System.Workflow.Runtime.WorkflowRuntime.InternalCreateWorkflow(CreationContext context, Guid instanceId) at System.Workflow.Runtime.WorkflowRuntime.CreateWorkflow(Type workflowType, Dictionary`2 namedArgumentValues, Guid instanceId) at Microsoft.SharePoint.Workflow.SPWinOeHostServices.Send(SPWinOeWorkflow winoeworkflow, SPWorkflowEvent e) at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(Guid trackingId, SPWorkflowHostService host, SPWorkflow workflow, Collection`1 events, TimeSpan timeOut)



The Fix:

As described in http://blog.hhebnes.no/?tag=/workflows, the fix is to:

Edit the Visual Studio project file (using notepad) and add the second line below:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.5\Workflow.Targets" />

Then reload the project and redeploy the wsp and everything will hopefully work. I suspect this might be an issue with WSPBuilder and the project it creates as it doesn't create .NET 3.5 projects by default.

Wednesday 16 September 2009

InfoPath 2007 - Issue when adding Web Reference in Code Behind to SAP Enterprise Service


There is a bug when adding Web References to secured WSDL files in InfoPath 2007 Code (in Visual Studio Tools for Applications aka VSTA). For example, I received the following error when adding a Web eference to a SAP enterprise service:

Unable to cast COM object of type 'System.__ComObject' to interface type 'EnvDTE.IVsExtensibility'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{3C536122-57B1-46DE-AB34-ACC524140093}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

The simple fix is to save the wsdl file to your local file system e.g. C:\mySavedWSDL.wsdl) and use that wsdl file as a reference rather than pointing to the secured HTTP location for your WSDL source.