Calling a Web Service using WS and REST Data Services

In Lawson Smart Office 9.1.3 we introduced the REST data service for mashups. In version 10.0.0 we introduced support for SOAP based web services. In 10.0.1 we introduced some new configuration options that will help you to connect to the web services out there.

There are different options available when consuming SOAP web services in Mashups.

1. Data Service and WS
2. Data Service and REST
3. Process Server with TriggerPanel

Data Service and WS is the use of generated proxy code combined with WCF in order to call web services. The advantage with using generated proxy code is that typing comes for free. Any result will be in form of objects according to the service definition. Using Data Service and REST involves using a XML template of the complete SOAP request with replacement variables and submitting the template XML as one request. The template XML can easily be extracted from a WSDL using a free tool such as SoapUI.

I recently recieved an email with two web services that was hard to consume via the WS Data Service. One problem was related to an issue in the configuration tool and the other web service was hard to consume becuase it returned a string that was XML. XML? Isn’t web services always xml? I’ll step you through the process of testing the web service using a tool and the data controls for Mashups.

The WSDLs are:
1. http://www.webservicex.net/CurrencyConvertor.asmx?WSDL
2. http://www.webservicex.net/stockquote.asmx?WSDL

Currency Converter
I usually start my testing by launching the Web service test tool available within Lawson Smart Office, tool://wstest.

I start by loading the WSDL and select the operation to test. Both web services are publically available. I enter the input USD and SEK and press test.

In LSO 10.0.0 you would have seen a message that the result object has no properties. And then you would have seen some strange data. Don’t dispair. It’s an issue with the test tool. In LSO 10.0.1 you will see that there is only one thing that is returned and that is a Double.

Anytime I get into trouble with testing the Web Service I turn to my favorite Web Service test tool – SoapUI. This is a must have if you are testing different REST and SOAP based services or developing your own services. It’s open source and free so just install it. In SoapUI you create a test project and point to the WSDL.

The result from testing ‘Request 1’ is shown in the image below. There you can see that the returned object is the convertion rate.

The convertion rate is returned and it is not wrapped in any result object. This means that the result will be available in the Mashup DataPanel as the Data property, the result from the operation. In many cases you can simply use the DataContext of the control and bind to {Binding .} or when you are interested in a property on the result then it is {Binding Path=PropertyName} or you bind to the DataPanel and it’s result using:

<!– detailPanelNameis the name of the DataPanel, list or detail–>
<Label Name="result" Content="{Binding Path=Data, ElementName=detailPanelName}" />

Here is what the final result looks like:

And here is the complete XAML:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI">
  <Grid.Resources>
  </Grid.Resources>

  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <mashup:DataPanel Name="detail">
    <mashup:DataPanel.DataService>
      <mashup:DataService Type="WS">
        <mashup:DataService.Operations>
          <mashup:DataOperation Name="Read">
            <mashup:DataParameter Key="WS.Wsdl" Value="http://www.webservicex.net/CurrencyConvertor.asmx?WSDL" />
            <mashup:DataParameter Key="WS.Address" Value="http://www.webservicex.net/CurrencyConvertor.asmx" />
            <mashup:DataParameter Key="WS.Operation" Value="ConversionRate" />
            <mashup:DataParameter Key="WS.Contract" Value="CurrencyConvertorSoap" />
        <!--    <mashup:DataParameter Key="FromCurrency" Value="USD" />
            <mashup:DataParameter Key="ToCurrency" Value="ALL" />-->
          </mashup:DataOperation>
        </mashup:DataService.Operations>
      </mashup:DataService>
    </mashup:DataPanel.DataService>
    <Grid Margin="8">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <TextBlock Text="From Currency:" />
      <TextBox Grid.Column="1" Name="fromCurrency" />
      <TextBlock Grid.Row="1" Text="To Currency:" />
      <TextBox Grid.Row="1" Grid.Column="1" Name="toCurrency" />

      <TextBlock Grid.Row="2" Text="Result:" />
      <Label Grid.Row="2" Grid.Column="1" Name="result" Content="{Binding Path=Data, ElementName=detail}" />

      <Button Grid.Row="3" Grid.ColumnSpan="2" Margin="5" Content="Get convertion rate" Width="160" HorizontalAlignment="Right" Name="button">
        <Button.CommandParameter>
          <mashup:Events>
            <mashup:Event SourceEventName="Click" TargetEventName="Read" TargetName="detail" Debug="False">
              <mashup:Parameter TargetKey="ToCurrency" Value="{Binding Path=Text, ElementName=toCurrency}" />
              <mashup:Parameter TargetKey="FromCurrency" Value="{Binding Path=Text, ElementName=fromCurrency}" />
            </mashup:Event>
          </mashup:Events>
        </Button.CommandParameter>
      </Button>

    </Grid>
  </mashup:DataPanel>

  <ui:StatusBar Name="StatusBar" Grid.Row="2" Grid.Column="0" />
</Grid>

Stock quote
Time to check the other SOAP web service. I’ll open the Web service test tool and load the WSDL.
Now I can’t search for LWSN anymore so lets check out the stocks from Microsoft, MSFT.

Here is the result in the Web Service test tool.

My screenshot is from a 10.0.1 version of LSO. If you have something else you can bind to the Data property of the DataPanel and you will see the string. Seeing XML in a SOAP request means that they are returning a xml as a string and that string is defined as a string in the WSDL and not as different complex types. Now I want to know exactly what the response is so I test this service as well in SoapUI.

