Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Friday, January 6, 2012

Binding dynamic XML objects to Silverlight Grids

Recently we had an requirement to bind the content of dynamic XML to Silverlight Grids.This is straightforward in ASP.NET with the help of DataSet. But we do not have DataSet in Silverlight or WPF. To achieve this we used the following approach;


The code is self-explanatory with the comments explaining each step;


public string Result
{
get
{
return _result;
}
set
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
//Load the xml string to XDocument
XDocument doc = XDocument.Load(new StringReader(value));
MemoryStream str = new System.IO.MemoryStream();
doc.Save(str);


//Finding the Name of the class
string objName = doc.Descendants().First().Name.LocalName.Replace("ArrayOf", "");


//Making it a fully qualified name by appending the corresponding
//namespace
objName = "MyCompany.MyApplication." + objName;


//Loading the assembly that contains the Entity which
//we are trying to de-serialize
//NOTE: To be able to do the below 3 steps, you need to ensure that
//the entities dll reference is added in Deployment.Parts of the
//App Manifest file
StreamResourceInfo sri = Application.GetResourceStream(new Uri("MyApplication.SL.Entities.dll",UriKind.Relative));
AssemblyPart myPart = new AssemblyPart();
System.Reflection.Assembly assm = myPart.Load(sri.Stream);


//Using reflection to build the List<T>
var pageToShowType = assm.GetType(objName);
Type t = typeof(List<>);
Type [] args = {pageToShowType};
Type r = t.MakeGenericType(args);


//De-serializing and assigning to the property to show in the grid
str.Position = 0;
DataContractSerializer serializer = new DataContractSerializer(r);
//Bind the ResultObject to the SL Grid
//NOTE: Ensure that SL Grid has AutoGenerateColumns = TRUE
ResultObject = serializer.ReadObject(str);
str.Close();


});


}


}

Friday, December 16, 2011

Workaround to Button using MVVM ICommand and IsEnabled issue

When you are using the Command Button in MVVM pattern with ICommand, you will not be able to use the IsEnabled property to enable/disable the command button. As a workaround to enable/disable the command button, you can put the Command Button inside the group control like StackPanel and set the IsEnabled property of StackPanel to TRUE/FALSE.

Tuesday, September 6, 2011

Silverlight and SEO

Recently I came across a very good article on Silverlight and SEO techniques for public facing Silverlight based websites. Check the link below for more;

Silverlight and SEO

Thursday, September 1, 2011

WCF RIA and custom methods

There may be times where-in you will have to add some custom coded methods along with the auto generated EF wrapper methods. You may be wondering how to do. Don't worry.. RIA provides support for that and is very simple. Follow these steps to get this work;

Server-side

In the Domain service class, decorate the custom methods with the [Invoke] attribute. Job done!!

[Invoke]
public string SayHello ()
{
        return "Hello";
}

Client-side

This is how you can access the RIA custom methods;

HelloDomainServiceContext ds = new HelloDomainServiceContext();
ds.SayHello( (p) => {var result = p.Value;}, null);

Wednesday, August 24, 2011

Dreaded NotFound and Object reference not set to an instance of object exceptions in WCF RIA Services

Recently while developing an WCF RIA Services and SL4 client, I was facing these dreaded "NotFound" and "Object reference not set to an instance of object". After a bit of googling figured out the problem and its root cause.

NotFound exception

To view the actual error, you will have to use Fiddler. In the Fiddler, you can find out the actual error as "HTTP 404, Page Not Found error". This is because, WCF RIA service sits in the same virtual directory of you SL4 application. But the necessary config entries were not getting copied to the SL4 application config file.

For instance, When you create an RIA service and SL4 client; you will get the following projects in your solution;

xxxRIASerices.Host
xxxRIAServices.Host.Web

xxxSLRIAClient
xxxSLRIAClient.Web

The necessary config entries for enabling RIA service will be available in the App.Config file in xxxRIAServices.Host.Web (Basically the connectionStrings, System.Web, System.webServer sections). Copy those sections to xxxSLRIAClient.Web Web.Config file.

Bingo, we have get rid of the NotFound exception.

Object reference not set to an instance of object exception

I am sure, you will be getting this error. :) To solve this error, copy paste the System.ServiceModel section from xxxRIAServices.Host.Web App.Config to xxxSLRIAClient.Web Web.Config file.

Yes, now you should have get rid of these 2 exceptions and your WCF RIA service and SL client App will be working like charm.

Tuesday, August 23, 2011

Dreaded System.Security.SecurityException: Security Error... Silverlight and WCF REST

Recently I faced the dreaded System.Security.SecurityException: Security Error.. while developing the SL4 application consuming the WCF REST service. After a lot of trials fixed this dreaded issue. So thought of sharing my experince on SL4 consuming WCF REST service.

