As the Dust Settles

As the Dust Settles on Tech.Ed I find myself frantically preparing sessions for Web On The Piste.


It was great catching up with Natasha (of Trade Me and Webstock fame) at Tech.Ed last week but like Natasha after doing this for a few years now I’m starting to realise that when it is event season your job is never done!


I had a few questions about the Silverlight video we pushed onto the http://techedlive.co.nz site during the conference. Yes all the videos are hosted on Silverlight Streaming using the free account so yes you can do the same thing on your sites!


This year I had been given the job as official video guy and after the hours spent capturing, editing and uploading to silverlight streaming I’m never going to put my hand up to do that job again. It took me out of the conference for much more time than I was happy with. The most frustrating part of all of this was dealing with the Mac centric firm that had been sub contracted to capture the keynote video. They came back to us no less that 5 times during the two days after the keynote with completely unusable formats (I can work with MOV, MPEG, AVI etc but not with what they produced!). In the end they came into Tech.Ed with a version of the latest quicktime installer from apple to prove that their MOV file did play on Windows. When it failed to work they tried to blame Vista only to find that it also didn’t work on Windows XP. Note to others wanting to do business with Microsoft in the future BUY A PC and test it or at least run boot camp on your Mac!


On the plus side although I didn’t present myself at Tech.Ed on Thursday I presented 3 sessions at Tech.Ed Student day in sky city theatre to 600+ students. I loved the sessions and presenting along side the famous Steve Riley I think they were well received.


I have received a few questions about how we created the keynote Picture in Picture player that streams the two keynote feeds simultaneously. I realised after watching the video on this player that there are a few sync issues if the streams need to buffer so it appears that there is still a bit of work required to address the sync’ing issues.


I grabbed the base code for this from Michael Scherotter opened it in the August preview of Blend 2 and pimped it a little for the event (my source code here).


The interesting thing about this piece is that it combines two Windows Media Streams that are hosted on the Microsoft site.


mms://wm.microsoft.com/ms/nz/teched07/keynote_deck.wmv
mms://wm.microsoft.com/ms/nz/teched07/keynote_speaker.wmv

Because these streams are external resources you can “repackage” them using other player designs. Here is another Silverlight player skin that I uploaded to Silverlight Streaming that points to the keynote_speaker.wmv stream and contains chapters to different parts of the keynote presentation.

To embed this video I have put the following HTML below

<iFrame src=”http://silverlight.services.live.com/invoke/33/teKeynote/iframe.html” mce_src=”http://silverlight.services.live.com/invoke/33/teKeynote/iframe.html” frameborder=”0″ width=”432″ height=”324″ scrolling=”no”></iFrame>


Click here to view!


The one surprise for me over the event was the quality of the Canon HV20 consumer camcorder, check out this video from TechFest that I shot and uploaded to Silverlight Streaming, the codex going from true HD to streaming produced a video that is smaller than 10MB and the quality IMO is still fantastic!

Using WCF WebHttpBinding and WebGet with nicer Urls

Using WCF WebHttpBinding and WebGet with nicer Urls

I’ve been playing with the REST support
in .NET 3.5.  I’m really enjoying the programming model, but I am not enjoying
the .svc file extension in my URLs (I’m not the only
person
I know who has felt this way for quite some time).

IMO (from what little I know about the REST style) URLs shouldn’t have things like
extensions in them (or preferably not).  So with they way WCF endpoint hosting
in IIS works (obviously if I am hosting a webHttpBinding in a non-IIS host I can totally
control the URLs, but I am writing a REST API to something where I plan to be hosting
inside of IIS).  This would end up being my url:

http://host/albumn.svc/instance/

and I want:

http://host/albumn/instance/

The .svc extension in the URL doesn’t seem opaque to me.  I tried modifying the
HttpHandler element for the svc file – but that didn’t work for various reasons. 
So I ended up writing a simple HttpModule to do URL re-writing (using HttpContext.RewritePath). 
I didn’t really want any config relating to URLs – so this module assumes you
are serving up only REST based URLs from a web application.  If you were going
to use it and serve up other handlers (like aspx files etc) it would need to
be modified. Here is the module code:

