Thursday, August 18, 2011

WCF REST - Two things made me wondering 2 or 3 days (stream.Position = 0 and WebMessageBodyStyle.Bare

Recently I developed one WCF REST service which has to be consumed in Silverlight 4.0. Since it is a WCF REST service, we will be dealing with JSON or XML format. But my customer wanted the support for object/contract as well [Don't ask me why not use simple WCF :) ]. So I did implement Datacontract Serialization. I was facing these 2 issues and looking throught web for answers. Finally after 2 days, the solution just struck in my mind.

Issue 1:
Root element is missing

I had the following code for deserialization.

XDocument doc = XDocument.Load(result);
MemoryStream str = new MemoryStream();
doc.Save(str);

DataContractSerializer serializer = new DataContractSerializer(typeof(EntityTypesCollection));
EntityTypesCollection typeColls = (EntityTypesCollection)serializer.ReadObject(str); //I was receiving the error "Root element is missing" here

I kept checking, what am I doing wrong... Finally after some brain crunches, finally figured out that we need to position the stream to 0.
str.Position = 0;

Voila, Issue 1 solved. Now the second issue.

Issue 2:
Response XML was wrapped like this;
<operation_response><operation_result>[Actual Result]</operation_result></operation_response>

I found a lot of complicated approaches to the simple 2 lines of deserialization code. Like filtering out the XElements from the response and through LINQ building back the contract.

Suddenly I noticed that, I mentioned the BodyStyle as WebMessageBodyStyle.Wrapped. This when I changed to WebMessageBodyStyle.Bare, Voila the response XML just came out like I wanted. Finally, the simple 2 lines of deserialization code worked..

So folks, be aware these 2 issues when you work witn WCF REST and serialization/deserialization.

Wednesday, July 20, 2011

WCF REST and Silverlight Synchronous calls within same domain

In my previous blog Silverlight and WCF REST near synchronous calling we saw how to achieve near synchronous behavior in the cross domain scenario. But if you have the advantage of hosting the WCF REST in the same domain of Silverlight; it is possible to achieve synchronous behavior using Wilco's HTTP requests for Silverlight

Below is the sample code which I used;
var result = Request.To("/services1.svc/DoWork")
.WithHeader("Content-Type","application/xml")
.Send().ReadAllText();

ASP.NET Validators inside AJAX UpdatePanels

Got a requirement to use ASP.NET Validators inside AJAX UpdatePanels? Don't worry, here is the solution. Just follow the steps provided in the link below;
http://blogs.msdn.com/b/mattgi/archive/2007/01/23/asp-net-ajax-validators.aspx

Silverlight and WCF REST, near synchronous calling

It may be very annoying since Silverlight doesn't provide synchronous calls with WCF. Loads and loads of debate happened around this but no concrete solution yet out in the market. I tried to solve this problem to an extend (not exactly synchronous) using Microsoft Rx (Reactive Extensions) framework and Wilco Bauwer's Http Request in Silverlight approach. See below how I did;


Microsoft Rx Extensions


1) Download the Microsoft Reactive Extensions framework
2) Add the System.Reactive.dll assembly reference to your Silverlight app
3) Add the following property and private variables;


private string _result;
protected bool _pageRefreshed;

public string Result1
{
get
{

return _result;
}
set
{
_result = value;
_pageRefreshed = true;
MainPage_Loaded(null, null);
}
}


Here what I am trying to do is that, instead of having the separate delegate function to handle the callback, I am pushing the callback to Silverlight Page_Loaded event. This is very similar to the way we deal with Postbacks in Page_Load in ASP.NET


4) Use this code to invoke your WCF REST service


WebClient client1 = new WebClient();
Uri url = new Uri(
https://www.WCFRESTService.Demo/BLServiceImplementation.svc/TraceError);
string input = "<LoggingServices_TraceError xmlns='http://tempuri.org/'><message>Hello!! I am from Silverlight!!!</message></LoggingServices_TraceError>";



var o = Observable.FromEventPattern(client1, "UploadStringCompleted").Select(newstring => newstring.EventArgs.Result);

o.Subscribe(s => Result1 = s);


client1.Headers["Content-Type"] = "application/xml";
client1.UploadStringAsync(url, input);


This is how it works, the result from asynchronous WCF REST call will be assigned to the Result1 property. In the Set section, after assigning to the local variable; I am also firing the Page_Loaded event of silverlight.
And in the Page_Loaded event, I am handling the result like shown below;


void MainPage_Loaded(object sender, RoutedEventArgs e)

{
if (_pageRefreshed == true)
{
_pageRefreshed = false;
result.Text = _result;
return;
}
}

Wilco Bauwer's Http Request in Silverlight approach

1) Download the code from Wilco HTTP Request and Silverlight
2) Before actually using this in you application, you need to get the code build.
3) Also, you need to make some modifications to be able to use XML and JSON WCF REST calls. Locate the Request.cs file and modify the SetRequestProperties as shown below;

private void SetRequestProperties(HttpWebRequest request) {

request.Method = _method;
foreach (var entry in _headers) {
if (entry.Key.ToLower() == "content-type")
{
request.ContentType = entry.Value;
}
else
request.Headers[entry.Key] = entry.Value;
}
}
4) Follow Step 3 in the above approach
5) Use the code below to call the WCF REST service;
Request.To(https://www.WCFREST.Demo/BLServiceImplementation.svc/TraceError)

.WithHeader("Content-Type", "application/xml")
.WithMethod("POST")
.WithBody("Hello!! I am from Silverlight!!!")
.SendAsync(response => Result1 = response.ReadAllText());

The approach is same as above except that Wilco provides Fluent Interface which is the user friendly LINQ.
The Page_Load code also same except for one small modification as below;

Dispatcher.BeginInvoke(()=> {

result.Text = _result;
});

You will make to wrap any assignment to UI controls with Dispatcher.BeginInvoke otherwise you will get cross thread access issue.

Happy coding!!! Let me know if you face any issues.

Wednesday, April 6, 2011

ScreenUpdating property and Excel/Word/Outlook Add-In

Recently while developing an Excel Add-In we faced a peculiar problem of Excel worksheet hanging after completing the processing. No problem in functionality, no memory leaks, no exceptions and nothing... We were breaking our heads where else it could fail...

After a couple of trials, we figured out that Workbook.ActiveWorksheet.ScreenUpdating was set to FALSE and was not turned back to TRUE. We usually set ScreenUpdating to FALSE to speed up the macro processing, but if we forget to turn back to TRUE; thats it; you will think Excel is hanging or something happened.. So please watch out while using ScreenUpdating in your code :)