1) Ensure that crossdomain.xml and clientaccesspolicy.xml files are available in C:\Inetpub\wwwroot folder.
2) If you are using HTTPS, ensure the following;
  • Ensure clientaccesspolicy.xml contains explicit <domain uri="https://*"></domain>
  • Ensure only SSL access is enabled. The SL app and WCF REST service should not be accessible in HTTP mode.
  • Ensure crossdomain.xml contains <site-control permitted-cross-domain-policies="master-only"/> <allow-access-from domain="*" />
Do IISRESET. Then you should be able to get rid of this dreaded error.

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();

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.

Tuesday, March 22, 2011

Silverlight Integration in DNN

Here are the simple steps to integrate Silverlight in DotNetNuke.
1) Publish the silverlight application


2) Host the published silverlight application in IIS
3) Goto the DNN website. Create a web page for hosting the silverlight application
4) 4) Add the “HTML” module to the newly created page. And then, go to the HTML view in the Rich Text Editor. Place the <IFRAME> tag with the src to the silverlight HTML page hosted in IIS in the above steps
5) Voila!!! Now you can see that silverlight functionality working in the DNN site

Monday, March 14, 2011

Changing WCF service reference in silverlight at runtime

Since Silverlight App is packaged as XAP file, you may be wondering how to change the service reference after building the package. It is pretty simple. XAP file is nothing but a ZIP archive file.
So,
  • Unzip the file using any ZIP archiving software
  • Locate the ServiceReferences.ClientConfig
  • Change the end point in the file, save changes
  • Zip it again and change the extension to XAP

Voila!!!

Thursday, March 10, 2011

WCF DataContract serialization and deserialization in Silverlight

Here is how you can do serialization and deserialization of WCF DataContracts in Silverlight. This is needed when you use MessageContracts in WCF by wrapping DataContracts as XmlElement.

Serialization code:

DataContractSerializer serialize = new DataContractSerializer(request.GetType());
MemoryStream stream = new MemoryStream();
serializer.WriteObject(stream,request);
string res = Encoding.UTF8.GetString(stream.ToArray(),0,stream.ToArray().GetLength(0));
TextReader reader = new StringReader(res);
XDocument doc = XDocument.Load(reader);
XElement elt = (XElement)doc.FirstNode;

you can pass the elt in your MessageContract and send to the WCF service.

Deserialization code:

Once you receive the response from WCF service as XElement, this is how you can deserialize that to object.

XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(elt.CreateReader());
DataContractSerializer serialize = new DataContractSerializer(reader);
result - serialize.ReadObject(reader);

Wednesday, March 9, 2011

Some simple steps to convert ASP.NET application to Silverlight application

Sometime you may be asked to look at the possiblity of converting the ASP.NET application to Silverlight application. Trust me, there are no hard and fast rules to migrating ASP.NET to Silverlight due to various reasons;
  1. Silverlight runs in client-side; ASP.NET runs in the server-side. This means, you will not be able to use as much as functionalities available from server-side.
  2. Application Life Cycle is entirely different for Silverlight and ASP.NET. You need to familiarize yourselves first before starting to work on silverlight.

But, somehow I managed to find some steps which will ease the ASP.NET to Silverlight migration;
  1. Find the equivalent controls for ASP.NET controls in Silverlight
  2. Convert the .aspx pages to .xaml files
  3. Define the Page navigation in App.xaml.cs file (bit difficult to do)
  4. Silverlight support very few assembly references. Migrate the .aspx.cs code .xaml.cs code accordingly.
  5. If you encounter some assembly references breaking, convert those functionalities to WCF service. Good thing about silverlight is that, it supports communication with WCF service with some limitations (no WS-Security)
  6. Silverlight follows MVVM pattern, if you application built around MVVM or can be easily upgraded to MVVM pattern, you can migrate your ASP.NET application to Silverlight application at ease...

I will update this post, If I manage to find some other tweaks and tricks in converting ASP.NET to Siliverlight.

Tuesday, February 22, 2011

Passing Default Credentials from Silverlight to WCF

While developing Silverlight and WCF apps you will have to share the default credentials from Silverlight to WCF service sometime.



This is how you can do;


1) Create the <basicHttpBinding> with the following information under the <bindings> section;

<basicHttpBinding>
<binding name="BasicBinding0">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>

2) Add the below piece of section under the <System.ServiceModel> section
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>

3) Add the below piece of code above the OperationContract behavior;
[System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode=System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)]
public class StaticDataProcessing : ProcessTaskWCFBase

Please note that steps 2 and 3 are needed to avoid the HttpContext.Current coming as NULL issue.

This way you can pass the default credentials from Silverlight to WCF.