public class RestModule
: IHttpModule
{

public void Dispose()
{ }

public void Init(HttpApplication
app)
{
app.BeginRequest += delegate

{
HttpContext ctx = HttpContext.Current;
string path = ctx.Request.AppRelativeCurrentExecutionFilePath;

int i = path.IndexOf(‘/‘,
2);
if(i>0)
{
string svc = path.Substring(0,
i) + “.svc”;
string rest = path.Substring(i,
path.Length i);
ctx.RewritePath(svc, rest, ctx.Request.QueryString.ToString(), false);
}
};

}

}

After configuring this in my web.config – I have the ability to type:

http://localhost/RestTest/Service2/Test?id=9999

and the module will translate it to Service2.svc as the handler file – which makes
WCF happy.

If you are interested you can download the code here:

RestTest.zip
(3.71 KB)


Check out my BizTalk
R2 Training.

My blog, the reasons, the results

I recently received an email from an anonymous blog reader asking why the recent posts about the minor discrepancies in the BizTalk product and how it would help them with resolving issues.

This isa perfect intro into the reason why I maintain a few blogs.

  1. These are my personal blogs, I don’t get any $ from MS for providing this information (however my wife thinks I should), so it is a lot of my rants.
  2. A reminder of the mistakes I have made, as before I had this blog, I would make the same mistakes over and over, and I finally realized that I needed to keep a record of all of my mistakes and how I fixed them so I wouldn’t need to re invent the wheel (so now you know that I am very proficient at making mistakes (the cat is out of the bag)!)
  3. Hopefully assist others from having to be as frustrated with the things that I have come across.
  4. Have a venue to present to a larger audience things I think could be improved so that the MS products in the dot releases or major releases are better, making my life easier (which is what I am all about (laziness)). By having a larger audience, MS listens to the masses a lot more than they do a single guy screaming of its deficiencies.

Since there are some of you that actually care about what I blog about, THANK YOU.

Could I ask a favor of you all who are my blog readers?

Could you tell me what you would like me to blog about, be it BizTalk issues, rants about the product, what you spend your time on, how you think the product (I don’t care which product) could be better, or the documentation better, or even my blog style.

I want thank Eric Battalio for suggesting that for my entries should be a little more ‘buildup’ to the answer, explaining how someone could get into situations where I provide the answer on how to resolve it. I am trying to give a little more background on the issues, instead of just the answer with no context.

Hope to hear from you

Channel 9 video on WCF Line of Business Adapter SDK

 


As promised, we have a new Channel 9 video with Sonu Arora, Senior Program Manager, and C. Venkatesh Principal Group Manager on the WCF Line of Business Adapter SDK.  Sonu and CV cover the SDK architecture & feature set along with interesting demos.   I’d highly recommend watching this video specially if you’ve questions around use of this SDK versus the WCF channel model and the older BizTalk adapter framework. want to find out what LOB adapters versus pure transport adapters are & how they differ from services.  


 


Make sure to send us your feedback via Channel 9.  For questions and community support, visit our forums.


 


Enjoy, it’s a fun video to watch. 


Marjan Kalantar

SOAP Adapter and BizTalk Web Publishing Wizard – things you need to know.

Exposing an Orchestration as Web Service:

This is the safest option you can choose, when you want to expose your business process as an industry standard web service, which can later be consumed by a client (consumer) either using a web service proxy or HTTP post of correctly formatted SOAP message.

There is a very good article in MSDN http://msdn2.microsoft.com/en-US/library/ms935219.aspx explaining how you can expose your orchestration as web service.

Let’s assume you have exposed your orchestration as web service, bound the inbound logical port to the auto-generated SOAP receive port (created by the wizard) and enlisted-started the Orchestration. Now, when you look at the activation subscription details for the Orchestration it will look something similar to the one shown below:

SNIPPET #1

http://schemas.microsoft.com/BizTalk/2003/system-properties.ReceivePortID == {73684F88-8D5C-4659-9E8F-F1B5E6E9A780} And

http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == http://www.digitaldeposit.net/samples/schema/1.0#personRequest And

http://schemas.microsoft.com/BizTalk/2003/system-properties.InboundTransportType != SOAP

Or