Here you can see a CDATA block and the beginning of the XML returned. Now this kind of SOAP web service is rather common. The developer use SOAP but as the result they have arbitrary XML. This xml cannot be converted to types and is there for not a good match for the WS data service. Here I have to use REST. However since it returns XML in a CDATA block I might be into trouble. When XML is parsed the value within the CDATA block is eqvivalent with the value of a text node. This means that the XML string will continure to be just and XML string within a XML document.

In version 10.0.1 we added a way to set the XPath to the element that has the XML string and then by setting REST.XPathNodeIsXmlDocument to true in the configuration. We also added the configuraiton option to set ContentType. This web service does not work with content type application/xml so you will not be able to run this mashup in previous versions of LSO (10.0.1 is required).

But if you find yourselft with a web service that returns a CDATA block you should try and set the REST.XPath to the node that has the CDATA block and then set REST.RemoveNamespace to true. This might create a XMLDocument from the node text.

My plan is to use the REST data service with a XML template where I specify the input XML. I could have used the exact same approach for the first web service. Becuase it has a simple structure I was only interested in getting the response as data. I do not care about it’s type for further processing in Mashup events.

If you care about performance you should use REST whenever possible. The reason is that the WS data service has two limitations. The WSDL has to be available and there is one download of the WSDL per LSO session. For REST the template XML is already embedded in the Mashup XAML.

Here is my template as a static resource:

<Grid.Resources>
 <x:String x:Key="templateStock">
  <![CDATA[
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET/">
   <soapenv:Header/>
   <soapenv:Body>
      <web:GetQuote>
         <web:symbol>{symbol}</web:symbol>
      </web:GetQuote>
   </soapenv:Body>
  </soapenv:Envelope>
  ]]>
 </x:String>
<Grid.Resources>

Note the {symbol} in the template. I’m going to send in an event parameter for symbol that will be automatically replaced in the XML.

Since I use REST I need to use XPaths for dealing with the data. I usually test my XPaths in this online test tool..

There are probably more efficeint ways to write the XPaths but I this case I also wanted to demonstrate how to find a node using the local name even if the node is in a default namespace.

Here is the result:

And the XAML:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI">
  <Grid.Resources>
    <x:String x:Key="templateStock">
         <![CDATA[
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET/">
   <soapenv:Header/>
   <soapenv:Body>
      <web:GetQuote>
         <web:symbol>{symbol}</web:symbol>
      </web:GetQuote>
   </soapenv:Body>
</soapenv:Envelope>
]]>
      </x:String>
  </Grid.Resources>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <!-- Form-->
      <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
    <TextBlock Text="Stock Quote" FontSize="18" Margin="8" />

<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="8,8,0,8">
<TextBlock Text="Symbol:" />
<TextBox Width="150" Name="textBoxSymbol" />
<Button Content="OK" Name="okButton">
      <Button.CommandParameter>
        <mashup:Events>
          <mashup:Event TargetName="detail" SourceEventName="Click" TargetEventName="Read">
             <!-- Here I pass in the symbol that is the replacement variable in template XML-->
            <mashup:Parameter TargetKey="symbol" Value="{Binding Path=Text, ElementName=textBoxSymbol}" />
          </mashup:Event>
        </mashup:Events>
      </Button.CommandParameter>
    </Button>
</StackPanel>
  <mashup:DataPanel Name="detail" Grid.Row="3">
    <mashup:DataPanel.DataService>
      <mashup:DataService Type="REST">
        <mashup:DataService.Operations>
          <mashup:DataOperation Name="Read">
            <mashup:DataParameter Key="REST.InputType" Value="XML" />
            <mashup:DataParameter Key="REST.InputXmlTemplate" Value="{StaticResource templateStock}" />
            <mashup:DataParameter Key="REST.HttpMethod" Value="POST" />
            <mashup:DataParameter Key="REST.BaseAddress" Value="http://www.webservicex.net/stockquote.asmx" />
            <mashup:DataParameter Key="REST.AcceptHeader" Value="text/xml" />
            <mashup:DataParameter Key="REST.RemoveNamespace" Value="false" />
            <mashup:DataParameter Key="REST.XPath" Value="//*[ local-name() = 'GetQuoteResponse']" />
            <mashup:DataParameter Key="REST.ContentType" Value="text/xml" />
            <mashup:DataParameter Key="REST.XPathNodeIsXmlDocument" Value="true" />
          </mashup:DataOperation>
        </mashup:DataService.Operations>
      </mashup:DataService>
    </mashup:DataPanel.DataService>
    <Grid Margin="8">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      <!-- Form-->
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <TextBlock Grid.Row="1" Grid.Column="0" Text="Name:" />
      <!--<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding XPath=//Name/text()}" />-->
      <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding XPath=//Name/text()}" />
      <TextBlock Grid.Row="2" Grid.Column="0" Text="Last:" />
      <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding XPath=//Last/text()}" />
      <TextBlock Grid.Row="3" Grid.Column="0" Text="Date:" />
      <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding XPath=//Date/text()}" />
      <TextBlock Grid.Row="4" Grid.Column="0" Text="Change:" />
      <TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding XPath=//Change/text()}" />
      <TextBlock Grid.Row="5" Grid.Column="0" Text="Returns:" />
      <TextBox Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Path=Data.InnerXml, ElementName=detail}" Height="100" Width="500" VerticalAlignment="top" HorizontalAlignment="Left" />
    </Grid>
  </mashup:DataPanel>
  <ui:StatusBar Name="StatusBar" Grid.Row="4" Grid.Column="0" />
</Grid>

Note that REST.XPathNodeIsXmlDocument is new in 10.0.1. For 9.1.3 and 10.0.o try and set REST.RemoveNamespace to true.

