<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Parago Media</title>
	<atom:link href="http://www.parago.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.parago.de</link>
	<description>Jürgen Bäurle\\\&#039;s resume and company blog website</description>
	<lastBuildDate>Wed, 04 Apr 2012 13:34:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>How To Use The New SQL-Like Query Language XtractQL To Retrieve SAP Business Data</title>
		<link>http://www.parago.de/2012/03/how-to-use-the-new-sql-like-query-language-xtractql-to-retrieve-sap-business-data/</link>
		<comments>http://www.parago.de/2012/03/how-to-use-the-new-sql-like-query-language-xtractql-to-retrieve-sap-business-data/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 11:24:36 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[ASP.NET (MVC)]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[ERPConnect]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Theobald Software]]></category>
		<category><![CDATA[ERPConnect Services]]></category>
		<category><![CDATA[Query Language]]></category>
		<category><![CDATA[SAP R/3]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SQL-like Query Language]]></category>
		<category><![CDATA[XQL]]></category>
		<category><![CDATA[XtractQL]]></category>

		<guid isPermaLink="false">http://www.parago.de/?p=958</guid>
		<description><![CDATA[Theobald Software released a new product suite called ERPConnect Services for SharePoint 2010. The product contains a new kind of query language named XtractQL to query SAP business data in a SQL-like manner. XtractQL or XQL is a combination of SQL and ABAP language syntax statements to simplify querying SAP systems. XtractQL allows querying SAP [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-size: 10pt;">Theobald Software released a new product suite called ERPConnect Services for SharePoint 2010. The product contains a new kind of query language named XtractQL to query SAP business data in a SQL-like manner. XtractQL or XQL is a combination of SQL and ABAP language syntax statements to simplify querying SAP systems.<br />
</span></p>
<p><span style="font-size: 10pt;">XtractQL allows querying SAP objects like tables, BW-Cubes and SAP Queries. In addition XtractQL executes function modules (BAPIs) and returns metadata for objects. It can even execute MDX statements. Each XQL query is returning a data table object as result set. In case of the execution function modules the caller must define the returning table explicitly. XtractQL is very useful in situations where you want or need to handle dynamic statements.<br />
</span></p>
<p><span style="font-size: 10pt;">ERPConnect Services for SharePoint 2010 (ECS) provides an additional tool, the XtractQL Explorer (see screenshot below), to learn more about the query language and to test XQL queries. You can use this tool independent of SharePoint 2010, but you need access to a SAP system.<br />
</span></p>
<p><span style="font-size: 10pt;"><a class="lightbox" title="031912_0923_HowToUseThe1.png" href="http://www.parago.de/wp-content/uploads/2012/03/031912_0923_HowToUseThe1.png"><img class="alignnone size-full wp-image-956" title="031912_0923_HowToUseThe1.png" src="http://www.parago.de/wp-content/uploads/2012/03/031912_0923_HowToUseThe1.png" alt="" /></a><br />
</span></p>
<p><span style="font-size: 10pt;">The screenshot shows different samples of XQL queries. The following list shows a couple of other samples of XQL queries you can use in your SharePoint applications:<br />
</span></p>
<p><strong>SELECT TOP 5 * FROM T001W WHERE FABKL = &#8216;US&#8217;<br />
</strong></p>
<p><span style="font-size: 10pt;">This query selects the top 5 records of the SAP table T001W where the field FABKL equals the value US.<br />
</span></p>
<p><strong>SELECT * FROM MARA WITH-OPTIONS(CUSTOMFUNCTIONNAME = &#8216;Z_XTRACT_IS_TABLE&#8217;)<br />
</strong></p>
<p><span style="font-size: 10pt;">This query selects all records and fields of the SAP table MARA using a custom SAP function module to retrieve the data called Z_XTRACT_IS_TABLE.<br />
</span></p>
<p><strong>SELECT MAKTX AS [ShortDesc], MANDT, SPRAS AS Language FROM MAKT<br />
</strong></p>
<p><span style="font-size: 10pt;">This query selects all records of the SAP table MAKT. The result set will contains three fields named ShortDesc, MANDT and Language.<br />
</span></p>
<p><strong>SELECT TOP 30 LIPS-LFIMG, LIPS-MATNR, TEXT_LIKP_KUNNR AS CustomerID<br />
</strong></p>
<p><strong> FROM QUERY &#8216;S|ZTHEO02|ZLIKP&#8217;<br />
</strong></p>
<p><strong> WHERE SP$00002 BT &#8217;0080011000&#8242;AND &#8217;0080011999&#8242;<br />
</strong></p>
<p><span style="font-size: 10pt;">This statement executes the SAP Query &#8220;S|ZTHEO02|ZLIKP&#8221; (name includes the workspace, user group and the query name). As you can see XtractQL extends the SQL syntax with ABAP or SAP specific syntax elements. This way you can define fields using the LIPS-MATNR format and SAP-like where clauses like &#8220;SP$00002 BT &#8217;0080011000&#8242;AND &#8217;0080011999&#8242;&#8221;.<br />
</span></p>
<p><strong>SELECT * FROM BWQUERY &#8217;0D_DECU/VARDEMO01&#8242;<br />
</strong></p>
<p><strong> WHERE MAT03 EQ &#8216;M03&#8242;, SALESORG BT &#8217;1000&#8242; AND &#8217;3000<br />
</strong></p>
<p><span style="font-size: 10pt;">This query executes a query against a specific SAP BW cube using a where clause.<br />
</span></p>
<p><strong>DESCRIBE FUNCTION &#8216;SD_RFC_CUSTOMER_GET&#8217; GET EXPORTS<br />
</strong></p>
<p><span style="font-size: 10pt;">This query returns metadata about the export parameters of the SAP function module.<br />
</span></p>
<p><strong>DESCRIBE QUERY &#8216;G|ZTHEO1|ZTHEOSQUERY&#8217; GET FIELDS<br />
</strong></p>
<p><span style="font-size: 10pt;">This query returns metadata about the defined SQP Query.<br />
</span></p>
<p><strong>EXECUTE FUNCTION &#8216;SD_RFC_CUSTOMER_GET&#8217;<br />
</strong></p>
<p><strong> EXPORTS KUNNR=&#8217;0000003340&#8242;<br />
</strong></p>
<p><strong> TABLES CUSTOMER_T INTO @RETVAL;<br />
</strong></p>
<p><span style="font-size: 10pt;">This query executes the SAP function module SD_RFC_CUSTOMER_GET and returns as result the table CUSTOMER_T (defined as @RETVAL).<br />
</span></p>
<p><span style="font-size: 10pt;">ERPConnect Services runtime provides three kind of libraries to integrate with your application: Silverlight, Desktop and SharePoint client library. See product documentation for more information.<br />
</span></p>
<p><span style="font-size: 10pt;">Here an example of how to use the libraries in code, e.g. within a web part project:<br />
</span></p>
<p style="background: #d9d9d9;">
<span style="font-family: Courier New; font-size: 10pt;">using ERPConnectServices;</span><br />
<span style="font-family: 'Courier New'; font-size: 10pt;">…</span><br />
<span style="font-family: 'Courier New'; font-size: 10pt;">ERPConnectServiceClient client = new ERPConnectServiceClient();</span><br />
<span style="font-family: 'Courier New'; font-size: 10pt;">DataTable dt = client.ExecuteXQL(&#8220;SELECT TOP 50 * FROM MAKT&#8221;);</span>
</p>
<p><span style="font-size: 10pt;">The ExecuteXQL method call of the ERPConnect Service Application in SharePoint will execute the XtractQL command against the defined SAP system.<br />
</span></p>
<p><span style="font-size: 10pt;">There is also another way to use XtractQL. ERPConnect Services for SharePoint 2010 includes a Visual Studio 2010 Designer plugin. Similar to the LINQ to SQL designer, the ECS designer creates automatically code for you, see screenshot below:<br />
</span></p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031912_0923_HowToUseThe2.png" alt="" /><span style="font-size: 10pt;"><br />
</span></p>
<p><span style="font-size: 10pt;">You will find more information about the XtractQL syntax and ERPConnect Services for SharePoint 2010 product itself at the website of Theobald Software. There is also an evaluation version available.<br />
</span></p>
<p><a href="http://www.theobald-software.com/de/products/erpconnectservices.htm"><span style="font-family: Garamond; font-size: 12pt;">http://www.theobald-software.com/de/products/erpconnectservices.htm</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2012/03/how-to-use-the-new-sql-like-query-language-xtractql-to-retrieve-sap-business-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Integrate SAP Business Data Into SharePoint 2010 Using BCS Services And BCS Connector From Theobald Software</title>
		<link>http://www.parago.de/2012/03/how-to-integrate-sap-business-data-into-sharepoint-2010-using-bcs-services-and-bcs-connector-from-theobald-software/</link>
		<comments>http://www.parago.de/2012/03/how-to-integrate-sap-business-data-into-sharepoint-2010-using-bcs-services-and-bcs-connector-from-theobald-software/#comments</comments>
		<pubDate>Sat, 17 Mar 2012 14:42:03 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[ASP.NET (MVC)]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Theobald Software]]></category>
		<category><![CDATA[BCS]]></category>
		<category><![CDATA[BCS Services]]></category>
		<category><![CDATA[Business Connectity Services]]></category>
		<category><![CDATA[ERPConnect Services]]></category>
		<category><![CDATA[SAP Business Data]]></category>

		<guid isPermaLink="false">http://www.parago.de/?p=950</guid>
		<description><![CDATA[The Business Connectivity Services (BCS) of SharePoint 2010 provide a great way to fully integrate external data into the SharePoint. In most cases developers are integrating SQL database tables into the BCS services. But how do we connect to a SAP system? How do we integrate real world SAP business data like tables and function [...]]]></description>
			<content:encoded><![CDATA[<p>The Business Connectivity Services (BCS) of SharePoint 2010 provide a great way to fully integrate external data into the SharePoint. In most cases developers are integrating SQL database tables into the BCS services. But how do we connect to a SAP system? How do we integrate real world SAP business data like tables and function modules or BAPIs into SharePoint?</p>
<p>The answer is just a few clicks away. Theobald Software just released the ERPConnect Services (ECS) for SharePoint 2010 product suite and the product includes a great tool named BCS Connector. The BCS Connector allows developer to create SAP-driven BDC models in minutes with just a couple of clicks.</p>
<p>The BCS Connector application can be installed on client machines and will connect remotely to the SharePoint BCS service application. In this post I will give you an overview of the tool by creating a BDC model with an entity called Customer. We will also create two operations for the entity, a Finder and SpecificFinder method. Both methods are using the SAP built-in function module SD_RFC_CUSTOMER_GET. This is a very simple SAP function returning a list of customers.</p>
<p>To create a new BDC model, first you must enter the SAP and the SharePoint connection data after starting the BCS Connector application (see screenshot for SAP connection below).</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr1.png" alt="" /></p>
<p>Once you have entered the SAP connection data press the OK button and start adding your new BDC entity. To add an entity that is connected to a SAP function module SD_RFC_CUSTOMER_GET press the New button on the lower left side. A new wizard dialog will pop up. Select Function and press the Next button.</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr2.png" alt="" /></p>
<p>Then search for the function module and press the Next button to select the structure of our new BDC entity.</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr3.png" alt="" /></p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr4.png" alt="" /></p>
<p>The last wizard page shows us a list with all possible entity structures available for this function module. Select the table CUSTOMER_T, including our customer data, and press the Finish button.</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr5.png" alt="" /></p>
<p>Now we have created our new entity Customer, but we still need to rename the entity from CUSTOMER_T to Customer. Each entity in BCS services must define at least two operations or methods, a so called Finder method to return a list of entities and a SpecificFinder method to return a specific entity within the list.</p>
<p>You also need to define the identifier fields within the entity by clicking the checkbox for the field KUNNR (Customer ID). You may also rename the field or all fields. Next, we create the Finder method by clicking the New button.</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr6.png" alt="" /></p>
<p>The Finder option is already selected. Just press the Finish button and the BCS Connector is automatically creating everything else and will open afterwards the Edit Operation dialog.</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr7.png" alt="" /></p>
<p>This dialog allows you to define the return parameter, input parameters and filters for the entity operation. Actually to execute the SAP function module SD_RFC_CUSTOMER_GET we need to define a value for the input parameters KUNNR or NAME1. For demonstration purpose I just define a name pattern for field NAME1. This query returns all customers that starts with T. What you can define as input parameter depends on the function itself. Clicking on the Preview button displays a list of all filtered customers.</p>
<p>In the same way we are creating the SpecificFinder method:</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr8.png" alt="" /></p>
<p>So, finally we have created a new entity with two entity operations and now we are able to save it on the SharePoint server. Just press the Save Model button. This will result in a new BDC model created on the server:</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr9.png" alt="" /></p>
<p>You can find the BDC models within the Central Administration of SharePoint 2010.</p>
<p>So far we just created a model, but we also want to display the customer data within an external list. We can create an external list using the SharePoint Designer or the BCS Connector. I will show you the second option. Switch to the External Lists tab of the ribbon bar and click on the New External List button.</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr10.png" alt="" /></p>
<p>The New External List dialog has pre-selected all values. Click on the Create button and you are done. You may also change the name of the external list. The final external list looks as follows:</p>
<p><img src="http://www.parago.de/wp-content/uploads/2012/03/031612_1437_HowToIntegr11.png" alt="" /></p>
<p>That was really easy and you can even export the BDC Model to Visual Studio 2010 and do additional customizing.</p>
<p>Further information about the product ERPConnect Services and BCS Connector can be found here:</p>
<p><a href="http://www.theobald-software.com/en/products/erpconnectservices.htm" target="_blank"><span style="font-size: 10pt;">http://www.theobald-software.com/en/products/erpconnectservices.htm</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2012/03/how-to-integrate-sap-business-data-into-sharepoint-2010-using-bcs-services-and-bcs-connector-from-theobald-software/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using ERPConnect Services To Integrate SAP Business Data Into SharePoint 2010</title>
		<link>http://www.parago.de/2012/02/using-erpconnect-services-to-integrate-sap-business-data-into-sharepoint-2010/</link>
		<comments>http://www.parago.de/2012/02/using-erpconnect-services-to-integrate-sap-business-data-into-sharepoint-2010/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 13:12:00 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[ASP.NET (MVC)]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[ERPConnect]]></category>
		<category><![CDATA[ERPConnect Services]]></category>
		<category><![CDATA[Query Language]]></category>
		<category><![CDATA[SAP R/3]]></category>
		<category><![CDATA[SharePoint Theobald Software]]></category>
		<category><![CDATA[XQL]]></category>
		<category><![CDATA[XtractQL]]></category>

		<guid isPermaLink="false">http://jbaurle.wordpress.com/?p=449</guid>
		<description><![CDATA[SharePoint 2010 provides developer with the capability to integrate external data sources like SAP business data via the Business Connectivity Services (BCS) into the SharePoint system. The concept of BCS is based on entities and associated stereotyped operations. This perfectly suits for flat and simple structured data sets like SAP tables. Another and way more [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">SharePoint 2010 provides developer with the capability to integrate external data sources like SAP business data via the Business Connectivity Services (BCS) into the SharePoint system. The concept of BCS is based on entities and associated stereotyped operations. This perfectly suits for flat and simple structured data sets like SAP tables. </span><br />
</span><span style="font-family: times new roman; font-size: 12pt;"> </span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Another and way more flexible option to use SAP data in SharePoint are the ERPConnect Services for SharePoint 2010 from Theobald Software. The product suite consists of three product components: ERPConnect Services runtime, the BCS Connector application and the Xtract PPS for PerformancePoint Services.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The ERPConnect Services runtime is providing a Service Application that integrates itself with the new service architecture of SharePoint 2010. The runtime offers a secure middle-tier layer to integrate different kind of SAP objects in your SharePoint applications, like tables and function modules.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The BCS Connector application allows developers to quickly create BDC models for the BCS Services, completely without programming knowledge. You even be able to export the BDC models created by the BCS Connector to Visual Studio 2010 for further customizing. The Xtract PPS component offers a SAP data source provider for the PerformancePoint Services of SharePoint 2010.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This article gives you an overview of the ERPConnect Services runtime and shows how easy you can create and incorporate business data from SAP in different SharePoint application types, like Web Parts, Application Pages or Silverlight modules. This article does not introduce the BCS Connector nor the Xtract PPS component.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>SAP Background</strong><br />
</span></span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This section will give you a short explanation and background of SAP objects that can be used in ERPConnect Services for SharePoint 2010. The most important objects are SAP tables and function modules.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">A function module is basically similar to a normal procedure in conventional programming languages. Function modules are written in ABAP, the SAP programming language, and are accessible from any other programs within a SAP system. They accept import and export parameters as well as other kind of special parameters. In addition, BAPIs (Business-API) are special function modules that are organized within the SAP Business Object Repository. In order to use function modules with ERPConnect Services they must be marked as Remote (RFC).<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">SAP tables can also be accessed by ERPConnect Services. Tables in SAP are basically relational database tables. Others SAP objects like BW Cubes or SAP Queries can be accessed via the XtractQL query language (see below).<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>ERPConnect Services Installation &amp; Configuration</strong><br />
</span></span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Theobald Software is providing an evaluation version that can be downloaded from their website. Installing the ERPConnect Services on a SharePoint 2010 server is done by an installer and is straight forward. The SharePoint Administration Service must run on the local server (see Windows Services). For more information see product documentation. After the installation has been successfully processed navigate to the Service Applications screen within the central administration (CA) of SharePoint:<br />
</span></span></p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon1.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"><br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Before creating your first ERPConnect Service Application a Secure Store must be created, where ERPConnect Services will save SAP user credentials. There will be a SNC (Secure Network Communication) option for Single-Sign-On (SSO) scenarios starting with the next product version. In the settings page for the &#8220;Secure Store Service&#8221; create a new Target Application and name the application &#8220;ERPConnect Services&#8221;. Click on the button &#8220;Next&#8221; to define the store fields as follows:<br />
</span></span></p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon2.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"><br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Finish the creation process by clicking on &#8220;Next&#8221; and define application administrators. Then, mark the application, click &#8220;Set Credentials&#8221; and enter the SAP user credentials:<br />
</span></span></p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon3.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"><br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Let&#8217;s go on and create a new ERPConnect Service Application!<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Click the &#8220;ERPConnect Service Application&#8221; link in the &#8220;New&#8221; menu of the Service Applications page (see also first screenshot above). This opens the &#8220;Create New ERPConnect Service Application&#8221; dialog to define the name of the service application, the SAP connection data and the IIS application pool:<br />
</span></span></p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon4.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"><br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Click &#8220;Create&#8221; after entering all data and you will see the following entries in the Service Applications screen:<br />
</span></span></p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon5.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"><br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">That&#8217;s it! You are now done setting up your first ERPConnect Service Application.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>ERPConnect Services Development</strong><br />
</span></span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The ERPConnect Services runtime functionality covers different programming demands such as generically retrievable interface functions. The ERPConnect Services are managed by the Central Administration of SharePoint. The following service and function areas are provided by ERPConnect Services:<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">1. Executing and retrieving data directly from SAP tables<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">2. Executing SAP function modules / BAPIs<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">3. Executing XtractQL query statements<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The next sections shows how to use these service and function areas and access different SAP objects from within your custom SharePoint applications using the ERPConnect Services. The runtime can be used in applications within the SharePoint context like Web Parts or Application Pages. In order to do so, you need to reference the assembly ERPConnectServices.Server.Common.dll in the project.<br />
</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Before you can access data from the SAP system you must create an instance of the ERPConnectServiceClient class. This is the gate to all SAP objects and the generic API of ERPConnect Services runtime in overall. In the SharePoint context there are two options to create a client object instance: </span><br />
</span></p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:7172f232-a9ff-4991-9877-42c921a9faa0" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: c#;">// Option #1
ERPConnectServiceClient client = new ERPConnectServiceClient();

// Option #2
ERPConnectServiceApplicationProxy proxy = SPServiceContext.Current.GetDefaultProxy  (typeof(ERPConnectServiceApplicationProxy)) as
    ERPConnectServiceApplicationProxy;

ERPConnectServiceClient client = proxy.GetClient();</pre>
</div>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">For more details on using ERPConnect Services in Silverlight or desktop applications see the specific sections below.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>Querying Tables</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Querying and retrieving table data is a common task for developers. ERPConnect Services runtime allows retrieving data directly from SAP tables. The ERPConnectServiceClient class provides a method called ExecuteTableQuery with two overrides which query SAP tables in a simple way. The method also supports a way to pass miscellaneous parameters like row count and skip, custom function, where clause definition and a returning field list. These parameters can be defined by using the ExecuteTableQuerySettings class instance.</span></span></p>
<p>&nbsp;</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:7be4a46b-d978-4f78-9eb9-7956533a6592" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: c#;">DataTable dt = client.ExecuteTableQuery("T001");

…

ExecuteTableQuerySettings settings = new ExecuteTableQuerySettings {
  RowCount = 100,
  WhereClause = "ORT01 = 'Paris' AND LAND1 = 'FR'",
  Fields = new ERPCollection&lt;string&gt; { "BUKRS", "BUTXT", "ORT01", "LAND1" }
};

DataTable dt = client.ExecuteTableQuery("T001", settings);

…

// Sample 2
DataTable dt = client.ExecuteTableQuery("MAKT",
  new ExecuteTableQuerySettings {
    RowCount = 10,
    WhereClause = "MATNR = '60-100C'",
    OrderClause = "SPRAS DESC"
});</pre>
</div>
<p><span style="font-family: courier new; font-size: 10pt;"> </span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The first query reads all records from the SAP table T001 where the fields ORT01 equals Paris and LAND1 equals FR (France). The query returns the top 100 records and the result set contains only the fields BUKRS, BUTXT, ORT01 and LAND1. The second query returns the top ten records of the SAP table MAKT, where the field MATNR equals the material number 60-100C. The result set is ordered by the field SPRAS. </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>Executing Function Modules</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">In addition to query SAP tables the runtime API executes SAP function modules (BAPIs). Function modules must be marked as remote-enabled modules (RFC) within SAP. The ERPConnectServiceClient class provides a method called CreateFunction to create a structure of metadata for the function module. The method returns an instance of the data structure ERPFunction. This object instance contains all parameters types (import, export, changing and tables) that can be used with function modules.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">In the sample below we call the function SD_RFC_CUSTOMER_GET and pass a name pattern (T*) for the export parameter with name NAME1. Then we call the Execute method on the ERPFunction instance. Once the method has been executed the data structure is updated. The function returns all customers in the table CUSTOMER_T.</span></span></p>
<p>&nbsp;</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:913df7b3-9e96-48e8-9875-7d306a90d338" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: c#;">ERPFunction function = client.CreateFunction("SD_RFC_CUSTOMER_GET");
function.Exports["NAME1"].ParamValue = "T*";
function.Execute();

foreach(ERPStructure row in function.Tables["CUSTOMER_T"])
  Console.WriteLine(row["NAME1"] + ", " + row["ORT01"]);</pre>
</div>
<p style="background: #f2f2f2;"><span style="font-size: x-small;"> </span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The following code shows an additional sample. Before we can execute this function module we need to define a table with HR data as input parameter. The parameters you need and what values the function module is returning dependents on the implementation of the function module.</span></span></p>
<p>&nbsp;</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:4a6dbb40-b415-4200-ac1b-951ec3ada917" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: c#;">ERPFunction function = client.CreateFunction("BAPI_CATIMESHEETMGR_INSERT");
function.Exports["PROFILE"].ParamValue = "TEST";
function.Exports["TESTRUN"].ParamValue = "X";

ERPTable records = function.Tables["CATSRECORDS_IN"];
ERPStructure r1 = records.AddRow();
r1["EMPLOYEENUMBER"] = "100096";
r1["WORKDATE"] = "20110704";
r1["ABS_ATT_TYPE"] = "0001";
r1["CATSHOURS"] = (decimal)8.0;
r1["UNIT"] = "H";

function.Execute();

ERPTable ret = function.Tables["RETURN"];

foreach(var i in ret)
  Console.WriteLine("{0} - {1}", i["TYPE"], i["MESSAGE"]);</pre>
</div>
<p style="background: #f2f2f2;"><span style="font-family: courier new; font-size: 10pt;"> </span></p>
<p><span style="font-size: x-small;"> </span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>Executing XtractQL Query Statements</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The ERPConnect Services runtime is offering a new way of accessing SAP data. Theobald Software has developed a SAP query language called XtractQL. The XtractQL query language, also known as XQL, consists of ABAP and SQL syntax elements.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">XtractQL allows querying SAP tables, BW-Cubes, SAP Queries and executing function modules. It also returns metadata for the objects and even MDX statements can be executed with XQL. All XQL queries are returning a data table object as result set. In case of the execution of function modules the caller must define the returning table (see sample below &#8211; INTO @RETVAL). XQL is very useful in situations where you need to handle dynamic statements. The following list shows a couple of query samples you may use in your applications:</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em>SELECT TOP 5 * FROM T001W WHERE FABKL = &#8216;US&#8217;</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This query selects the top 5 records of the SAP table T001W where the field FABKL equals the value US.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em>SELECT * FROM MARA WITH-OPTIONS(CUSTOMFUNCTIONNAME = &#8216;Z_XTRACT_IS_TABLE&#8217;)</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This query selects all records and fields of the SAP table MARA using a custom SAP function module to retrieve the data called Z_XTRACT_IS_TABLE.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em>SELECT MAKTX AS [ShortDesc], MANDT, SPRAS AS Language FROM MAKT</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This query selects all records of the SAP table MAKT. The result set will contains three fields named ShortDesc, MANDT and Language.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em>EXECUTE FUNCTION &#8216;SD_RFC_CUSTOMER_GET&#8217;</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em> EXPORTS KUNNR=&#8217;0000003340&#8242;</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em> TABLES CUSTOMER_T INTO @RETVAL;</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This query executes the SAP function module SD_RFC_CUSTOMER_GET and returns as result the table CUSTOMER_T (defined as @RETVAL).</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em>DESCRIBE FUNCTION &#8216;SD_RFC_CUSTOMER_GET&#8217; GET EXPORTS</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This query returns metadata about the export parameters of the SAP function module.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em>SELECT TOP 30 LIPS-LFIMG, LIPS-MATNR, TEXT_LIKP_KUNNR AS CustomerID</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em> FROM QUERY &#8216;S|ZTHEO02|ZLIKP&#8217;</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong><em> WHERE SP$00002 BT &#8217;0080011000&#8242;AND &#8217;0080011999&#8242;</em></strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">This statement executes the SAP Query &#8220;S|ZTHEO02|ZLIKP&#8221; (name includes the workspace, user group and the query name). As you can see XtractQL extends the SQL syntax with ABAP or SAP specific syntax elements. This way you can define fields using the LIPS-MATNR format and SAP-like where clauses like &#8220;SP$00002 BT &#8217;0080011000&#8242;AND &#8217;0080011999&#8242;&#8221;.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">ERPConnect Services for SharePoint 2010 (ECS) provides a little helper tool, the XtractQL Explorer (see screenshot below), to learn more about the query language and to test XQL queries. You can use this tool independent of SharePoint 2010, but you need access to a SAP system.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon6.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">To find out more about all XtractQL language syntax see the product manual.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>ERPConnect Services In Silverlight And Desktop Applications</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">So far all samples are using the assembly ERPConnectServices.Server.Common.dll as project reference and all code snippets shown run within the SharePoint context, e.g. Web Part. ERPConnect Services runtime also provides client libraries for Silverlight and desktop applications:</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">ERPConnectServices.Client.dll for Desktop applications</span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">ERPConnectServices.Client.Silverlight.dll for Silverlight applications</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">You need to add the references depending what project you are implementing.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">In Silverlight the implementation and design pattern is a little bit more complicated, since all web services will be called in asynchronously. It&#8217;s also not possible to use the DataTable class. It&#8217;s just not implemented for Silverlight. ERPConnect Services provides a similar class called ERPDataTable, which is used in this cases by the API.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The ERPConnectServiceClient class for Silverlight provides the method ExecuteTableQueryAsync and an event called ExecuteTableQueryCompleted as callback delegate.</span></span></p>
<p>&nbsp;</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:22aca4c8-e602-425e-b811-183cad446ea8" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: c#;">public event EventHandler&lt;ExecuteTableQueryCompletedEventArgs&gt; ExecuteTableQueryCompleted;

public void ExecuteTableQueryAsync(string tableName)
public void ExecuteTableQueryAsync(string tableName, ExecuteTableQuerySettings settings)</pre>
</div>
<p style="background: #f2f2f2;"><span style="font-family: courier new; font-size: 10pt;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The following code sample shows a simple query of the SAP table T001 within a Silverlight client. First of all, an instance of the ERPConnectServiceClient is created using the URI of the ERPConnectService.svc, then a delegate is defined to handle the complete callback. Next, the query is executed, defined with a RowCount equal 10 to only return the top 10 records in the result set. Once the result is returned the data set will be attached to a DataGrid control (see screenshot below) within the callback method.</span></span></p>
<p>&nbsp;</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:76609e08-c4f9-429e-8060-778aec727d5b" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: c#;">void OnGetTableDataButtonClick(object sender, RoutedEventArgs e)
{
   ERPConnectServiceClient client = new ERPConnectServiceClient(
      new Uri("http://&lt;SERVERNAME&gt;/_vti_bin/ERPConnectService.svc"));

   client.ExecuteTableQueryCompleted += OnExecuteTableQueryCompleted;

   client.ExecuteTableQueryAsync("T001",
      new ExecuteTableQuerySettings { RowCount = 150 });
}

void OnExecuteTableQueryCompleted(object sender,    ExecuteTableQueryCompletedEventArgs e)
{
   if(e.Error != null)
      MessageBox.Show(e.Error.Message);
   else
   {
      e.Table.View.GroupDescriptions.Add(new PropertyGroupDescription("ORT01"));
      TableGrid.ItemsSource = e.Table.View;
   }
}</pre>
</div>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The screenshot below shows the XAML of the Silverlight page:</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon7.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The final result can be seen below:</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon8.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>ERPConnect Services Designer</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;">ERPConnect Services for SharePoint 2010 product suite includes a Visual Studio 2010 plugin, the ECS Designer, that allows developer to visually design SAP interfaces. It&#8217;s working similar to the LINQ to SAP Designer I have written about a while ago, see article at CodeProject: <span style="font-family: garamond; font-size: 10pt;">LINQ to SAP</span></span></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">.</span></span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The ECS Designer is not automatically installed once you install the ERPConnect Services suite. You need to call the installation program manually. The setup adds a new project item type to Visual Studio 2010 with the file extension .ecs and is linking it with the ECS Designer. The needed references are added automatically after adding an ECS project item. The designer generates source code to integrate with the ERPConnect Services runtime after the project item is saved. The generated context class contains methods and sub-classes that represent the defined SAP objects (see screenshots below).</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon9.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Before you access the SAP system for the first time you will be asked to enter the connection data. You may also load the connection data from SharePoint system. The ECS Designer GUI is shown in the screenshots below:</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon10.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon11.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The screenshot above for instance shows the tables dialog. After clicking the Add (+) button in the main designer screen and searching a SAP table in the search dialog, the designer opens the tables dialog. In this dialog you can change the name of the generated class, the class modifier and all needed properties (fields) the final class should contain. To preview your selection press the Preview button. The next screenshot shows the automatically generated classes in the file named EC1.Designer.cs:</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon12.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Using the generated code is simple. The project type we are using for this sample is a standard console application, therefore the ECS Designer is referencing the ERPConnectServices.Client.dll for desktop applications. Since we are not within the SharePoint context, we have to define the URI of the SharePoint system by passing this value into the constructor of the ERPConnectServicesContext class.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The designer has generated class MAKT and an access property MAKTList for the context class of the table MAKT. The type of this property MAKTList is ERPTableQuery&lt;MAKT&gt;, which is a LINQ queryable data type. This means you can use LINQ statements to define the underlying query. Internally, the ERPTableQuery&lt;T&gt; type will translate your LINQ query into call of ExecuteTableQuery.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small;"><img src="http://jbaurle.files.wordpress.com/2012/03/033012_0927_usingerpcon13.png" alt="" /></span><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;"> </span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">That&#8217;s it! SAP access as its best.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>Advanced Techniques</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">There are situations when you have to use the exact same SAP connection while calling a series of function modules in order to receive the correct result. Let&#8217;s take the following code:</span></span></p>
<p>&nbsp;</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:aea1ecc3-e982-42ab-87f6-0f1ad94ef2f2" class="wlWriterEditableSmartContent" style="margin: 0; display: inline; float: none; padding: 0;">
<pre class="brush: cpp;">ERPConnectServiceClient client = new ERPConnectServiceClient(); 

using(client.BeginConnectionScope())
{
    ERPFunction f = client.CreateFunction("BAPI_GOODSMVT_CREATE"); 

    ERPStructure s = f.Exports["GOODSMVT_HEADER"].ToStructure();
    s["PSTNG_DATE"] = "20110609"; // Posting Date in the Document
    s["PR_UNAME"] = "BAEURLE"; // UserName
    s["HEADER_TXT"] = "XXX"; // HeaderText
    s["DOC_DATE"] = "20110609"; // Document Date in Document 

    f.Exports["GOODSMVT_CODE"].ToStructure()["GM_CODE"] = "01"; 

    ERPStructure r = f.Tables["GOODSMVT_ITEM"].AddRow();
    r["PLANT"] = "1000";            // Plant
    r["PO_NUMBER"] = "4500017210";    // Purchase Order Number
    r["PO_ITEM"] = "010";        // Item Number of Purchasing Document
    r["ENTRY_QNT"] = 1;            // Quantity in Unit of Entry
    r["MOVE_TYPE"] = "101";        // Movement Type
    r["MVT_IND"] = "B";            // Movement Indicator
    r["STGE_LOC"] = "0001";        // Storage Location 

    f.Execute(); 

    string matDocument = f.Imports["MATERIALDOCUMENT"].ParamValue as string;
    string matDocumentYear = f.Imports["MATDOCUMENTYEAR"].ParamValue as string; 

    ERPTable ret = f.Tables["RETURN"]; //.ToADOTable(); 

    foreach(var i in ret)
        Console.WriteLine("{0} - {1}", i["TYPE"], i["MESSAGE"]); 

    ERPFunction fCommit = client.CreateFunction("BAPI_TRANSACTION_COMMIT");
    fCommit.Exports["WAIT"].ParamValue = "X";
    fCommit.Execute();
}</pre>
</div>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">In this sample we create a goods receipt for a goods movement with BAPI_GOODSMVT_CREATE. The final call to BAPI_TRANSACTION_COMMIT will only work, if the system under the hood is using the same connection object.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">The ERPConnect Services is not providing direct access to the underlying SAP connection, but the library offers a mechanism called connection scoping. You may create a new connection scope with the client library and telling ERPConnect Services to use the same SAP connection until you close the connection scope. Within the connection scope every library call will use the same SAP connection.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">In order to create a new connection scope you need to call the BeginConnectionScope method of the class ERPConnectServiceClient. The method returns an IDisposable object, which can be used in conjunction with the using statement of C# to end the connection scope. Alternatively, you may call the EndConnectionScope method.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">It&#8217;s also possible to use function modules with nested structures as parameters. This is a special construct of SAP. The goods receipt sample above is using a nested structure for the export parameter GOODSMVT_CODE. For more detailed information about nested structures and tables see the product documentation.</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana;"><span style="font-size: x-small;"><strong>Summary</strong> </span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: x-small;"> </span></span></p>
<p><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">ERPConnect Services for SharePoint 2010 is powerful product suite to integrate SAP business data into SharePoint applications. Combining the ERPConnect Services runtime with the BCS Connector tool unleashes the real power of this toolkit. More information about ERPConnect Services for SharePoint 2010 you will find here:</span></span></p>
<p>&nbsp;</p>
<p><a href="http://www.theobald-software.com/en/products/erpconnectservices.htm"><span style="font-family: times new roman; font-size: 12pt;"><span style="font-family: Verdana; font-size: x-small;">Product website of ERPConnect Services for SharePoint 2010</span></span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2012/02/using-erpconnect-services-to-integrate-sap-business-data-into-sharepoint-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Theobald Software releases ERPConnect Services for SharePoint 2010</title>
		<link>http://www.parago.de/2011/11/theobald-software-releases-erpconnect-services-for-sharepoint-2010/</link>
		<comments>http://www.parago.de/2011/11/theobald-software-releases-erpconnect-services-for-sharepoint-2010/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 12:34:19 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Theobald Software]]></category>
		<category><![CDATA[ERPConnect Services]]></category>
		<category><![CDATA[LINQ to SAP]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://www.parago.de/?p=909</guid>
		<description><![CDATA[Theobald Software GmbH is finally releasing an existing new product to integrate SAP business data into SharePoint 2010. ERPConnect Services is its name and consists of 3 components, which allow you the complete range of data integration between SharePoint and your SAP ERP/BW system. ERPConnect Services also gives you the opportunity to realize Single-Sign-On scenarios: Using [...]]]></description>
			<content:encoded><![CDATA[<p>Theobald Software GmbH is finally releasing an existing new product to integrate SAP business data into SharePoint 2010. ERPConnect Services is its name and consists of 3 components, which allow you the complete range of data integration between SharePoint and your SAP ERP/BW system.</p>
<p>ERPConnect Services also gives you the opportunity to realize Single-Sign-On scenarios: Using the SharePoint Secure Stores, users can access SAP with their personal SAP credentials. While doing so, all SAP safety guidelines will be available directly in SharePoint.</p>
<p><a title="Take a look!" href="http://www.theobald-software.com/en/products/erpconnectservices.htm" target="_blank">Take a look!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/11/theobald-software-releases-erpconnect-services-for-sharepoint-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FluentSP &#8211; The Fluent SharePoint API</title>
		<link>http://www.parago.de/2011/09/fluentsp-the-fluent-sharepoint-api/</link>
		<comments>http://www.parago.de/2011/09/fluentsp-the-fluent-sharepoint-api/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 16:43:24 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Fluent]]></category>
		<category><![CDATA[Fluent API]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://www.parago.de/?p=884</guid>
		<description><![CDATA[Download FluentSP 1.0 from Codeplex.com Once you are doing a lot of SharePoint programming you know you often have to write lengthy pieces of code to implement simple tasks like querying SharePoint lists. Nowadays you can read a lot of fluent APIs or fluent interface. For instance, jQuery, a JavaScript library that had successfully introduced [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://fluentsp.codeplex.com/" target="_blank">Download FluentSP 1.0 from Codeplex.com</a></p>
<p>Once you are doing a lot of SharePoint programming you know you often have to write lengthy pieces of code to implement simple tasks like querying SharePoint lists. Nowadays you can read a lot of fluent APIs or fluent interface. For instance, jQuery, a JavaScript library that had successfully introduced a fluent API to handle the hierarchical structure of the HTML documents.</p>
<p>Today, I want to introduce a small library I have developed, FluentSP, a modern fluent interface around the classic SharePoint 2010 API. By using FluentSP instead of the classic SharePoint API, you will be able to chain methods and act on sets of items of the underlying SharePoint objects.</p>
<p><em>What is a fluent API?</em><br />
Checkout this CodeProject article <a href="http://www.codeproject.com/KB/WPF/fluentAPI.aspx" target="_blank">A Look at Fluent APIs</a> and the Wikipedia article <a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">Fluent interface</a>.</p>
<p>To start into the fluent API you call the <strong>Use()</strong> method on <em>SPSite</em>, <em>SPWeb</em>, <em>SPWebCollection</em> or <em>SPListCollection</em>. The Use() method is implemented as an extension method that will return the entry facade object (see facade table below). Another entry point to the fluent API is the static class <strong>SP</strong> with its static methods CurrentSite, CurrentWeb, CurrentLists or RootWebLists.</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d2a9627a-4c29-447a-a1e1-0a0e3a36ee90" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">SPContext.Current.Site.Use()... // =&gt; Returns the SPSiteFacade as entry point

// OR:
SP.CurrentSite()...       // =&gt; Returns the SPSiteFacade as entry point</pre>
</div>
<p>Using the entry facade instance you can start chaining the available facade methods as follows:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d9dd536a-40d3-47ad-b4bb-a3e47048f11a" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">SP.CurrentSite().Web("Home").List("Tasks").Items().ForEach(i =&gt; // Do something with the item i of type SPListItem...);

// OR:
SP.CurrentSite()
      .Web("Home")
         .List("Tasks")
           .Items()
           .ForEach(i =&gt; // Do something with...);</pre>
</div>
<p>Each facade object is actually wrapping an underlying data item, for instance the SPSiteFacade class is the fluent wrapper of the SPSite class. Depending on what kind of facade methods you are calling the method is returning either the current facade instance (e.g., ForEach() or Where()) or the method is returning a new child facade object (e.g. Items()). During the process of chaining methods in such a way you will build up a tree or hierarchy of facade instances. In order to step back to the parent or previous facade instance you need to call the End() method:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:baeb4a9d-311b-4103-a3e8-cad67410cdb9" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">site.Use()
       .RootWeb()
         .Site()
       .End()		// Returns SPWebFacade  as parent facade
         .Site()
       .End()		// Returns SPWebFacade  as parent facade
     .End();		// Returns SPSiteFacade as parent facade</pre>
</div>
<p>FluentSP is currently missing a number of possible useful methods, but you can easily extend the FluentSP API with custom facade classes and extension methods, see below and source code for implementation examples.</p>
<p><strong></strong></p>
<p><strong>Samples</strong></p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:2cdd2c2d-f7c0-48d0-8610-ec9ef4aa3e5b" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">SPSite site = SPContext.Current.Site;

// ----------------------------

// Outputs titles of all lists of the root web where the list title starts with T
site.Use().RootWeb().Lists().Where(l =&gt; l.Title.StartsWith("T")).ForEach(l =&gt; Console.WriteLine(l.Title));

// Outputs titles of all lists of the root web where the list title ends with a ts (using RegEx)
site.Use().RootWeb().Lists("ts$").ForEach(l =&gt; Console.WriteLine(l.Title)).Count(out c);

// Outputs titles of all lists of the root web in ascending order where the starts with T
site.Use().RootWeb().Lists().Where(l =&gt; l.Title.StartsWith("T")).OrderBy(l =&gt; l.Title).ForEach(l =&gt; Console.WriteLine(l.Title));

// Outputs titles of all lists of the root web in descending order where the starts with T
site.Use()
    .RootWeb()
      .Lists()
      .Where(l =&gt; l.Title.StartsWith("T"))
      .OrderByDescending(l =&gt; l.Title)
      .ForEach(l =&gt; Console.WriteLine(l.Title));

// ----------------------------

// Delete all items in the Members list, then add 7 new members and then select and output
// the titles of a few of the newly created items
site.Use()
    .RootWeb()
      .List("Members")
      .Do(w =&gt; Console.WriteLine("Deleting all members..."))
       .Items()
       .Delete()
      .End()
      .Do(w =&gt; Console.WriteLine("Adding all members..."))
      .AddItems(7, (i, c) =&gt; i["Title"] = "Member " + c)
       .Items()
       .Skip(2)
       .TakeUntil(i =&gt; ((string)i["Title"]).EndsWith("6"))
       .ForEach(i =&gt; Console.WriteLine(i["Title"]));

// ----------------------------

// Search for lists that are created by specific a user and depending on the results
// displays different messages by calling the IfAny or IfEmpty methods
site.Use()
    .RootWeb()
      .Lists()
      .ThatAreCreatedBy("Unknown User")
      .IfAny(f =&gt; f.ForEach(l =&gt; Console.WriteLine(l.Title)))
      .IfAny(l =&gt; l.Title.StartsWith("M"), f =&gt; Console.WriteLine("Lists found that starts with M*"))
      .IfEmpty(f =&gt; Console.WriteLine("No lists found for user"))
    .End()
    .Do(w =&gt; Console.WriteLine("---"))
      .Lists()
      .ThatAreCreatedBy("System Account")
      .IfAny(f =&gt; f.ForEach(l =&gt; Console.WriteLine(l.Title)));

// ----------------------------

var items = new List&lt;SPListItem&gt;();

// Query with Skip and TakeUnitl methods
site.Use().RootWeb().List("Members").Items().Skip(2).TakeUntil(i =&gt; i.Title.EndsWith("5")).ForEach(i =&gt; { items.Add(i); Console.WriteLine(i.Title); });

// Query with Skip and TakeWhile methods
site.Use()
    .RootWeb()
      .List("Members")
       .Items()
       .Skip(2)
       .TakeWhile(i =&gt; i.Title.StartsWith("Member"))
       .ForEach(i =&gt; { items.Add(i); Console.WriteLine(i.Title); })
      .End()
       .Items()
       .Where(i =&gt; i.Title == "XYZ")
       .ForEach(i =&gt; { items.Add(i); Console.WriteLine(i.Title); });

// ----------------------------

// Adds new items using the Do method with the passed facade object
site.Use()
    .RootWeb()
    .AllowUnsafeUpdates()
      .List("Members")
      .Do((f, l) =&gt; {
        for(int c = 1; c &lt;= 5; c++)
          f.AddItem(i =&gt; i["Title"] = "Standard Member #" + c);
      })
      .AddItem(i =&gt; i["Title"] = "Premium Member")
       .Items()
        .OrderBy(i =&gt; i.Title)
        .ForEach(i =&gt; Console.WriteLine(i["Title"]));</pre>
</div>
<p><strong>Extensibility Samples</strong></p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:310b9254-3296-4e21-9f4a-b355cec0081b" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">// This sample is using the ThatAreCreatedBy extension method defined in Extensions.cs to show how to extend the fluent API
site.Use()
        .RootWeb()
          .Lists()
          .ThatAreCreatedBy("System Account", "jbaurle")
          .Count(c =&gt; Console.WriteLine("Lists found: {0}", c))
          .ForEach(l =&gt; Console.WriteLine(l.Title));

// This sample uses the new SPWebApplicationFacade extenion defined in SPwebApplicationFacade.cs to show how to extend the fluent API
site.WebApplication.Use()
              .Sites()
              .ForEach(i =&gt; Console.WriteLine(i.Url));

// This sample uses an alternative implementation for SPSiteFacade defined in SPSiteFacadeAlternate.cs to show how to extend the fluent API
site.WebApplication.Use().WithFirstSite().DoSomething();
site.Use&lt;SPSiteFacadeAlternate&lt;BaseFacade&gt;&gt;().DoSomething();</pre>
</div>
<p>The custom method ThatAreCreatedBy which is used in the first query of the extensibility samples is implemented as follows:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:3687795f-1367-4880-b7f5-d5f2c0283133" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">static class Extensions
{
  public static SPListCollectionFacade&lt;TParentFacade&gt; ThatAreCreatedBy&lt;TParentFacade&gt;(this SPListCollectionFacade&lt;TParentFacade&gt; facade, params string[] names)
    where TParentFacade : BaseFacade
  {
    // NOTE: This sample uses the GetCollection method of the given facade instance to retrieve the current
    // collection and adds the its query (see LINQ Deferred Execution). The Set method updates the
    // underlying collection. The GetCurrentFacade method will then return the current facade to allow
    // method chaining.

    if(names.Length &gt; 0)
      facade.Set(facade.GetCollection().Where(i =&gt; names.Contains(i.Author.Name)));

    return facade.GetCurrentFacade();
  }
}</pre>
</div>
<p>For more samples and details check out the source code you can download from <a href="http://fluentsp.codeplex.com/" target="_blank">Codeplex</a>.</p>
<p><strong>Built-In Facades and Methods</strong></p>
<p>See <a href="http://fluentsp.codeplex.com/" target="_blank">Codeplex</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/09/fluentsp-the-fluent-sharepoint-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ParagoServices &#8211; A SharePoint 2010 Service Application Sample</title>
		<link>http://www.parago.de/2011/09/paragoservices-a-sharepoint-2010-service-application-sample/</link>
		<comments>http://www.parago.de/2011/09/paragoservices-a-sharepoint-2010-service-application-sample/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 20:26:37 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Excel Services]]></category>
		<category><![CDATA[Service Architecture]]></category>
		<category><![CDATA[SharePoint Middleware]]></category>
		<category><![CDATA[SharePoint Service Application]]></category>

		<guid isPermaLink="false">http://www.parago.de/2011/09/paragoservices-a-sharepoint-2010-service-application-sample/</guid>
		<description><![CDATA[The new Service Application Architecture in SharePoint 2010 is a replacement of the Shared Service Provider (SSP) architecture known from SharePoint 2007. The framework offers greater flexibility in configuring, scaling and administrating SharePoint shared services. The Service Application Framework (SAF) is now part of SharePoint 2010 Foundation, the old Shared Service Provider framework was part [...]]]></description>
			<content:encoded><![CDATA[<p>The new Service Application Architecture in SharePoint 2010 is a replacement of the Shared Service Provider (SSP) architecture known from SharePoint 2007. The framework offers greater flexibility in configuring, scaling and administrating SharePoint shared services.</p>
<p>The Service Application Framework (SAF) is now part of SharePoint 2010 Foundation, the old Shared Service Provider framework was part of the MOSS 2007. But best of all, custom service applications can be developed and integrated next to the standard services like Excel Services or Business Connectivity Services (BCS).</p>
<p>In 2010 I started to develop a new product called ERPConnect Services for <a href="http://www.theobald-software.com" target="_blank">Theobald Software</a>, a company developing products for SAP integration (.NET / SAP Interoperability). ERPConnect Services is a service application built on top of the SharePoint 2010 Shared Service Architecture similar to Excel Services. ERPConnect Services offer a secure and easy to use interface operations to integrate SAP business data in SharePoint applications. The product will be released soon.</p>
<p>Based on the experience developing ERPConnect Services I have created a sample implementation of a simple SharePoint 2010 Service Application named <a href="http://paragoservices.codeplex.com/" target="_blank">ParagoServices</a>. You can download the source code at <a href="http://paragoservices.codeplex.com/" target="_blank">Codeplex</a>. At Codeplex you will find some screenshots. In the next couple weeks I will try to add another post describing the implementation in more detail. Meanwhile see the following links:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/ee536263.aspx" target="_blank">SharePoint 2010 Service Application Framework</a><br />
<a href="http://technet.microsoft.com/en-us/edge/Video/ff711423" target="_blank">Understanding the Service Applications of SharePoint 2010</a></p>
<p>Here a screenshot to give you a first impression:</p>
<p><a href="http://www.parago.de/wp-content/uploads/2011/09/image.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.parago.de/wp-content/uploads/2011/09/image_thumb.png" border="0" alt="image" width="309" height="366" /></a></p>
<p><a href="http://paragoservices.codeplex.com/" target="_blank">See more screenshots and get the ParagoServices source code via Codeplex.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/09/paragoservices-a-sharepoint-2010-service-application-sample/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Implement A Generic Template Engine For SharePoint 2010 Using DotLiquid</title>
		<link>http://www.parago.de/2011/05/how-to-implement-a-generic-template-engine-for-sharepoint-2010-using-dotliquid-2/</link>
		<comments>http://www.parago.de/2011/05/how-to-implement-a-generic-template-engine-for-sharepoint-2010-using-dotliquid-2/#comments</comments>
		<pubDate>Wed, 04 May 2011 10:09:03 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[ASP.NET (MVC)]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[DotLiquid]]></category>
		<category><![CDATA[mail templates]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[template engine]]></category>

		<guid isPermaLink="false">http://www.parago.info/?p=375</guid>
		<description><![CDATA[During the process of creating a complex SharePoint application you often need to send mails and create text files based on SharePoint data elements like SPListItem or SPWeb. Mail templates for instance mostly contain specific list item data. It would be helpful sometimes if the text generation itself is template-driven. This article shows how to [...]]]></description>
			<content:encoded><![CDATA[<p>During the process of creating a complex SharePoint application you often need to send mails and create text files based on SharePoint data elements like SPListItem or SPWeb. Mail templates for instance mostly contain specific list item data. It would be helpful sometimes if the text generation itself is template-driven.</p>
<p>This article shows how to implement a generic template manager based on the free DotLiquid templating system with SharePoint specific extensions. This allows you for example to iterate through all SharePoint lists available within a SiteCollection and render only details for lists which contain Task in their title:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:8a8eaa52-e3f4-4dab-964d-c5fbcffb168a" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: text;">&lt;p&gt;All task lists for the current web '{{SP.Web.Title}}' and site '{{SP.Site.Url}}'
  &lt;ul&gt;
    {% for list in SP.Lists %}
      {% if list.Title contains 'Task' %}
        &lt;li&gt;&lt;i&gt;{{list.Title}}&lt;/i&gt; with ID '{{Slist.ID|upcase}}' (&lt;i&gt;(Created:
                                                     {{list.Created|sp_format_date}})&lt;/i&gt;&lt;/li&gt;
      {% endif %}
    {% endfor %}
  &lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;All lists for current web '{{SP.Site.RootWeb.Title}}' created by the 'splists' tag
  &lt;ul&gt;{% splists '&lt;li&gt;{0}&lt;/li&gt;' %}&lt;/ul&gt;
&lt;/p&gt;</pre>
</div>
<p>The screenshot below shows the result of the rendered template sample:</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/TemplateEngine.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="TemplateEngine" src="http://www.parago.info/wp-content/uploads/2011/05/TemplateEngine_thumb.png" border="0" alt="TemplateEngine" width="644" height="396" /></a></p>
<p>Of course the technique implemented in this article can also be used in conjunction with other technologies or applications, it’s not only SharePoint related.</p>
<p><strong>DotLiquid Template Engine</strong></p>
<p>The DotLiquid template engine is a C# port of the Ruby’s Liquid templating system and is available for .NET 3.5 and above. DotLiquid is open source and can be downloaded at dotliquidmarkup.org. The software is also available as NuGet package for Visual Studio.</p>
<p>The templating system includes features like variable, text replacement, conditional evaluation and loop statements that are similar to common programming languages. The language elements consists of tags and filter constructs.</p>
<p>The engine can also be easily extended by implementing and adding custom filters and/or tags. This article actually shows how to extend the DotLiquid and implement SharePoint specific parts.</p>
<p>The following sample shows a Liquid template file:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:5819e1a6-3256-4799-804f-70dfcd6702cb" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">&lt;p&gt;{{ user.name | upcase }} has to do:&lt;/p&gt;

&lt;ul&gt;
{% for item in user.tasks -%}
  &lt;li&gt;{{ item.name }}&lt;/li&gt;
{% endfor -%}
&lt;/ul&gt;</pre>
</div>
<p>Output markup is surrounded by curly brackets {{…}} and tag markup by {%&#8230;%}. Output markup can take filter definitions like upcase. Filters are simple static methods, where the first parameter is always the output of the left side of the filter and the return value of the filter will be the new left value when the next filter is run. When there are no more filters, the template will receive the resulting string.</p>
<p>There are a big number of standard filters available to use, but later on we will implement a custom filter method for SharePoint. The result of the above rendered template looks like:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:942e6c93-5134-4c80-8ded-f3c3771ea613" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">&lt;p&gt;TIM JONES has to do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Documentation&lt;/li&gt;
  &lt;li&gt;Code comments&lt;/li&gt;
&lt;/ul&gt;</pre>
</div>
<p>To pass variables and render the template you first need to parse the template and the then just call the Render method with the variable values:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:331b380e-94de-4202-8c01-26ee17b08a8c" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">string templateCode = @"&lt;ul&gt;
{% for item in user.tasks -%}
  &lt;li&gt;{{ item.name }}&lt;/li&gt;
{% endfor -%}
&lt;/ul&gt;";

Template template = Template.Parse(templateCode);

string result = template.Render(Hash.FromAnonymousObject(new {
                                    user = new User
                                    {
                                      Name = "Tim Jones",
                                      Tasks = new List&lt;Task&gt; {
                                        new Task { Name = "Documentation" },
                                        new Task { Name = "Code comments" }
                                      }
                                    }}));

public class User : Drop
{
	public string Name { get; set; }
	public List&lt;Task&gt; Tasks { get; set; }
}

public class Task : Drop
{
	public string Name { get; set;	 }
}</pre>
</div>
<p>&nbsp;</p>
<p>The User and Task classes inherit from the Drop class. This is an important class in DotLiquid. The next sections explains the class in more detail. It is out of scope of this article to discuss all the features for DotLiquid in detail. For more information please see the homepage of DotLiquid (dotliquidmarkup.org) or the website of the original creator of the Liquid template language at liquidmarkup.org. You will find there a lot of manuals and sample code.</p>
<p><strong>Template Manager</strong></p>
<p>The TemplateManager class is a wrapper over the DotLiquid template engine and provides SharePoint support. The class allows to cache parsed templates, to register tags and filters and render them using a top-level custom Drop class named SharePointDrop:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:24bd1fe7-ac82-4e6c-bc86-deae0eb3bcee" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal class TemplateManager
{
  public Dictionary&lt;string, Template&gt; Templates { get; protected set; }

  public TemplateManager()
  {
    Templates = new Dictionary&lt;string, Template&gt;();
  }

  public void AddTemplate(string name, string template)
  {
    if(string.IsNullOrEmpty(name))
      throw new ArgumentNullException("name");
    if(string.IsNullOrEmpty(template))
      throw new ArgumentNullException("template");

    if(Templates.ContainsKey(name))
      Templates[name] = Template.Parse(template);
    else
      Templates.Add(name, Template.Parse(template));
  }

  public void RegisterTag&lt;T&gt;(string tagName) where T : Tag, new()
  {
    Template.RegisterTag&lt;T&gt;(tagName);
  }

  public void RegisterFilter(Type type)
  {
    Template.RegisterFilter(type);
  }

  public string Render(string nameOrTemplate, IDictionary&lt;string, object&gt; values)
  {
    Template template;

    if(Templates.ContainsKey(nameOrTemplate))
      template = Templates[nameOrTemplate];
    else
      template = Template.Parse(nameOrTemplate);

    SharePointDrop sp = new SharePointDrop();

    if(values != null)
    {
      foreach(KeyValuePair&lt;string, object&gt; kvp in values)
        sp.AddValue(kvp.Key, kvp.Value);
    }

    return template.Render(new RenderParameters { LocalVariables =
             Hash.FromAnonymousObject(new { SP = sp }), RethrowErrors = true });
  }
}</pre>
</div>
<p>The Render method is using the SharePointDrop class to support objects like SPListItem or SPListCollection. The Drop class as key concept of DotLiquid must be explained in detail. The DotLiquid template engine is focusing on making templates safe. A Drop is a class which allows you to export DOM like objects. DotLiquid, by default, only accepts a limited number of types as parameters to the Render method. These data types include the .NET primitive types (integer, float, string, etc.), and some collection types including IDictionary, IList and IIndexable (a custom DotLiquid interface).</p>
<p>If DotLiquid would support arbitrary types, then it could result in properties or methods being unintentionally exposed to template authors. To prevent this, DotLiquid templating system uses Drop classes that use an opt-in approach to exposing object data.</p>
<p>The code following shows the SharePointDrop implementation:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:a2acc28e-a555-4bc7-8277-fa299b5b1c61" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal class SharePointDrop : Drop
{
  Dictionary&lt;string, object&gt; _values;

  public SharePointDrop()
  {
    _values = new Dictionary&lt;string, object&gt;();

    if(SPContext.Current != null)
      _values.Add("Site", SPContext.Current.Site);
    if(SPContext.Current != null)
      _values.Add("Web", SPContext.Current.Web);
    if(SPContext.Current != null)
      _values.Add("User", SPContext.Current.Web.CurrentUser);

    _values.Add("Date", DateTime.Now);
    _values.Add("DateISO8601",
                   SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now));

    // TODO: Add more default values
  }

  public void AddValue(string name, object value)
  {
    if(string.IsNullOrEmpty(name))
      throw new ArgumentNullException("name");

    if(_values.ContainsKey(name))
      _values[name] = value;
    else
      _values.Add(name, value);
  }

  public override object BeforeMethod(string method)
  {
    if(!string.IsNullOrEmpty(method) &amp;&amp; _values.ContainsKey(method))
      return DropHelper.MayConvertToDrop(_values[method]);

    return null;
  }
}</pre>
</div>
<p>The SharePointDrop class main objective is to solve the problem of casting unsupported data types like SPListItem or SPListItemCollection and other SharePoint related types. Therefore the class is overriding the BeforeMethod method of the Drop class to analyse the requested variable value. If the variable is available in the value context the method will try to cast the data type to a known Drop type by calling the MayConvertToDrop method of the DropHelper class:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d8feb368-37c5-49ba-8b2c-103b907c69b6" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">public static object MayConvertToDrop(object value)
{
  if(value != null)
  {
    // TODO: Add your own drop implementations here

    if(value is SPList)
      return new SPPropertyDrop(value);
    if(value is SPListCollection)
      return ConvertDropableList&lt;SPPropertyDrop, SPList&gt;(value as ICollection);
    if(value is SPListItem)
      return new SPListItemDrop(value as SPListItem);
    if(value is SPListItemCollection)
      return ConvertDropableList&lt;SPListItemDrop, SPListItem&gt;(value as ICollection);
    if(value is SPWeb)
      return new SPPropertyDrop(value);
    if(value is SPSite)
      return new SPPropertyDrop(value);
    if(value is SPUser)
      return new SPPropertyDrop(value);
    if(value is Uri)
      return ((Uri)value).ToString();
    if(value is Guid)
      return ((Guid)value).ToString("B");
  }

  return value;
}</pre>
</div>
<p>The SPListItemDrop class for instance is returning the value of the requested field:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f6f433e1-e6d0-4d00-aeec-ee4b9b1544d4" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal class SPListItemDrop : SPDropBase
{
  public SPListItem ListItem { get { return DropableObject as SPListItem; } }

  public SPListItemDrop()
  {
  }

  public SPListItemDrop(SPListItem listItem)
  {
    DropableObject = listItem;
  }

  public override object BeforeMethod(string method)
  {
    if(!string.IsNullOrEmpty(method))
    {
      StringBuilder sb = new StringBuilder();
      string name = method + "\n";

      for(int i = 0; i &lt; name.Length; i++)
      {
        if(name[i] == '\n')
          continue;
        if(name[i] == '_')
        {
          if(name[i + 1] != '_')
            sb.Append(' ');
          else
          {
            i++;
            sb.Append('_');
          }
        }
        else
          sb.Append(name[i]);
      }

      name = sb.ToString();

      if(ListItem.Fields.ContainsField(name))
        return DropHelper.MayConvertToDrop(ListItem[name]);
    }

    return null;
  }
}</pre>
</div>
<p>The method parameter (field name of the SPListItem) of the BeforeMethod method can contain underscores which are replaced by spaces. So, field names with spaces like Start Date of the Task item must be defined in the template as {{task.Start_Date}}.</p>
<p>The SPPropertyDrop class, also part of the solution of this article, is a generic Drop implementation which exposes all properties of an object and may cast them if needed into an Drop objects again. For implementation details see the source code.</p>
<p><strong>Filters and Tags</strong></p>
<p>The solution is also providing a custom filter and tag implementation. The filter called sp_format_date (see template above) is implemented by the method SPFormatDate and is calling the FormatDate method of the class SPUtility form the SharePoint API:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f946a813-7f12-441a-9369-5ca0bbd1ddda" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal static class SPFilters
{
  public static object SPFormatDate(object input)
  {
    DateTime dt = DateTime.MinValue;

    if(input is string)
    {
      try
      {
        dt = SPUtility.ParseDate(SPContext.Current.Web, input as string,
               SPDateFormat.DateOnly, false);
      }
      catch { }
    }
    else if(input is DateTime)
      dt = (DateTime)input;

    if(dt != DateTime.MinValue &amp;&amp; dt != DateTime.MaxValue &amp;&amp; SPContext.Current != null)
      return SPUtility.FormatDate(SPContext.Current.Web, (DateTime)input,
               SPDateFormat.DateOnly);

    return input;
  }
}</pre>
</div>
<p>The custom tag named splists is returning a formatted list of all SPList object names of the current web (see template above):</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:fbc9ba06-7b1b-46c8-91f3-e673b2d35539" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal class SPListsTag : Tag
{
  string _format;

  public override void Initialize(string tagName, string markup, List&lt;string&gt; tokens)
  {
    base.Initialize(tagName, markup, tokens);

    if(string.IsNullOrEmpty(markup))
      _format = "{0}";
    else
      _format = markup.Trim().Trim("\"".ToCharArray()).Trim("'".ToCharArray());
  }

  public override void Render(Context context, StreamWriter result)
  {
    base.Render(context, result);

    if(SPContext.Current != null &amp;&amp; !string.IsNullOrEmpty(_format))
    {
      foreach(SPList list in SPContext.Current.Web.Lists)
        result.Write(string.Format(_format, list.Title));
    }
  }
}</pre>
</div>
<p><a href="http://content.parago.de/samples/SP2010TemplateEngine.zip">Download Source Code</a> | <a href="http://content.parago.de/articles/SP2010TemplateEngine/HowToImplementAGenericTemplateEngineForSharePoint2010UsingDotLiquid.pdf">Download Article (PDF)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/05/how-to-implement-a-generic-template-engine-for-sharepoint-2010-using-dotliquid-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Use SharePoint 2010 Secure Store As Single Sign-On Service For SAP Applications Using ERPConnect</title>
		<link>http://www.parago.de/2011/04/how-to-use-sharepoint-2010-secure-store-as-single-sign-on-service-for-sap-applications-using-erpconnect/</link>
		<comments>http://www.parago.de/2011/04/how-to-use-sharepoint-2010-secure-store-as-single-sign-on-service-for-sap-applications-using-erpconnect/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 08:54:17 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[ASP.NET (MVC)]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[ERPConnect]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Theobald Software]]></category>
		<category><![CDATA[SAP R/3]]></category>
		<category><![CDATA[Secure Store]]></category>
		<category><![CDATA[Single Sign-On]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://www.parago.info/?p=418</guid>
		<description><![CDATA[The Secure Store Service in SharePoint 2010 replaces the Single Sign-on Shared Service of MOSS 2007 and provides an easy way to map user credentials of external resources like SAP systems to Windows users. During the process of developing SAP interfaces using the very handy ERPConnect library from Theobald Software you have to open a [...]]]></description>
			<content:encoded><![CDATA[<p>The Secure Store Service in SharePoint 2010 replaces the Single Sign-on Shared Service of MOSS 2007 and provides an easy way to map user credentials of external resources like SAP systems to Windows users. During the process of developing SAP interfaces using the very handy ERPConnect library from Theobald Software you have to open a R3 connection with the SAP system using SAP account credentials (username and password).</p>
<p>In most cases you will use a so called technical user with limited access rights to execute or query objects in SAP, but a SAP system saves a lot of sensitive data which cannot all be shown to all users. So, creating a new secure store in SharePoint 2010 to save the SAP user credentials will be the solution. Accessing the secure store from program code is quite simple.</p>
<p>A trail version of the ERPConnect library can be downloaded at <a href="http://www.theobald-software.com/">www.theobald-software.com</a>.</p>
<p><strong>Secure Store Configuration</strong></p>
<p>The Secure Store Service will be managed by the Central Administration (CA) of SharePoint 2010 under <em>Application Management &gt; Manage service applications &gt; Secure Store Service</em>:</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/Screenshot1_thumb3.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Screenshot1_thumb3" src="http://www.parago.info/wp-content/uploads/2011/05/Screenshot1_thumb3_thumb.png" border="0" alt="Screenshot1_thumb3" width="644" height="230" /></a></p>
<p>As the screenshot above shows is it possible to create multiple target applications within one Secure Store Service.</p>
<p>Clicking the New button will open the Create New Secure Store Target Application page. In this dialog you have to enter the new Target Application ID, a display name, a contact email address and other application related details (see screenshot below).</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/Screenshot2_thumb1.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Screenshot2_thumb1" src="http://www.parago.info/wp-content/uploads/2011/05/Screenshot2_thumb1_thumb.png" border="0" alt="Screenshot2_thumb1" width="644" height="343" /></a></p>
<p>Next, the application fields must be defined:</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/Screenshot3_thumb1.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Screenshot3_thumb1" src="http://www.parago.info/wp-content/uploads/2011/05/Screenshot3_thumb1_thumb.png" border="0" alt="Screenshot3_thumb1" width="644" height="250" /></a></p>
<p>It’s important to select the field type User Name and Password, because our implementation later on will check the target application for those two field types.</p>
<p>In the last dialog step the application administrator must be defined. After defining the administrator and clicking the Ok button SharePoint is creating a new secure store:</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/Screenshot5_thumb1.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Screenshot5_thumb1" src="http://www.parago.info/wp-content/uploads/2011/05/Screenshot5_thumb1_thumb.png" border="0" alt="Screenshot5_thumb1" width="644" height="206" /></a></p>
<p>Next, the Windows users must be mapped to the SAP user credentails. Therefore mark the checkbox for the newly created secure store SAPCredentialsStore and click the Set button in the toolbar. This opens the following dialog:</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/Screenshot6_thumb1.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Screenshot6_thumb1" src="http://www.parago.info/wp-content/uploads/2011/05/Screenshot6_thumb1_thumb.png" border="0" alt="Screenshot6_thumb1" width="644" height="441" /></a></p>
<p>The Credential Owner is the Windows user for whom the SAP user credentials will be set. Enter the SAP username and password and click the Ok button to save them.</p>
<p>That’s it !</p>
<p><strong>Secure Store Programming</strong></p>
<p>Accessing the secure store by code is simple. We implement a SecureStore class which will encapsulate all the access logic. A second class called SecureStoreCredentials contains the retrieved user credentials returned by the method GetCurrentCredentials of the SecureStore class.</p>
<p>But first, we need to create a Visual Studio 2010 SharePoint project and reference a couple of assemblies. You can directly enter the file paths in the Reference dialog (Browse tab) to add the assemblies:</p>
<p><em>Microsoft.BusinessData.dll</em><br />
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.BusinessData.dll</p>
<p><em>Microsoft.Office.SecureStoreService.dll<br />
</em>C:\Windows\assembly\GAC_MSIL\Microsoft.Office.SecureStoreService\14.0.0.0__71e9bce111e9429c\Microsoft.Office.SecureStoreService.dll</p>
<p>The following code shows the SecureStore class implementation:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:ee6cfa12-2c0b-49b2-865b-7a56f53e9261">
<pre>internal class SecureStore
{
  public string ApplicationId { get; private set; }

  public SecureStore(string applicationId)
  {
    if(string.IsNullOrEmpty(applicationId))
      throw new ArgumentNullException("applicationId");
    if(!IsApplicationValid(applicationId))
      throw new ArgumentException(string.Format("Target application with ID '{0}' is not defined.", applicationId));

    ApplicationId = applicationId;
  }

  public SecureStoreCredentials GetCurrentCredentials()
  {
    SecureStoreProvider provider = new SecureStoreProvider { Context = SPServiceContext.Current };
    string userName = string.Empty;
    string password = string.Empty;

    using(SecureStoreCredentialCollection data = provider.GetCredentials(ApplicationId))
    {
      foreach(ISecureStoreCredential c in data)
      {
        if(c != null)
        {
          if(c.CredentialType == SecureStoreCredentialType.UserName)
            userName = GetDecryptedCredentialString(c.Credential);
          else if(c.CredentialType == SecureStoreCredentialType.Password)
            password = GetDecryptedCredentialString(c.Credential);
        }
      }
    }

    if(string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
      throw new SecureStoreException("Credentials for the current Windows user are not valid or not defined.");

    return new SecureStoreCredentials(userName, password);
  }

  public static bool IsApplicationValid(string applicationId)
  {
    if(string.IsNullOrEmpty(applicationId))
      throw new ArgumentNullException("applicationId");

    SecureStoreProvider provider = new SecureStoreProvider { Context = SPServiceContext.Current };

    foreach(TargetApplication application in provider.GetTargetApplications())
    {
      if(application.ApplicationId == applicationId)
      {
        ReadOnlyCollection&lt;ITargetApplicationField&gt; fields = provider.GetTargetApplicationFields(applicationId);
        bool existsUserNameDefinition = false;
        bool existsPasswordDefinition = false;

        foreach(TargetApplicationField field in fields)
        {
          if(field.CredentialType == SecureStoreCredentialType.UserName)
            existsUserNameDefinition = true;
          else if(field.CredentialType == SecureStoreCredentialType.Password)
            existsPasswordDefinition = true;
        }

        if(existsUserNameDefinition &amp;&amp; existsPasswordDefinition)
          return true;
      }
    }

    return false;
  }

  public static string GetDecryptedCredentialString(SecureString secureString)
  {
    IntPtr p = Marshal.SecureStringToBSTR(secureString);

    try
    {
      return Marshal.PtrToStringUni(p);
    }
    finally
    {
      if(p != IntPtr.Zero)
        Marshal.FreeBSTR(p);
    }
  }
}</pre>
</div>
<p>The constructor checks if an application ID is passed and if it’s valid by calling the static method IsApplicationValid. In first place, the IsApplicationValid method is creating an instance of the SecureStoreProvider class to get access to Secure Store Service. The SecureStoreProvider class provides all methods to talk to the SharePoint service. Then, the method queries for all target applications and checks for the given application. If the application has been created and can be found, the method will analyse the application field definitions. The IsApplicationValid method then looks for two fields of type User Name and Password (see above).</p>
<p>The GetCurrentCredentials method is actually trying to get the SAP user credentials from the store. The method is creating an instance of the SecureStoreProvider class to get access to service and then calls the GetCredentials method of the provider class. If credentials are available the method decrypt the username and password from type SecureString using the internal method GetDecryptedCredentialString. It then will wrap and return the data into an instance of the SecureStoreCredentails class.</p>
<p>For more details of the implementation see the source code.</p>
<p><strong>Accessing SAP Using The Secure Store Credentials</strong></p>
<p>The sample and test code calls the SAP function module SD_RFC_CUSTOMER_GET to retrieve all customer data that match certain criteria (where NAME1 starts with Te*):</p>
<p><a href="http://www.parago.info/wp-content/uploads/2011/05/Screenshot7_thumb1.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Screenshot7_thumb1" src="http://www.parago.info/wp-content/uploads/2011/05/Screenshot7_thumb1_thumb.png" border="0" alt="Screenshot7_thumb1" width="644" height="443" /></a></p>
<p>The following code shows the implementation of the Test button click event:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:a440df40-cc05-4371-ac9d-9319368dbc7f">
<pre>protected void OnTestButtonClick(object sender, EventArgs e)
{
  string licenseKey = "&lt;LICENSEKEY&gt;";
  string connectionStringFormat = "CLIENT=800 LANG=EN USER={0} PASSWD={1} ASHOST=HAMLET ...";

  R3Connection connection = null;

  try
  {
    LIC.SetLic(licenseKey);

    ...

    SecureStoreCredentials credentials =
      new SecureStore(ApplicationID.Text).GetCurrentCredentials();
    string connectionstring =
      string.Format(connectionStringFormat, credentials.UserName, credentials.Password);

    connection = new R3Connection(connectionstring);
    connection.Open();

    RFCFunction function = connection.CreateFunction("SD_RFC_CUSTOMER_GET");
    function.Exports["NAME1"].ParamValue = "Te*";
    function.Execute();

    ResultGrid.DataSource = function.Tables["CUSTOMER_T"].ToADOTable();
    ResultGrid.DataBind();

    OutputLabel.Text = string.Format("The test called...",
      ApplicationID.Text, Web.CurrentUser.Name, Web.CurrentUser.LoginName,
      credentials.UserName);
  }
  catch(Exception ex)
  {
    WriteErrorMessage(ex.Message);
  }
  finally
  {
    if(connection != null &amp;&amp; connection.Ping())
      connection.Close();
  }
}</pre>
</div>
<p>The interesting part is the retrieval of the SAP user credentials from the secure store defined in the text box named ApplicationID. The application ID will be passed as parameter to the constructor of the SecureStore class. After creating the instance the method GetCurrentCredentials will be called to ask the store for the credentials of the current Windows user.</p>
<p>After the user credential query has been successfully executed the SAP connection string will be constructed. Then the connection string will then be used to create an instance of the R3Connection class to connect with the SAP system. The remaining code is just calling the function module SD_RFC_CUSTOMER_GET and binding the result to the SPGridView.</p>
<p><a href="http://content.parago.de/samples/SP2010SecureStoreSAP.zip">Download Source Code</a> | <a href="http://content.parago.de/articles/SP2010SecureStoreSAP/HowToUseSharePoint2010SecureStoreAsSingleSignOnServiceForSAPApplicationsUsingERPConnect.pdf">Download Article (PDF)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/04/how-to-use-sharepoint-2010-secure-store-as-single-sign-on-service-for-sap-applications-using-erpconnect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Export SharePoint Task List Data To PDF Using A Templating System</title>
		<link>http://www.parago.de/2011/04/how-to-export-sharepoint-task-list-data-to-pdf-using-a-templating-system/</link>
		<comments>http://www.parago.de/2011/04/how-to-export-sharepoint-task-list-data-to-pdf-using-a-templating-system/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 16:47:38 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.parago.de/?p=862</guid>
		<description><![CDATA[A couple of times I had the situation where I needed to export SharePoint list data into a PDF file in a customized way. I wanted to use some kind of template technology to translate SharePoint list data into a PDF file. I was working with a text templating system called DotLiquid before (see also [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of times I had the situation where I needed to export SharePoint list data into a PDF file in a customized way. I wanted to use some kind of template technology to translate SharePoint list data into a PDF file. I was working with a text templating system called DotLiquid before (see also my post <a href="http://www.parago.de/2011/05/how-to-implement-a-generic-template-engine-for-sharepoint-2010-using-dotliquid-2/" target="_blank">How To Implement A Generic Template Engine For SharePoint 2010 Using DotLiquid</a><a href="http://www.parago.de/2011/05/how-to-implement-a-generic-template-engine-for-sharepoint-2010-using-dotliquid-2/">)</a>.</p>
<p>It&#8217;s a really simple and easy to use template engine for .NET.&#160; Another dependency is the PDF library ABCpdf8. You can download a trail version <a href="http://www.websupergoo.com/abcpdf-8.htm" target="_blank">here</a>. This library is very powerful in creating PDF files, especially in adding HTML content to a PDF document.</p>
<p>At the end of this post you can download a SharePoint 2010 sample solution that shows you how to create a new button called &quot;Export to PDF&quot; for each task list, see screenshot below:</p>
<p><a class="lightbox"  title ="ExportToPDF" href="http://www.parago.de/wp-content/uploads/2011/09/ExportToPDF.png"><img src="http://www.parago.de/wp-content/uploads/2011/09/ExportToPDF.png" alt="" title="ExportToPDF" class="alignnone size-full wp-image-866" /></a></p>
<p>This post is actually not describing all the implementation details. I currently have not the time to do this, but I still want to share this solution with you.</p>
<p>The SharePoint 2010 solution adds a new custom action called PDFCreationAction. This action will add a new ribbon button called “Export to PDF” next to the “Export to Excel” button. The button will be displayed for task lists only.</p>
<p>The command action will link to an ASPX-file called CreatePDF.aspx that is doing the actual work. The SharePoint list ID and will be passed as parameter. The Page_Load method of the web form is executing the template against the list data and then the HTML representation will get added to a PDF document using the ABCpdf8 library.</p>
<p>That&#8217;s all!</p>
<p><a href="http://content.parago.de/samples/SP2010HTML2PDF.zip">Download Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/04/how-to-export-sharepoint-task-list-data-to-pdf-using-a-templating-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Implement A Modern Progress Dialog For WPF Applications</title>
		<link>http://www.parago.de/2011/04/how-to-implement-a-modern-progress-dialog-for-wpf-applications/</link>
		<comments>http://www.parago.de/2011/04/how-to-implement-a-modern-progress-dialog-for-wpf-applications/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 19:13:58 +0000</pubDate>
		<dc:creator>Jürgen Bäurle</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[Background Process]]></category>
		<category><![CDATA[BackgroundWorker]]></category>
		<category><![CDATA[progress bar]]></category>
		<category><![CDATA[Progress Dialog]]></category>

		<guid isPermaLink="false">http://www.parago.info/2011/05/how-to-implement-a-modern-progress-dialog-for-wpf-applications/</guid>
		<description><![CDATA[Developing a Windows Presentation Foundation (WPF) application requires sometimes to execute an asynchronous task with long-running execution steps, e.g. calling a web service. If those steps are triggered by user interactions, you want show a progress dialog to block the user interface and display detail step information. In some cases you also want to allow [...]]]></description>
			<content:encoded><![CDATA[<p>Developing a Windows Presentation Foundation (WPF) application requires sometimes to execute an asynchronous task with long-running execution steps, e.g. calling a web service. If those steps are triggered by user interactions, you want show a progress dialog to block the user interface and display detail step information. In some cases you also want to allow the user to stop the long-running task by clicking a Cancel button.</p>
<p>The following screenshots show some samples of progress dialogs implemented in this blog entry:</p>
<p><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.parago.de/wp-content/uploads/2011/05/image_thumb.png" border="0" alt="image" width="244" height="97" /></p>
<p><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.parago.de/wp-content/uploads/2011/05/image_thumb1.png" border="0" alt="image" width="244" height="97" /></p>
<p><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.parago.de/wp-content/uploads/2011/05/image_thumb2.png" border="0" alt="image" width="244" height="97" /></p>
<p><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.parago.de/wp-content/uploads/2011/05/image_thumb3.png" border="0" alt="image" width="244" height="89" /></p>
<p>This article will show how to implement such progress dialogs in WPF with C#. All of the above dialogs can be used with one implementation. The solution will also show how to hide the close button of a window, which is officially not supported by WPF.</p>
<p>The code snippet below shows how to use and display such a progress dialog:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:2909b695-2e79-4c59-8052-8c72484504b9" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">ProgressDialogResult result = ProgressDialog.Execute(this, "Loading data...", () =&gt; {

  // TODO: Do your work here!

});

if(result.OperationFailed)
  MessageBox.Show("ProgressDialog failed.");
else
  MessageBox.Show("ProgressDialog successfully executed.");</pre>
</div>
<p>The ProcessDialog class provides a number of static Execute methods (overrides) to easily setup a long-running task with a dialog window. The first parameter always defines the parent window in order to center the process dialog relative to the parent window. The second parameter is the text message displayed in all dialogs. The third parameter is the asynchronous method itself.</p>
<p>The fourth parameter allows to pass additional settings. Those dialog settings, represented by an instance of the ProcessDialogSettings class, define if the dialog shows a sub label, has a Cancel button or displays the progress bar itself in percentage or indeterminate. Predefined settings are also defined as static properties.</p>
<p>Using lambda expressions in C#, it is very comfortable to start a long-running task and displaying the dialog. You can also communicate with the progress dialog to report messages to the user by calling the Report method of the ProgressDialog class:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f45de43c-d914-4339-aa3d-84eccb1dc59a" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">ProgressDialogResult result = ProgressDialog.Execute(this, "Loading data...", (bw) =&gt; {

  ProgressDialog.Report(bw, "Connecting to the server...");

  // TODO: Connect to the server

  ProgressDialog.Report(bw, "Reading metadata...");

  // TODO: Reading metadata

}, ProgressDialogSettings.WithSubLabel);</pre>
</div>
<p>The two samples above did not show a Cancel button. The next code shows a progress dialog with a Cancel button including code to check if the long-running code must be cancelled:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:0c414dd1-3358-4146-b32c-42da673448c3" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">int millisecondsTimeout = 1500;

ProgressDialogResult result = ProgressDialog.Execute(this, "Loading data", (bw, we) =&gt; {

  for(int i = 1; i &lt;= 5; i++)
  {
    if(ProgressDialog.ReportWithCancellationCheck(bw, we, "Executing step {0}/5...", i))
      return;

    Thread.Sleep(millisecondsTimeout);
  }

  // So this check in order to avoid default processing after the Cancel button has been
  // pressed. This call will set the Cancelled flag on the result structure.
  ProgressDialog.CheckForPendingCancellation(bw, we);

}, ProgressDialogSettings.WithSubLabelAndCancel);

if(result.Cancelled)
  MessageBox.Show("ProgressDialog cancelled.");
else if(result.OperationFailed)
  MessageBox.Show("ProgressDialog failed.");
else
  MessageBox.Show("ProgressDialog successfully executed.");</pre>
</div>
<p>Calling the ReportWithCancellationCheck method will check for a pending cancellation request (from the UI) and will may set the Cancel property of the DoWorkEventArgs class passed from the underlying BackgroundWorker object to True. Otherwise the method will display the message and continue processing.</p>
<p>The Exceute method of the ProgressDialog class will return an instance of the ProgressDialogResult class that returns the status of the execution. Thrown exceptions in the task method will be stored in the Error property if the OperationFailed property is set to True. For more samples see the Visual Studio 2010 solution you can download from my homepage.</p>
<p>The ProgressDialog window contains the main application logic. The above described static Execute methods will internally call the ExecuteInternal method to create an instance of the ProgressDialog window passing and setting all necessary values. Then the Execute method with the asynchronous method as parameter is called:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:4835e7c9-2ba7-4b62-9e26-a3a95bc9013e" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal static ProgressDialogResult ExecuteInternal(Window owner, string label,
  object operation, ProgressDialogSettings settings)
{
  ProgressDialog dialog = new ProgressDialog(settings);
  dialog.Owner = owner;

  if(!string.IsNullOrEmpty(label))
    dialog.Label = label;

  return dialog.Execute(operation);
}</pre>
</div>
<p>The operation method can be a delegate of the following type:</p>
<p>· Action</p>
<p>· Action&lt;BackgroundWorker&gt;</p>
<p>· Action&lt;BackgroundWorker, DoWorkEventArgs&gt;</p>
<p>· Func&lt;object&gt;</p>
<p>· Func&lt;BackgroundWorker, object&gt;</p>
<p>· Func&lt;BackgroundWorker, DoWorkEventArgs, object&gt;</p>
<p>The Func types can return a value that will be used to set the Result property of the ProgressDialogResult class.</p>
<p>The Excute method is implemented as follows:</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:bb5b828f-441f-4038-95b4-d550f4b647f6" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: c#;">internal ProgressDialogResult Execute(object operation)
{
  if(operation == null)
    throw new ArgumentNullException("operation");

  ProgressDialogResult result = null;

  _isBusy = true;

  _worker = new BackgroundWorker();
  _worker.WorkerReportsProgress = true;
  _worker.WorkerSupportsCancellation = true;

  _worker.DoWork +=
    (s, e) =&gt; {
      if(operation is Action)
        ((Action)operation)();
      else if(operation is Action&lt;BackgroundWorker&gt;)
        ((Action&lt;BackgroundWorker&gt;)operation)(s as BackgroundWorker);
      else if(operation is Action&lt;BackgroundWorker, DoWorkEventArgs&gt;)
        ((Action&lt;BackgroundWorker, DoWorkEventArgs&gt;)operation)(s as BackgroundWorker, e);
      else if(operation is Func&lt;object&gt;)
        e.Result = ((Func&lt;object&gt;)operation)();
      else if(operation is Func&lt;BackgroundWorker, object&gt;)
        e.Result = ((Func&lt;BackgroundWorker, object&gt;)operation)(s as BackgroundWorker);
      else if(operation is Func&lt;BackgroundWorker, DoWorkEventArgs, object&gt;)
        e.Result = ((Func&lt;BackgroundWorker, DoWorkEventArgs, object&gt;)operation)(s as BackgroundWorker, e);
      else
        throw new InvalidOperationException("Operation type is not supoorted");
    };

  _worker.RunWorkerCompleted +=
    (s, e) =&gt; {
      result = new ProgressDialogResult(e);
      Dispatcher.BeginInvoke(DispatcherPriority.Send, (SendOrPostCallback)delegate {
        _isBusy = false;
        Close();
      }, null);
    };

  _worker.ProgressChanged +=
    (s, e) =&gt; {
      if(!_worker.CancellationPending)
      {
        SubLabel = (e.UserState as string) ?? string.Empty;
        ProgressBar.Value = e.ProgressPercentage;
      }
    };

  _worker.RunWorkerAsync();

  ShowDialog();

  return result;
}</pre>
</div>
<p>The ProgressDialog class is using internally a BackgroundWorker object to handle the asynchronous execution of the task or operation method.</p>
<p>For more details of the implementation see the source code.</p>
<p><a href="http://content.parago.de/samples/ProgressDialog.zip">Download Source Code</a></p>
<p><a href="http://content.parago.de/articles/ProgressDialog/HowToImplementAModernProgressDialogForWPFApplications.pdf">Download Article (PDF)</a></p>
<p><strong>UPDATE:</strong></p>
<p>I wrote a second edition of the progress dialog which is using a ProgressDialogContext class to access BackgroundWorker and the DoWorkEventArgs. Also, all Report methods moved to the context class. So, you can basically use the static ProgressDialog.Current property within the asynchronous method and its sub methods to report to the progress dialog. This usefully if you call a chain of methods in which you have to report messages to the dialog and may need to cancel the process.</p>
<p><a href="http://content.parago.de/samples/ProgressDialogEx.zip">Download Source Code with ProgresDialogContext class</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.parago.de/2011/04/how-to-implement-a-modern-progress-dialog-for-wpf-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

