Wednesday, November 28, 2012

BizTalk BAM Portal View Message Error

In the Bam portal, when tried to click "related documents -> MessageBody", which access the url,

http://localhost/bam/bammanagementservice/bammanagementservice.asmx/GetReferences?viewName=&referenceType=MsgBody...

Then I got the following error message,
Request format is unrecognized for URL unexpectedly ending in '/GetReferences'

 

 
This issue is because the web.config is not fully configured.
 
Fix:
 
In the web.config of the BamManagement web servcie, which is in C:\Program Files (x86)\Microsoft BizTalk Server 2010\BAMPortal\BAMManagementService
 
Add the following configuration,
 
<configuration>
    <system.web>
    <webServices>
        <protocols>
            <add name="HttpGet"/>
            <add name="HttpPost"/>
        </protocols>
    </webServices>
    </system.web>
</configuration>
 
Then it worked.

SharePoint 2013 layout folder path

Just realized that SharePoint 2013 now has two folders for _layout virtual directory.
 _layout --> layout/14
_layout/15 --> layout/15

Tuesday, November 27, 2012

BizTalk Mapping - Use XSLT template to split a csv field to repease fields

Recently in a data integration scenario, I need to map a CSV field values into a repeating field.

The source schema field will be look like this,
<TestData>
     123, A, 23, B, 45, FF, 67, SD, 78, DE,,,
</TestData>
The value of the data is a variable length, also it maybe have some blank values or not.

The destination schema data should be mapped like this,
<Results>
    <Result id="123">A<Result>
    <Result id="23">B</Result>
    <Result id="45">FF</Result>
    <Result id="67">SD</Result>
    ...
</Results>

Because the incoming test data is a variable length csv value, we can not use a table looping and extractor to direct mapping to the destination

The solution I come up is to use a XSLT template with a recursive call.

The solution has a single link to destination Results element to decide if need to create the whole element.

Then the template is linked to the Result element to create each element by keep calling XSLT substring-before(), substring-after() to reduce the string and generate the result.

Also xslt contains() is used to check if the element is the last value. or else substring-before() will return empty string.

Here is the sample codes, we need to run substring-after twice for each round, becasue this scenario is a key-value pair.
 
 <xsl:template name="TokenizeCommaSepString">
    <xsl:param name="stringToTokenize" />
 
    <xsl:if test="$stringToTokenize != ''">

        <xsl:variable name="var:v98" select="substring-before($stringToTokenize, ',')" />
        <xsl:variable name="var:v99" select="substring-after($stringToTokenize,',')" />
       
        <xsl:choose>
            <xsl:when test="contains($var:v99, ',') = 0">              
                <xsl:if test=" $var:v98!='' or $var:v99!='' ">
                    <xsl:element name="Result">
                        <xsl:attribute name="Id">
                            <xsl:value-of select="$var:v99" />
                        </xsl:attribute>
                        <xsl:element name="Value">
                            <xsl:value-of select="$var:v98" />
                        </xsl:element>
                    </xsl:element>
                </xsl:if>
            </xsl:when>
         
            <xsl:otherwise>
                <xsl:variable name="var:v99.2" select = "substring-before($var:v99, ',')" />
                <xsl:if test=" $var:v98!='' or $var:v99.2!='' ">
                    <xsl:element name="Result">
                        <xsl:attribute name="Id">
                            <xsl:value-of select="$var:v99.2" />
                        </xsl:attribute>
                        <xsl:element name="Value">
                            <xsl:value-of select="$var:v98" />
                        </xsl:element>
                    </xsl:element>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>

        <xsl:call-template name="TokenizeCommaSepString">
            <xsl:with-param name="stringToTokenize" select="substring-after(substring-after($stringToTokenize,','), ',')" />
        </xsl:call-template>
  </xsl:if>

</xsl:template>


Saturday, November 24, 2012

SharePoint customization content types reference links

During customization in SharePoint solution development, it is always be nice to have a reference in hand to know all the field types and re

SharePoint 2010 field types reference
http://koenvosters.wordpress.com/2010/04/27/available-field-types-in-sharepoint-2010/

Tuesday, November 20, 2012

SharePoint 2013 Apps is an opportunity

Now SharePoint 2013 is out. Since the beta version with the new Apps programming model, I have talked to many developers. Like what I first see this, most of them are disappointed. Apps is not something the SharePoint developers really want, it moves to another direction rather than giving us something better and easier for SharePoint server solutions development.

My opionion about this actually has been changed. I think SharePoint team is on the right track and we need to embrace this model. Since SharePoint 2007, all the versions were built on top of asp.net. And in these years, web development has been changed so much because of the the power of javascript library. In MVC4, you have all the good javascript library included in the box to do amazing things that give very good user experience.

Since SharePoint 2013 has a good revamp in their client javascript library, developers finally can do things like the modern web apps can do. So now SharePoint developers have the tools in hand and can work with them in SharePoint 2013. I believe it is time to leave your comfortable zone and start to write your own mordern web apps within SharePoint.

Monday, November 19, 2012

SharePoint 2013 - View data through REST from browser

Now many information can be loaded from browser through REST. This is a quick links list to show what you can expose,

First, In IE, needs to go to Internet Options -> Content tab -> feeds and web slices -> settings
uncheck "turn on feed reading view"

http://spsite/_api/web - list all SharePoint related information
http://spsite/_api/web/lists - all the SharePoint site lists
http://spsite/_api/web/lists/getbytitle('listname') - specific list information
http://spsite/_api/web/lists/getbytitle('listname')/items - show the list data
http://spsite/_api/web/lists/getbytitle('listname')/items(int) - show the list data by id
http://spsite/_api/web/lists/getbytitle('listname')/items(int)?$select=Title,Field1,Field2 - only select the list fields
http://spsite/_api/web/lists/getbytitle('listname')/items?$filter=Title eq 'title'  fitler the data

The reference can be found out in http://www.odata.org -> document -> URL Convention

Here has a very good tutorial about how to do write operation in REST, and how to consume it in JSON data.

SharePoint 2013 - Create JS templates view

SharePoint 2013 has a new feature that you can write custom js codes to render a view rather than xslt view.

Here are the quick steps,

1. Create the custom list and their columns
    In SharePoint 2013, there is list designer that is much easier to create the list content type and columns,
 
2. Create a new view and include the fields you will reference in the java script, those fields can be called by context.CurrentItem.FieldName

3. Add the JSLink to the javascript file, such as
<JSLink Default="TRUE">~site/Scripts/<your custom javascript file>.js</JSLink>

4. Create a new Scripts module and write a custom java script to deploy them, Here is a quick example,


(function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    overrideCtx.BaseViewID = 2; // the custom view ID
    overrideCtx.ListTemplateType = 10001; //the template type

    overrideCtx.Templates.Header = "<B><#=ctx.ListTitle#></B><hr><ul>";
    overrideCtx.Templates.Footer = "</ul>";
    overrideCtx.Templates.Item = CustomItem;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

function CustomItem(context) {
    var ret = "<li>This is a " + context.CurrentItem.Title+ " - " + context.CurrentItem.ISBN + "</li>";
    return ret;
}