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;
}




Saturday, November 17, 2012

MVC4 Web API Starter needs to know

I have just tried to use the MVC 4 Web API. There are some findings that needs to know during the process,

1. Use cUrl command line tool to test out the rest end points

2. Modify the IIS or IIS Express settings to enable verb PUT, DELETE
This is a link to show how to do this.

3. If need to use web API provided HttpClient class
In package manager console, run:
    Install-Package Microsoft.AspNet.WebApi.Client projectname
to install the necessary libraries


4. This will be a quick example to return the result.

By Calling add MediaTypeWithQualityHeaderValue("application/xml"), a xml format data will be returned. By default, web api return Json format data.

use new System.Net.Http.HttpClient() to send Form data
To use xml format data, need to add the MediaTypeHeader
clt.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
To get the result
 var result = clt.GetAsync(new Uri("http://localhost:52094/api/videos")).Result
 
For post complex type data, Call PostAsJsonAsync() such as
clt.PostAsJsonAsync("http://localhost:52094/api/videos/222", customer).Result
 

5. There are some old examples to use HttpRequestMessage and its extension method CreateContent, which are deprecated. it is much easier now.

6. In debug->immediate window, enter GlobalConfiguration object to check the current formatters.
GlobalConfiguration.Configuration.Formatters

Count = 4

[0]: {System.Net.Http.Formatting.JsonMediaTypeFormatter}

[1]: {System.Net.Http.Formatting.XmlMediaTypeFormatter}

[2]: {System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter}

[3]: {System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter}
 
 


 

Thursday, November 15, 2012

Azure Blob Upload - SocketException

Today when I deployed my MVC 4 application to azure, when I tried to access the blob, I got the following error,

An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:10000

[SocketException (0x271d): An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:10000]
   System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) +6462061
   System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception) +271