http://schemas.microsoft.com/BizTalk/2003/system-properties.ReceivePortID == {73684F88-8D5C-4659-9E8F-F1B5E6E9A780} And

http://schemas.microsoft.com/BizTalk/2003/soap-properties.MethodName == GetPersonDetail

When you are receiving the messages via the auto-generated SOAP receive port the properties MethodName and ReceivePortID will get promoted by the SOAP adapter and the orchestration will get the message due to second subscription condition. (MethodName will equate to the Operation name you defined inside the logical port within your Orchestration)

If you inspect the first condition carefully, you’ll see “if MessageType property is present then the receive adapter should NOT be SOAP”. Also, the auto-generated SOAP ReceiveLocation uses PassThru pipeline, which results in MessageType property not being promoted.

This design introduces two potential problems

 (LISTING #1)

    1. Configuring MAP(S) on the auto-generated SOAP receive port will be ignored.
    2. Properties (distinguished and promoted) defined in the schema wont get into the context.

Maps will be ignored on the auto-generated SOAP Receive Port:

Usage of PassThru pipeline inside the auto-generated SOAP ReceiveLocation is bit contrary when you are using Orchestrations and dealing with XML messages. Majority of the time Orchestration subscriptions will be based on MessageType you specified on the Activation receive shape and you’ll be using XmlReceive pipeline on your ReceiveLocation, so that MessageType and other property promotions (both distinguished and promoted properties defined in the schema) gets into the context. Since the MessageType property is NOT promoted anywhere in the ReceivePort (mainly due to the usage of PassThru pipeline), any MAP you configure on the ReceivePort will be ignored.

Due to the configuration of PassThru pipeline by default, any properties (both distinguished and promoted) defined in your schema won’t get into to the context, which creates potential problem if you want to use content based routing.

We can fix these problems easily, by modifying the auto-generated SOAP ReceiveLocation to use XmlReceive pipeline instead of PassThru. As I mentioned in the beginning “Exposing orchestration as web-service” is the safest option, it doesn’t introduce too much head aches. The problem really starts when you just want to expose your schemas as web services as explained in next topic.

Exposing schemas as web services:

The MSDN article http://msdn2.microsoft.com/en-US/library/ms935219.aspx got clear explanation of exposing schemas as web services.

After exposing your schemas as web-services using “BizTalk Web Publishing” wizard, you can create an Orchestration to consume the messages published by the auto-generated SOAP ReceivePort. The important thing to note here is the name of the “Operation” you define inside the logical port, make sure it matches the WebMethod name you have specified while generating the web-service. As shown in the below figure:

When you bind the logical orchestration port to physical auto-generated SOAP ReceivePort and start (enlist) the orchestration, the subscription for the orchestration will look identical to the one shown in SNIPPET #1 (earlier).

We’ll hit the same problems (explained in detail earlier) outlined under “Exposing an Orchestration as web service”

  1. Map won’t get applied
  2. Properties (distinguished and promoted) won’t get into context

Due to the fact, the auto-generated SOAP ReceiveLocation uses PassThru pipeline by default.

If you modify the auto-generated SOAP ReceiveLocation to use XmlReceive pipeline instead of PassThru (hoping its going to fix all the problems, as we did with “Exposing an Orchestration as web service”) the run-time will generate the following exception when it receives the message:

There was a failure executing the receive pipeline: “Microsoft.BizTalk.DefaultPipelines.XMLReceive, Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35” Source: “XML disassembler” Receive Port: “WebPort_SK.ws.viaSchemas.1_0/WebService1” URI: “/SK.ws.viaSchemas.1_0/WebService1.asmx” Reason: The type SK.Schemas.Person_1_0 is not a valid part type for a message. This invalid type may be from a property schema.

The exception is mainly raised because SOAP adapter puts the wrong DocumentSpecName property in the message context and hands over the message to the pipeline. PassThru pipeline (DEFAULT Configuration on auto-generated SOAP ReceiveLocation) doesn’t do any processing, so whatever value present in the property DocumentSpecName is ignored. On the other hand if you configure XmlReceive pipeline which uses XmlDisassembler, it will utilizes the “DocumentSpecName” property to resolve the schema.

Behavior of XmlDissambler inside the XmlReceive pipeline:

Having the DocumentSpecName property in the context, will force XmlDissambler pipeline component to use it, to locate your schema. If DocumentSpecName is NOT present then XmlDissambler pipeline component will go through dynamic schema resolution mechanisms to get the correct schema. Since DocumentSpecName is present with wrong value, XmlDissambler throws the exception and it clearly states “This invalid type may be from a property schema”.

There are few ways you can get away from this problem

Solution #1: Use PassThru pipeline and Orchestration (DEFAULT config):

If you don’t have any inbound maps to be applied on the port level and you are not dependant on promoted properties (distinguished and promoted) defined in the schema outside the orchestration, then you can use PassThru pipeline (configured by default by auto-generated SOAP receive location). The Orchestration gets the message by other subscription conditions (ex: MethodName) without the need for MessageType.

  1. You can get away from the MAP problem by applying it inside your orchestration, and
  2. You automatically get away from property promotion problem. Because when the orchestration receives a message the IBaseMessage (from adapter/pipeline) is converted into a XLANG message, which results in the process of new message construction (since messages are immutable in BizTalk server). During this step all the distinguished and promoted properties gets into the context. [This is my own prediction of how distinguished fields and promoted properties gets into the context automatically within Orchestration even though we used PassThru pipeline, I couldn’t find clear documentation explaining it] and available within the Orchestration.

Solution #2: Modify the generated .asmx.cs code. Passing null instead of bodyTypeAssemblyQualifiedName:

By passing the value “null” instead of bodyTypeAssemblyQualifiedName both the problems defined in Listing #1 can be solved

//Original Code

string bodyTypeAssemblyQualifiedName = “SK.Schemas.Person_2_0, SK.Schemas, Version=1.0.0.0, Culture=neutral, PublicKeyTok” +

“en=c2b0cafd9314ef3e”;

// BizTalk invocation

object[] invokeResults = this.Invoke(“GetPersonDetail”, invokeParams, inParamInfos, outParamInfos, 0, bodyTypeAssemblyQualifiedName, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, false, false);

//Modified Code

// BizTalk invocation

object[] invokeResults = this.Invoke(“GetPersonDetail”, invokeParams, inParamInfos, outParamInfos, 0, null, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, false, false);

If the value null is passed instead of bodyTypeAssemblyQualifiedName, SOAP adapter won’t add the DocumentSpecName property to the context. Now, when we configure our auto-generated SOAP ReceiveLocation to use XmlReceive pipeline, the XmlDisassembler component inside XmlReceive will go through the process of automatic dynamic schema resolution mechanism, pick up the correct schema and promotes all the required properties (distinguished and promoted) defined in the schema and it also promotes the MessageType property.

Solution #3: Modify the generated .asmx.cs code. Change bodyTypeAssemblyQualifiedName property to include the schema root node.

We are going to follow a similar approach here, but instead of passing null”for bodyTypeAssemblyQualifiedName, we are actually going to pass the correct value.

//Original Code

string bodyTypeAssemblyQualifiedName = “SK.Schemas.Person_2_0, SK.Schemas, Version=1.0.0.0, Culture=neutral, PublicKeyTok” +

“en=c2b0cafd9314ef3e”;

//Modified Code

string bodyTypeAssemblyQualifiedName = “SK.Schemas.Person_2_0+personRequest, SK.Schemas, Version=1.0.0.0, Culture=neutral, PublicKeyTok” +

“en=c2b0cafd9314ef3e”;

The only difference is we are appending the schema root element name to the schema Type Name. You can see the correct DocumentSpecName name by

  1. Add a Receive Pipeline to your project (or to a dummy project),
  2. Drag-Drop a XmlDisassembler component
  3. Select XmlDisassembler and in the properties window, click on button next to the “Document Schemas” property. You’ll see “Schema collection property editor” window as shown in the below figure, which clearly shows the expected “DocumentSpecName” name.

When you expose your Orchestration as web service the auto generated code will look similar to our modified code.

NOTE: You need to be careful with Solution #2 and #3, because regenerating the web-service code will result in losing the manual changes you performed.

You can download the ZIP file containing all the sample projects I used for this research.

Nandri!

Saravana