Check the code documentation (available under the help menu in the Mashup Designer) for RestDataService and WSDataService for more information on how to configure Data Service panels for REST or WS.

26 thoughts on “Calling a Web Service using WS and REST Data Services

  1. Jon

    Hi
    I try to figure out how to use POST to add a ticket in a application through the REST api and from a mashup form. Is this possible? How to build the xml to be sent?

    1. karinpb Post author

      Hi,
      Sorry for the late reply. I must have missed your comment.
      It is possible to use a POST and submit the XML to be sent.
      You did not mention if your service requires authentication so I assume it’s accessable for everyone.
      You need to set REST.HttpMethod to POST. Then you can set an REST.InputXmlTemplate for example by adding it to the resources like below:

      Then you create replacement variables for the data that you would like to send and you specify those as parameters in the event which means that the MashupDataPanel will fill in the values from the event into your XMLTemplate and fill the form. If the code below is not visible check the API Documentation for RestDataService.KeyInputXmlTemplate

      <Grid.Resources>
          <x:String x:Key="EmployeeRequestTemplate">
          <![CDATA[        
              <Request Action="Load">
                  <Employee Number={EmployeeNumber}" />
              </Request>
          ]]>
          </x:String>
      <Grid.Resources>
      
      <mashup:DataParameter Key="REST.InputXmlTemplate" Value="{StaticResource EmployeeRequestTemplate}" />
      
      

      As for the MashupDataPanel it does not have to wrap the input form – it just has to exist on the Mashup – hidden – but accessible for events. Check out the API Documentation in the Mashup Designer and search for RestDataService. It is possible that you need to specify ContentType or AcceptHeader.

  2. Jon

    Hi and thanx for your reply!

    I’ve found out how to POST, but as you commented, I need to validate access through at API-key. So far haven’t found a way to post a API-key, but thorugh fiddler, I see that my XML is correct. The workaround so far is to let the mashup call a script to POST the data to the REST-service. I try to create a ticket in the osTicket service system 😉

  3. ZaherElShamy

    thanks for that helpful Post ,,, i want to know how to Call WS (which retrieves one row and two columns as a result ) with a button and then write the first Column in a Text Field on the Grid… here is my code
    i tested the WebService with the Tool and it is Working well

    1. ZaherElShamy

      thanks for that helpful Post ,,, i want to know how to Call WS (which retrieves one row and two columns as a result ) with a button and then write the first Column in a Text Field on the Grid… here is my code
      i tested the WebService with the Tool and it is Working well

      1. ZaherElShamy

        when i write that Code … with the click it takes the Value ” getItemNameResponseType”
        Label Grid.Row=”2″ Grid.Column=”1″ Name=”result” Content=”{Binding Path=Data, ElementName=detail}”

      2. karinpb Post author

        I’m sorry but there isn’t enough information. Try and get the binding to a ListView or DataGrid two work first. Then use index to get just the first row.

      3. karinpb Post author

        You should search for the tag to use to escape code. I can’t print it out so google it. And remember that tool://wstest will show you tips for bindings.

  4. Priyanka Nadgouda

    Hi,
    I am new to M3 Web Services(MWS) for M3 version 13.2 and still in the learning phase.

    Requirement: I want to edit values in textboxes in display program PPS200/E by calling it through Web service. Also, I want to store the modified values back into M3 database.

    My work so far: I have created a web service for display program PPS200 in MWS and deployed it on our local server. I have validated the Web service through SoapUI. I created dynamic web project in eclipse, but when I try to create web service client for it, I get the following error: “IWAB0237W The sample JSP client does not support arrays{0}:PPS200″. Kindly advise how to resolve the same.

    Question: How can we call M3 Web Services externally using Java and Tomcat server? If not, then how can we achieve this requirement through any other java-based applications?

    Thanks in advance.

    1. karinpb Post author

      Hi,
      This is a question that is not related to Smart Office but I’ll try with what I know.
      The sample JSP is not suited for Web services that has arrays as input. If I remember the WSDL format for MWS you would need to make sure the WS is called correctly. The issue you have is eclipse specific and not related to the MWS. I would recommend generating java client stub classes and checking the WSDL for information on how to call it.

      Since MWS is like any standard SOAP WS you can call it from any client that supports SOAP web services so Java and Tomcat is fine.

      I thinke the input is an array where the first entry is the actual input. The documentation for MWS should have a code example or you should contact Infor Support. I recommend analyzing the example since any MWS M3 script would be similar.

  5. HeikoM

    Hi,
    I am calling a M3 “Update” API by sending a GET query to the REST service:
    GET https://./m3api-rest/execute/OIS017MI/UpdBasePrice?PRRF=MYLIST&CUCD=EUR&FVDT=20170101&ITNO=MYITEM&SAPR=1.40 .

    This works fine when I have a value for my updated field, in this case SAPR (sales price)

    But is there any way to remove/blank out a field value (replace it with a zero-length string) ?

    I can not add a parameter like ‘XXXX=’ without a value, I retrieve the error message:
    ‘Xxxx ? does not exist’.

  6. Dom

    Hi Karin,

    I am using DataPanel with web service(CLM SQL). The events available to me are OperationComplete & OperationError. My problem is that when web service encounters error the mashup control still tags it as OperationComplete. I’ve tried using the MessagesInDialog as a condition but it doesn’t work. It only works when I use it in the variables section.

    I have also exhausted all documentation I can find and I’m trying to figure out the mashup DataPanel default properties and how to use them e.g. ErrorHandling, MessagesInDialog etc. but I can’t find any.

    1. karinpb Post author

      Hi,
      Are you using REST or WS properties as you configure the datasource?
      With WS, if there is an exception, it should go to the error handler and result in an OperationError.
      But if you have REST and a template for your SOAP call then it’s much harder for the component to know if it is an error or not.

      What version of Smart Office are you using?

      /Karin

      1. Dom

        I am using WS.

        The issue is I have a dialog that should either now show(if there is an error) and show if there is none. Error is all good with OperationError but with success OperationComplete still counts WS that returned SQL error as complete.

        Version 10.2.1.0.273

      2. karinpb Post author

        Hi,
        Since OperationError is a new event we couldn’t brake and not call OperationComplete. OperationComplete will always be called. Perhaps you can use an event condition and check for Error (or ErrorInfo – I don’t remember the exact name).

        Regards
        Karin

  7. Dom

    Yeah, already contacted product dev since I can’t make sense out of the default properties of datapanel. Was able to get MessagesInDialog binding element value as parameter(equals to ‘Error’) but it won’t accept it as a condition parameter.

    Also checked a lot of sites to find out what those default properties are for(including this site) but no luck with documentation.

    1. karinpb Post author

      Some notes I took by checking the DataPanel and thinking about your scenario.

      MessageInDialog – enum DataServiceMessageType (Success, Information,Warning, Error)
      MessagesInStatusBar – default all (All)
      HideWhenServiceIsMissing – If the data service is missing the visibility will be set to collapsed.

      ErrorHandling – Gets or sets a value that indicates how the panel handles errors from the Data service. Eg “custom”

      The default behavior is to show error messages in a dialog or the status bar depending on how
      the MessagesInDialog and MessagesInStatusBar are configured. The panel will also be updated
      if the operation had an error which will cause bindings to be cleared etc.

      The default behavior can be changed by setting the value of this property to Custom.
      When custom error handling is used the OperationError event will be raised when error
      occurs and the Mashup must use this event to show message to the user or handle the
      error in some other way. The panel will not be updated when errors occur.

      When an error is raised these properties will be set: “WS.OperationName” “WS.ErrorHeader”, “WS.ErrorMessage”, “WS.ErrorCode”, “WS.Exception”, “WS.ExceptionName” “WS.ExceptionFullName”. (It could have the REST or WS prefix depending on the type of DataService you are using.

      They are all placed on the control itself and can be checked in a condition in an event after the operation completes. In your case you should be able to add a condition that the event that will open a success dialog would be conditional on that there is no errorheader, exception and so on.
      But for a success dialog there is no automatic support for actually opening and showing that dialog so you would have to use the event togheter with the example on how to show a dialog which I’m assuming that you are using.
      These values are accessible by using the standard way to get a value from a control using a name in an event to ask the control for the value for “WS.Exception” for example. These are not WPF Dependency properties that you can use in bindings but you can use them and pass them in events and also use them in conditions in events.

      I can see that there is no OnSuccessEvent which would have been easier for you to use in your case. It’s just that for most scenarios you might still need a condition to check that the reply is correct and you would do that in the OnOperationComplete. Since we already had that we did not add a SuccessEvent when we added custom error handling.

      By default this control raises currentItemChanged and OnOperationComplete. If Custom is set as ErrorHandling it will raise the error but then still raise the OnOperationComplete. If you in OnOperationComplete has a condition for that WS.Exception exists I think you should be able to get this to work.

      1. Dom

        Karin thanks for the support. This is the solution that I used.

                       <mashup:DataPanel Name="DP_AddQuestion" Grid.Column="2" ErrorHandling="Custom" MessagesInDialog="Error">
                                      <mashup:DataPanel.Events>
                                                     <mashup:Events>
                                                                    <mashup:Event SourceEventName="Closed" TargetEventName="Create" SourceName="mb_QuestionCreateConfirm">
                                                                                   <mashup:Event.Conditions>
                                                                                                 <mashup:Conditions>
                                                                                                                <mashup:Condition SourceKey="NumericResult" TargetValue="1" Operator="Equal" />
                                                                                                                 <mashup:Condition SourceValue="{Binding ElementName=cb_QuestionType, Path=SelectedValue}" TargetValue="{x:Null}" Operator="NotEqual" />
                                                                                                                <mashup:Condition SourceValue="{Binding ElementName=cb_AnswerType, Path=SelectedValue}" TargetValue="{x:Null}" Operator="NotEqual" />
                                                                                                                <mashup:Condition SourceValue="{Binding ElementName=tb_QuestionName, Path=Text}" TargetValue="" Operator="NotEqual" />
                                                                                                                <mashup:Condition SourceValue="{Binding ElementName=tb_QuestionText, Path=Text}" TargetValue="" Operator="NotEqual" />
                                                                                                 </mashup:Conditions>
                                                                                   </mashup:Event.Conditions>
                                                                                   <mashup:Parameter TargetKey="AddQuestion1.QuestionTypeCode" Value="{Binding ElementName=cb_QuestionType , Path=SelectedValue}" />
                                                                                   <mashup:Parameter TargetKey="AddQuestion1.AnswerTypeCode" Value="{Binding ElementName=cb_AnswerType , Path=SelectedValue}" />
                                                                                   <mashup:Parameter TargetKey="AddQuestion1.Name" Value="{Binding ElementName=tb_QuestionName , Path=Text}" />
                                                                                   <mashup:Parameter TargetKey="AddQuestion1.Description" Value="{Binding ElementName=tb_QuestionDescription , Path=Text}" />
                                                                                   <mashup:Parameter TargetKey="AddQuestion1.QuestionText" Value="{Binding ElementName=tb_QuestionText , Path=Text}" />
                                                                    </mashup:Event>
                                                                    <mashup:Event SourceName="DP_AddQuestion" SourceEventName="OperationError" TargetName="mbc_validateFields" TargetEventName="Show">
                                                                                   <mashup:Event.Conditions>
                                                                                                 <mashup:Conditions>
                                                                                                                <mashup:Condition SourceValue="WS.ErrorHeader" TargetValue="{x:Null}" Operator="NotEqual" />
                                                                                                  </mashup:Conditions>
                                                                                   </mashup:Event.Conditions>
                                                                                   <mashup:Parameter TargetKey="MessageType" Value="Error" />
                                                                                   <mashup:Parameter TargetKey="Message" SourceKey="WS.ErrorMessage" />
                                                                                   <mashup:Parameter TargetKey="Header" SourceKey="WS.ErrorHeader" />
                                                                    </mashup:Event>                                                         
                                                                    <mashup:Event SourceName="DP_AddQuestion" SourceEventName="OperationComplete" TargetName="mbc_validateFields" TargetEventName="Show">
                                                                                   <mashup:Parameter TargetKey="MessageType" Value="Information" />
                                                                                   <mashup:Parameter TargetKey="Message" Value="Question has been created" />
                                                                                   <mashup:Parameter TargetKey="Header" Value="Information" />
                                                                    </mashup:Event>
                                                     </mashup:Events>
                                      </mashup:DataPanel.Events>
                                      <mashup:DataPanel.DataService>
                                                     <mashup:DataService Type="WS">
                                                                    <mashup:DataService.Operations>
                                                                                   <mashup:DataOperation Name="Create">
                                                                                                 <mashup:DataParameter Key="WS.Wsdl" Value="{}{=GetProfileValue('M3','WebService','url')}/CustomerSurveys?wsdl" />
                                                                                                 <mashup:DataParameter Key="WS.Address" Value="{}{=GetProfileValue('M3','WebService','url')}/CustomerSurveys" />
                                                                                                 <mashup:DataParameter Key="WS.Operation" Value="AddQuestion" />
                                                                                                 <mashup:DataParameter Key="WS.Contract" Value="CustomerSurveys" />
                                                                                                 <mashup:DataParameter Key="WS.CredentialSource" Value="Current" />
                                                                                   </mashup:DataOperation>
                                                                    </mashup:DataService.Operations>
                                                     </mashup:DataService>
                                      </mashup:DataPanel.DataService>
                       </mashup:DataPanel>
        
        
  8. Doms

    Hi Karin,

    I need your help once again. I have an IDM REST API call wherein I need to get some details from a specific entry. I am using fiddler and I can see that the request returns results. However, I can’t seem to map it using a datapanel.

    I had another mashup wherein I used a different IDM REST API, this one, unlike the first one, returns search results of the IDM(I formulated it using the same REST call IDM is doing). I realize that there is a way to get the whole xml wherein I can just parse it using sql ws to get the details I need. The problem is that this IDM REST API doesn’t support the call when you have the main key of the IDM entry.

    Hence I am stuck with the get api which returns only one result and I need to do it the same thing where you used DataPanel instead of DataListPanel. Here is the code that I have. The results by the way have attributes that’s why I even considered getting the whole InnerXml data.

    <Grid Margin="15,10,15,15" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI">
    	<!-- API Overview http://developer.spotify.com/en/metadata-api/overview/ -->
    	<Grid.Resources>
    		<DataTemplate x:Key="templateLink">
    			<TextBlock>
    				<ui:TaskHyperlink NavigateUri="{Binding XPath=@href}">
    					<TextBlock Text="Link" />
    				</ui:TaskHyperlink>
    			</TextBlock>
    		</DataTemplate>
    	</Grid.Resources>
    	<Grid.ColumnDefinitions>
    		<ColumnDefinition Width="1*" />
    		<ColumnDefinition Width="1*" />
    	</Grid.ColumnDefinitions>
    	<Grid.RowDefinitions>
    		<RowDefinition Height="Auto" />
    		<RowDefinition Height="Auto" />
    		<RowDefinition Height="1*" />
    		<RowDefinition Height="1*" />
    		<RowDefinition Height="1*" />
    	</Grid.RowDefinitions>
    	<TextBox Grid.Row="0" Grid.Column="1" Name="TB_HOLDER" Height="20" Width="150" HorizontalContentAlignment="Left" HorizontalAlignment="Left" Margin="7,5,7,5" />
    	<!-- Application header 
    	<Label Content="Spotify Search" Padding="0" Margin="0" Style="{DynamicResource styleLabelHeader}" FontSize="24" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="0" />-->
    	<!-- Search form 
    	<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Row="1">
    		<Label Content="_Artist" Padding="0" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Center" Target="{Binding ElementName=textBoxArtist}" />
    		<TextBox Width="200" Name="textBoxArtist" Margin="10,0,0,0" MaxLength="256" HorizontalAlignment="Left" VerticalAlignment="Center" />
    		<Button Content="Search" Width="100" Margin="10,0,0,0" IsDefault="True" Style="{DynamicResource styleButtonPrimaryMashup}">
    			<Button.CommandParameter>
    				<mashup:Events>
    					<mashup:Event TargetName="PanelArtists" SourceEventName="Click" TargetEventName="List">
    						<mashup:Parameter TargetKey="Query" Value="{Binding ElementName=textBoxArtist, Path=Text}" />
    					</mashup:Event>
    				</mashup:Events>
    			</Button.CommandParameter>
    		</Button>
    	</StackPanel>-->
    	<mashup:DataListPanel Name="PanelArtists" Margin="0,15,0,0" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
    		<mashup:DataListPanel.Events>
    			<mashup:Events>
    				<mashup:Event TargetName="PanelArtists" SourceEventName="Startup" TargetEventName="List" Debug="False">
    					<mashup:Parameter TargetKey="IDMLink" Value="http://ppzjhidm.zahid.com:19007/" />
    					<mashup:Parameter TargetKey="Part1" Value="ca/api/items/search/?$offset=0&amp;$limit=10&amp;$language=en-US&amp;$includeCount=true&amp;$query=%2FCLM_DOC%5B%40Database_ID%20%3D%20%22" />
    					<mashup:Parameter TargetKey="DatabaseID" Value="504D73A3-EC5B-44A8-A2C8-3ABE60038F57" />
    					<mashup:Parameter TargetKey="Part2" Value="%22%5D%20SORTBY(%40CREATETS%20DESCENDING)%20" />
    					<mashup:Parameter TargetKey="REST.BaseAddress" Value="{}{IDMLink}{Part1}{DatabaseID}{Part2}" />
    				</mashup:Event>
    				<mashup:Event SourceName="PanelArtists" SourceEventName="CurrentItemChanged" Debug="True" Target="{mashup:SetProperty ElementName=TB_HOLDER, Path=Text}">
    					<!--<mashup:Parameter TargetKey="Value" Value="{Binding ElementName=listViewArtists,Path=DataListPanel.Items[0].InnerXml}" />-->
    					<!--<mashup:Parameter TargetKey="Value" Value="{Binding ElementName=PanelArtists,Path=GetValue(pid)}" />-->
    					<!--<mashup:Parameter TargetKey="Value" Value="{}{=GetValue('pid')}" />-->
    					<mashup:Parameter TargetKey="Value" Value="{Binding Path=ItemsSource[0].InnerXml, ElementName=listViewArtists}" />
    				</mashup:Event>
    				<!--<mashup:Event SourceName="PanelArtists" SourceEventName="CurrentItemChanged" Target="{mashup:SetProperty ElementName=textBoxArtist, Path=Text}">
    					<mashup:Parameter TargetKey="Value" Value="{Binding ElementName=PanelArtists,Path=items/item/resrs/res[0].filename}" />
    				{Binding Path=SearchResultsCollection[0].PrimaryKey}
    					 {Binding ElementName=DLP_Main,Path=CurrentItem[PrimaryKey]}
    				</mashup:Event>-->
    			</mashup:Events>
    		</mashup:DataListPanel.Events>
    		<mashup:DataListPanel.DataService>
    			<mashup:DataService Type="REST">
    				<mashup:DataService.Operations>
    					<mashup:DataOperation Name="List">
    						<mashup:DataParameter Key="REST.CredentialSource" Value="Current" />
    						<mashup:DataParameter Key="REST.RemoveNamespace" Value="True" />
    						<mashup:DataParameter Key="REST.XPath" Value="items/item" />
    						<!--<mashup:DataParameter Key="REST.XPathNodeIsXmlDocument" Value="True" />-->
    					</mashup:DataOperation>
    				</mashup:DataService.Operations>
    			</mashup:DataService>
    		</mashup:DataListPanel.DataService>
    		<ListView Name="listViewArtists" ItemsSource="{Binding Items}" Style="{DynamicResource styleListView}" ItemContainerStyle="{DynamicResource styleListViewItem}">
    			<ListView.View>
    				<GridView ColumnHeaderContainerStyle="{DynamicResource styleGridViewColumnHeader}">
    					<GridView.Columns>
    						<GridViewColumn Header="DAF ID" DisplayMemberBinding="{Binding XPath=id}" />
    						<!--<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=attrs/attr/MDS_Name}" />
    						<GridViewColumn Header="Extension" DisplayMemberBinding="{Binding XPath=filename}" />
    						<GridViewColumn Header="Description" DisplayMemberBinding="{Binding XPath=MDS_Desc}" />
    						<GridViewColumn Header="Filename" DisplayMemberBinding="{Binding XPath=filename}" />-->
    						<GridViewColumn Header="Create Date" DisplayMemberBinding="{Binding XPath=createdTS}" />
    						<GridViewColumn Header="Update Date" DisplayMemberBinding="{Binding XPath=lastChangedTS}" />
    					</GridView.Columns>
    				</GridView>
    			</ListView.View>
    		</ListView>
    	</mashup:DataListPanel>
    	<mashup:DataListPanel Name="PanelATTR" Margin="0,15,0,0" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">
    		<mashup:DataListPanel.Events>
    			<mashup:Events>
    				<!--<mashup:Event SourceName="PanelArtists" SourceEventName="OperationComplete" Debug="True" Target="{mashup:SetProperty ElementName=textBoxArtist, Path=Text}">
    					<mashup:Parameter TargetKey="Value" Value="{Binding entityName}" />
    				</mashup:Event>-->
    				<mashup:Event TargetName="PanelATTR" SourceEventName="Startup" TargetEventName="List">
    					<mashup:Parameter TargetKey="IDMLink" Value="http://ppzjhidm.zahid.com:19007/" />
    					<mashup:Parameter TargetKey="Part1" Value="ca/api/items/search/?$offset=0&amp;$limit=1&amp;$language=en-US&amp;$includeCount=true&amp;$query=%2FCLM_DOC%5B%40Database_ID%20%3D%20%22" />
    					<mashup:Parameter TargetKey="DatabaseID" Value="504D73A3-EC5B-44A8-A2C8-3ABE60038F57" />
    					<!--SourceKey="PrimaryKey" />-->
    					<mashup:Parameter TargetKey="Part2" Value="%22%5D%20SORTBY(%40CREATETS%20DESCENDING)%20" />
    					<mashup:Parameter TargetKey="REST.BaseAddress" Value="{}{IDMLink}{Part1}{DatabaseID}{Part2}" />
    				</mashup:Event>
    				<!--<mashup:Event SourceName="PanelATTR" SourceEventName="CurrentItemChanged" Target="{mashup:SetProperty ElementName=textBoxArtist, Path=Text}">
    					<mashup:Parameter TargetKey="Value" Value="{Binding ElementName=PanelATTR,Path=items/item/resrs/res[0].filename}" />
    				{Binding Path=SearchResultsCollection[0].PrimaryKey}
    					{Binding ElementName=DLP_Main,Path=CurrentItem[PrimaryKey]}
    				</mashup:Event>-->
    			</mashup:Events>
    		</mashup:DataListPanel.Events>
    		<mashup:DataListPanel.DataService>
    			<mashup:DataService Type="REST">
    				<mashup:DataService.Operations>
    					<mashup:DataOperation Name="List">
    						<mashup:DataParameter Key="REST.CredentialSource" Value="Current" />
    						<mashup:DataParameter Key="REST.RemoveNamespace" Value="True" />
    						<mashup:DataParameter Key="REST.XPath" Value="items/item/attrs/attr" />
    						<!--<mashup:DataParameter Key="REST.XPath" Value="items/item" />
    						<mashup:DataParameter Key="REST.XPath" Value="items/item" />						
    						<mashup:DataParameter Key="REST.XPathKey" Value="name" />-->
    					</mashup:DataOperation>
    				</mashup:DataService.Operations>
    			</mashup:DataService>
    		</mashup:DataListPanel.DataService>
    		<ListView Name="listViewATTRS" ItemsSource="{Binding Items}" Style="{DynamicResource styleListView}" ItemContainerStyle="{DynamicResource styleListViewItem}">
    			<ListView.View>
    				<GridView ColumnHeaderContainerStyle="{DynamicResource styleGridViewColumnHeader}">
    					<GridView.Columns>
    						<!--<GridViewColumn Header="DAF ID" DisplayMemberBinding="{Binding XPath=id}" />
    						<GridViewColumn Header="Extension" DisplayMemberBinding="{Binding XPath=filename}" />
    						<GridViewColumn Header="Filename" DisplayMemberBinding="{Binding XPath=filename}" />
    						<GridViewColumn Header="Create Date" DisplayMemberBinding="{Binding XPath=createdTS}" />
    						<GridViewColumn Header="Update Date" DisplayMemberBinding="{Binding XPath=lastChangedTS}" />-->
    						<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=name}" />
    						<GridViewColumn Header="Description" DisplayMemberBinding="{Binding XPath=value}" />
    					</GridView.Columns>
    				</GridView>
    			</ListView.View>
    		</ListView>
    	</mashup:DataListPanel>
    	<mashup:DataListPanel Name="PanelRESRS" Margin="0,15,0,0" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2">
    		<mashup:DataListPanel.Events>
    			<mashup:Events>
    				<!--<mashup:Event SourceName="PanelArtists" SourceEventName="OperationComplete" Debug="True" Target="{mashup:SetProperty ElementName=textBoxArtist, Path=Text}">
    					<mashup:Parameter TargetKey="Value" Value="{Binding entityName}" />
    				</mashup:Event>-->
    				<mashup:Event TargetName="PanelRESRS" SourceEventName="Startup" TargetEventName="List">
    					<mashup:Parameter TargetKey="IDMLink" Value="http://ppzjhidm.zahid.com:19007/" />
    					<mashup:Parameter TargetKey="Part1" Value="ca/api/items/search/?$offset=0&amp;$limit=1&amp;$language=en-US&amp;$includeCount=true&amp;$query=%2FCLM_DOC%5B%40Database_ID%20%3D%20%22" />
    					<mashup:Parameter TargetKey="DatabaseID" Value="504D73A3-EC5B-44A8-A2C8-3ABE60038F57" />
    					<!--SourceKey="PrimaryKey" />-->
    					<mashup:Parameter TargetKey="Part2" Value="%22%5D%20SORTBY(%40CREATETS%20DESCENDING)%20" />
    					<mashup:Parameter TargetKey="REST.BaseAddress" Value="{}{IDMLink}{Part1}{DatabaseID}{Part2}" />
    				</mashup:Event>
    				<!--<mashup:Event SourceName="PanelRESRS" SourceEventName="CurrentItemChanged" Target="{mashup:SetProperty ElementName=textBoxArtist, Path=Text}">
    					<mashup:Parameter TargetKey="Value" Value="{Binding ElementName=PanelRESRS,Path=items/item/resrs/res[0].filename}" />
    				{Binding Path=SearchResultsCollection[0].PrimaryKey}
    					{Binding ElementName=DLP_Main,Path=CurrentItem[PrimaryKey]}
    				</mashup:Event>-->
    			</mashup:Events>
    		</mashup:DataListPanel.Events>
    		<mashup:DataListPanel.DataService>
    			<mashup:DataService Type="REST">
    				<mashup:DataService.Operations>
    					<mashup:DataOperation Name="List">
    						<mashup:DataParameter Key="REST.CredentialSource" Value="Current" />
    						<mashup:DataParameter Key="REST.RemoveNamespace" Value="True" />
    						<mashup:DataParameter Key="REST.XPath" Value="items/item/resrs/res" />
    						<!--<mashup:DataParameter Key="REST.XPath" Value="items/item/attrs/attr" />
    						<mashup:DataParameter Key="REST.XPath" Value="items/item" />
    						<mashup:DataParameter Key="REST.XPathKey" Value="name" />-->
    					</mashup:DataOperation>
    				</mashup:DataService.Operations>
    			</mashup:DataService>
    		</mashup:DataListPanel.DataService>
    		<ListView Name="listViewRESRS" ItemsSource="{Binding Items}" Style="{DynamicResource styleListView}" ItemContainerStyle="{DynamicResource styleListViewItem}">
    			<ListView.View>
    				<GridView ColumnHeaderContainerStyle="{DynamicResource styleGridViewColumnHeader}">
    					<GridView.Columns>
    						<!--<GridViewColumn Header="DAF ID" DisplayMemberBinding="{Binding XPath=id}" />
    						<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=attrs/attr/MDS_Name}" />
    						<GridViewColumn Header="Create Date" DisplayMemberBinding="{Binding XPath=createdTS}" />
    						<GridViewColumn Header="Update Date" DisplayMemberBinding="{Binding XPath=lastChangedTS}" />
    						<GridViewColumn Header="Description" DisplayMemberBinding="{Binding XPath=MDS_Desc}" />-->
    						<GridViewColumn Header="Extension" DisplayMemberBinding="{Binding XPath=filename}" />
    						<GridViewColumn Header="Filename" DisplayMemberBinding="{Binding XPath=filename}" />
    					</GridView.Columns>
    				</GridView>
    			</ListView.View>
    		</ListView>
    	</mashup:DataListPanel>
    </Grid>
    
    1. Karin Portillo Post author

      Hi Doms,
      I recommend that you use Snoop UI For these issues as it will show the error for the binding. The issue was that XPath cannot bind to non-XML object using XOath “//lastChangedBy/text.

      We think that the issue you had was that the TextBox within the DataPanel did not bind to the value correctly. Peter G helped me with the solution here.

      If you use the DataItem approach instead and bind to that object that we create in the panel it should work. See below:

      <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:Mango.UI.Controls;assembly=Mango.UI" xmlns:mashup="clr-namespace:Mango.UI.Services.Mashup;assembly=Mango.UI">
      	<Grid.ColumnDefinitions>
      		<ColumnDefinition Width="1*" />
      	</Grid.ColumnDefinitions>
      	<Grid.RowDefinitions>
      		<RowDefinition Height="20" />
      		<RowDefinition Height="1*" />
      		<RowDefinition Height="Auto" />
      	</Grid.RowDefinitions>
      	<mashup:DataPanel Grid.Row="1" Grid.Column="0" Name="dp_IDMGetInfo">
      		<mashup:DataPanel.Events>
      			<mashup:Events>
      				<mashup:Event SourceEventName="Startup" TargetName="dp_IDMGetInfo" TargetEventName="dp_GetItem">
      					<mashup:Parameter SourceKey="Key" DefaultValue="MDS_File-3-17-LATEST" />
      				</mashup:Event>
      			</mashup:Events>
      		</mashup:DataPanel.Events>
      		<mashup:DataPanel.DataService>
      			<mashup:DataService Type="REST">
      				<mashup:DataService.Operations>
      					<mashup:DataOperation Name="dp_GetItem">
      						<mashup:DataParameter Key="REST.Uri" Value="https://hostname.acme.com:12345/ca/api/items/MDS_File-3-17-LATEST" />
      						<mashup:DataParameter Key="REST.SharedCookieContainer" Value="true" />
      						<mashup:DataParameter Key="REST.User" Value="UserName" />
      						<mashup:DataParameter Key="REST.Password" Value="Password" />
      						<!-- <mashup:DataParameter Key="REST.CredentialSource" Value="Current" /> -->
      						<mashup:DataParameter Key="REST.RemoveNamespace" Value="True" />
      					</mashup:DataOperation>
      				</mashup:DataService.Operations>
      			</mashup:DataService>
      		</mashup:DataPanel.DataService>
      		<Grid>
      			<Grid.ColumnDefinitions>
      				<ColumnDefinition Width="Auto" />
      			</Grid.ColumnDefinitions>
      			<Grid.RowDefinitions>
      				<RowDefinition Height="Auto" />
      			</Grid.RowDefinitions>
      			<StackPanel Orientation="Vertical">
      				<TextBox Name="LastChangedBy" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding XPath=/*/lastChangedBy}" Margin="0,0,0,0" Width="300" />
      				<TextBox Name="Pid" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding XPath=/*/pid}" Margin="0,0,0,0" Width="300" />
      				<TextBox Name="EntityName" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding XPath=/*/entityName}" Margin="0,0,0,0" Width="300" />
      			</StackPanel>
      		</Grid>
      	</mashup:DataPanel>
      </Grid>
      
  9. Olof

    Hi,

    I am having problem with displaying information from a REST API in a mashup.
    I want to display the information from the REST API as a list in the mashup trough a DataListPanel.

    I tested the REST API in SoapUI and a get correct answeer. BUT; I only get answeer in JSON.
    When entering the same information to the mashup, I get no answeer, the log tells me that there are no Response in the answeer from the REST API.

    Hopefully I do only write the code wrong in the mashup.

    Here is the code; it is a super simple mashup, but can anyone tell me what I am doing wrong to not get any response ?

    Thank you!
    //Olof

    1. Karin Portillo Post author

      Hi,
      I know the support for JSON is very limited. Does the service only support JSON or would it switch to return XML if you pass an accept header?
      I’ve asked for assistance on this one, since I don’t remember all the details. Let me check and get back to you.

      1. Olof

        Hi Karin,
        I Think it only support JSON. It is the only media type I can find in the documentation from the provider.
        Do you men an accept header like this?

        Yes, thank you, that would be very helpful.
        //Olof

Comments are closed.