[WebException: Unable to connect to the remote server]
   Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.get_Result() +77
   Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.ExecuteAndWait() +171
   Microsoft.WindowsAzure.StorageClient.TaskImplHelper.ExecuteImplWithRetry(Func`2 impl, RetryPolicy policy) +29
   Microsoft.WindowsAzure.StorageClient.CloudBlobContainer.CreateIfNotExist(BlobRequestOptions options) +93
   AzurePictures.Models.ImageRepository.SaveImage(String name, Byte[] buffer) +109
   AzurePictures.Controllers.HomeController.Upload() +316


The issue is when I deployed the application, I am still setting it to useDevelopmentStorage = true,
Just reset the web config to use the Azure one, then it worked.

Monday, November 12, 2012

BizTalk 2010 - Create a dynamic flat file disassembler to set the document schema

In this scenario, there are quite a few different flat files in different flat file schema types, they all need to map into a common format schema to be processed in BizTalk.

It is will be too much to create pipeline for each trading party, so I wrote a custom flat file disassember which inherit from the Microsoft one to set the document schema in the disassemble stage.

There is an existing msdn example to show how to create a custom disassember which inheritted from the Flat file disassembler, Extending the Flat File Disassembler Pipeline Component.

In my scenario, I only need to have some custom code in the Disassemble() method.

1. Understand the received file name,
  IBaseMessageContext context = pInMsg.Context;

  object obj = context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties");
In this blog, you can find all the common used properties as reference.

2. Set the DocumentSpecName of the pipeline

DocumentSpecName is a type of SchemaWithNone, which need to add reference to Microsoft.BizTalk.Component.Utilities from GAC.

this property can be created by this.DocumentSpecName = new SchemaWithName("schematype, assemblyname, ..."); 

3. Then just call base.Disasseble(pContext, pInMsg)
4. To inherit from Flat file disassember (FFDasmComp class), need to add reference to Microsoft.BizTalk.Pipeline.Components from GAC. For the Pipeline components interface such as IBaseComponent, IDisassemblerComponent,need to add reference to Microsoft.BizTalk.Pipeline 

When add this custom component into the pipeline, the Flat File Disassembler needs the Document schema to be set up. Although you can override the IComponent.Validate() method to pass the validation, however, it will cause error "value can not be null" in the pipeline processing.

Also the flat file disassembler needs to set the "Recoverable Interchange processing" property to true, or else, there is a "datareader disposed" error sometimes.  

Create asp.net MVC 4 supported membership database

In traditional asp.net, you can run aspnet_regsql to create the membership database.

In this one I will explain how to create mvc 4 membership database.

1. In web.config, add the default (localdb) connection

    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=dbname;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\dbname.mdf" />

2. Install the necessary packages reference in NuGet
Install-Package DotNetOpenAuth
Install-Package DotNetOpenAuth.aspnet
Install-Package Microsoft.AspNet.WebPages.OAuth
Install-Package WebGrease
Install-Package WebMatrix.Data
Install-Package WebMatrix.WebData
Add reference to system.web.helpers from nuget packages, make sure copy to local is true

3. Include the codes from an internet application sample
\Models\AccountModels.cs
\Filters\InitializeSimpleMembershipAttribute.cs
\Controller\AccountController.cs
\Views\Shared\_LoginPartial.cshtml
\Views\Account\* (update the namespace)

4. Also in web.config, remove the default membership provider and role provider section.

5. To use OAuth with Facebook, Google, Twitter etc,
Need to include the file \App_Start\AuthConfig.cs to uncomment the provider code with their appid and app seceret.
Also modify the global.asax.cs to add the line of the code,
AuthConfig.RegisterAuth();

Thursday, November 8, 2012

BizTalk pipeline can not access a disposed object error

I got this error related to Flat file disassembler in the eventlog,

There was a failure executing the receive pipeline: "XXX.Pipelines.ReceivePipeline1, XXX.Pipelines, Version=1.0.0.0, Culture=neutral, PublicKeyToken=28bb1f44fbba3ea7" Source: "Flat file disassembler" Receive Port: "Commodities_Recv_Port" URI: "D:\XXX\Tests\XXX_OUT_In\*.*" Reason: Cannot access a disposed object.
Object name: 'DataReader'.

Fix:

In the flat file disassembler componet in the pipeline design, set the property
"Recoverable interchange processing" to true


 

Wednesday, November 7, 2012

Another scenario for this issue that in biztalk administration console, schema referenced by map has been deleted

This issue seems to happen only in BizTalk 2010, maybe onwards.

A few days ago, I had this issue and I blogged the fix here.

Today it has a different scenario.

As the previous blog said, as long as I removed the masp reference in the BizTalkMgmtDb, the warnning message will not show.

However, as long as I deployed the maps project, this issue shows up again in the administration console. And there are no any maps shown in the application even the maps assembly was added in the resource.

This one seems to do with the maps project and schemas project are in seperated solution, also the map project has reference to schemas from GAC. In the end I have to delete the application and redeploy each project (schemas, then maps) one by one and it worked.

Tuesday, November 6, 2012

BizTalk 2013 Beta released and the stuff I am interested

BizTalk 2013 beta is released and you can download it here

In this release, there are some new features I think that worth while to try,

1. Azure service bus support

2. REST service support

3. ESB toolkit is fully integrated and the configuration is much simplified.

4. Dependency tracking - dependencies between artifacts can be viewed in admin console.

The BizTalk 2013 is still based on the previous architecture but it is upgraded to work nicely with all the latest development environment such as visual studio 2012 and SQL server 2012. That is very good thing.

Thursday, November 1, 2012

A link to set up SAP adapter in BizTalk 2010

Just found the link here that explained how to set up SAP adapter in BizTalk 2010

Get the WCF current directory

A wcf service is running and hosted by IIS. I have the requirment to get the current folder of the serivce.  And it will return NULL if use HttpContext.Current.Server.MapPath since wcf context is diffrent from the default asp.net context.

what we can do is using,
System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;