May
26
2011
After having great success consuming a WCF Web service using MonoTouch as I mentioned in the previous post, I next set off to consume an OData feed thinking this would be just as easy. And sure enough, it was just as easy, until I graduated my wonderful little app from the iPhone Simulator to my actual phone. Once on my phone, the application would still run just fine, but whenever a call was made to asynchronously fetch data from the OData feed – crickets – my user friendly activity indicators just keep spinning indefinitely.
Here are the steps I took to get this far:
- Copied into my MonoTouch project the generated data service reference class from the WP7 project where I previously consumed the OData feed
- Referenced the System.Data.Services.Client assembly provided by MonoTouch
- Put together the following method to asynchronously retrieve a single entity from the OData feed:
public void GetMarker(int markerNum, Action<Marker> successCallback, Action<Exception> errorCallback)
{
var serviceUri = new Uri(ODataServiceUrl);
var dataServiceContext = new MyDataServiceContext(serviceUri);
var markerUri = new Uri(string.Format("/Marker({0})", markerNum), UriKind.Relative);
try
{
dataServiceContext.BeginExecute<Marker>(markerUri, a =>
{
try
{
var results = dataServiceContext.EndExecute<Marker>(a);
var marker = results.Single();
successCallback(marker);
}
catch (Exception e)
{
errorCallback(e);
}
},
null);
}
catch (Exception e)
{
errorCallback(e);
}
}
As you can see by reviewing the above code, you would think that it is guaranteed that one of the two callbacks (either the successCallback or errorCallback) will always be called. However, launching the Mono Soft Debugger proved otherwise. I placed a breakpoint inside the anonymous delegate passed to the BeginExecute method, and sure enough, it is never reached.
Dumbfounded by what was happening, I rewrote the method to make the call synchronously by replacing the call to BeginExecute with its synchronous counterpart, Execute. It was then that I finally got some visibility into my original issue because the underlying exception was now being caught:
Attempting to JIT compile method '(wrapper managed-to-native) System.Threading.Interlocked:CompareExchange
(System.Exception&,System.Exception,System.Exception)' while running with --aot-only.
at System.Data.Services.Client.BaseAsyncResult.HandleFailure (System.Exception e) [0x00000] in :0
at System.Data.Services.Client.QueryResult.Execute () [0x00000] in :0
at System.Data.Services.Client.DataServiceRequest.Execute[Marker]
(System.Data.Services.Client.DataServiceContext context, System.Data.Services.Client.QueryComponents
queryComponents) [0x00000] in :0
at System.Data.Services.Client.DataServiceContext.Execute[Marker] (System.Uri requestUri) [0x00000] in :0
at Trentacular.Trsh.MarkerService.GetMarkerUsingDataServiceContext (Int32 markerNum, System.Action`1
successCallback, System.Action`1 errorCallback) [0x0002a]
I then found this entry in the MonoTouch troubleshooting documentation that I believe is suggesting that I need to explicitly force the AOT compiler to include the Interlocked.CompareExchange method by calling it myself before the call to Execute. Tried that, same exception still, except it is now getting thrown when I explicitly called the CompareExchange method.
Running out of options, I ditched the DataServiceContext altogether and rewrote the GetMarker method using a WebClient and Linq-to-Xml as follows:
static readonly XNamespace atomNS = XNamespace.Get("http://www.w3.org/2005/Atom");
static readonly XNamespace metadataNS = XNamespace.Get("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
static readonly XNamespace dataservicesNS = XNamespace.Get("http://schemas.microsoft.com/ado/2007/08/dataservices");
public void GetMarker(int markerNum, Action<Marker> successCallback, Action<Exception> errorCallback)
{
var webClient = new WebClient();
webClient.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs args)
{
try
{
if (args.Error != null)
{
errorCallback(args.Error);
return;
}
var document = XDocument.Parse(args.Result);
var root = document.Root;
var properties = root.Element(atomNS + "content").Element(metadataNS + "properties");
var marker = new Marker
{
MarkerNum = Convert.ToInt32(properties.Element(dataservicesNS + "MarkerNum").Value),
Address = properties.Element(dataservicesNS + "Address").Value.TrimEnd(),
YearEstablished = properties.Element(dataservicesNS + "Year").Value,
MarkerText = properties.Element(dataservicesNS + "MarkerText").Value
};
successCallback(marker);
}
catch (Exception e)
{
errorCallback(e);
}
};
try
{
var markerUri = new Uri(string.Format("{0}/Marker({1})", ODataServiceUrl, markerNum), UriKind.Absolute);
webClient.DownloadStringAsync(markerUri);
}
catch (Exception e)
{
errorCallback(e);
}
}
This worked liked a charm. It is unfortunate though the DataServiceContext approach doesn’t work. While Linq-to-Xml isn’t all that bad, I am having to do more work than my spoiled .Net developer mentality would like – why traverse xml, deal with xml namespaces, and require knowledge of node names when this can all be abstracted for you.
Knowing the Mono guys are no longer working for Novell, I doubt this will ever get fixed in MonoTouch, but I am hoping that they will produce something far more exceptional with their new venture Xamarin.
no comments | tags: ios, mono, monodevelop, monotouch, odata, wcf, web services | posted in iOS, Mobile, wcf
May
13
2011
I was recently presented with an opportunity to write a mobile application for a local Dallas homeless ministry. Learning about what the ministry leader envisioned for the app as well as already owning a Mac and an iPhone led me down the iOS development path. After reading a little about Objective-C and memory management, I quickly was loosing hope for turning something around before having to go back to work Monday. I guess I’ve been spoiled for too long with automatic garbage collection.
I then learned about MonoTouch, downloaded the trial, got up and running with MonoDevelop, and one evening later had finished my first application. To get my feet wet, I chose to port a Windows Phone 7 application my colleagues at Slalom and I had written called Texas Roadside History (shameless plug: if you use a WP7, search for Roadside History in the Marketplace).
I want to highlight a single HUGE benefit I’ve realized to having used MonoTouch: I get the WCF stack!
The server component of Texas Roadside History is running in Azure – SQL Azure and a Web role providing both a SOAP Web service endpoint and OData endpoints. Having already generated service references (client proxies) for these endpoints in the WP7 version of the app, I simply copied them into my MonoTouch project, referenced the System.ServiceModel assembly, and was back to making asynchronous Web service calls with zero XML parsing.
2 comments | tags: ios, mono, monodevelop, monotouch, wcf, web services | posted in iOS
Feb
1
2011
Stumbling here because you are having trouble updating a service reference in your Windows Phone 7 application? Are you getting a warning that reads something like this?
Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Could not load type 'System.Runtime.Serialization.DataContractSet' from assembly 'System.Runtime.Serialization, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
Or this?
Custom tool warning: No endpoints compatible with Silverlight 3 were found. The generated client class will not be usable unless endpoint information is provided via the constructor.
I’ve had this problem several times now, and each time I’m stumped why this happens. So I am writing down what causes this once and for all so that I don’t keep forgetting. Here it goes …
Frequently I am wanting to consume OData feeds within my apps. An easy way to do so is to use the Open Data Protocol Client Library available on CodePlex. The library contains the System.Data.Services.Client.dll assembly that you reference in your Windows Phone application project.
This assembly is trouble when trying to mix with service reference generation. I’ve seen posts that talk about deselecting the “Reuse Types in Referenced Assemblies” option when generating the reference, but this is not exactly a solution I am happy with. What if I do want to reuse types?
The best workaround I’ve come up with so far is to generate my service references in a separate Windows Phone Class Library project that does not reference the System.Data.Services.Client.dll. I then add a project reference to this class library in the WP7 application project. Finally, I need to copy the system.serviceModel entries generated in the class library’s ServiceReferences.ClientConfig file to the WP7 application’s ServiceReferences.ClientConfig file.
It is also probably not a bad idea to include any OData generated proxies along with the System.Data.Services.Client.dll in a separate Windows Phone Class Library project as well.
I hope this post saves you some headache as it will for me time and time again.
5 comments | tags: mobility, wcf, web services, windows phone 7 | posted in Windows Phone 7
Apr
15
2010
In this post I am going to walk through writing and consuming JSON services using ASP.Net, WCF, and jQuery to request the stock price for a company.
Visual Studio 2010 Web Application Project Template Additions
- jQuery Intellisense – let Visual Studio write your jQuery for you
- AJAX-enabled WCF Service – item template that auto-generates the web.config entries for configuring a JSON service to be consumed and proxied by an ASP.Net ScriptManager
- Targeted web.config files – easy way to manage different service endpoints for different environments
What is JSON?
Java Script Object Notation – JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
var dog = {color: "grey", name: "Spot", size: 46};
SOAP Bloat
SOAP services are extremely verbose. This verbosity enables us to use tools like Visual Studio’s built-in ”Add Service Reference” to auto-generate client proxy classes. The following examples demonstrate the XML that is used for requesting a stock price and the corresponding response:
Example SOAP Request
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPrice>
<m:StockName>GOOG</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
Example SOAP Response
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPriceResponse>
<m:Price>534.5</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>
The above example when formatted as JSON is as follows:
GET Request
ticker=GOOG
JSON Response
JSON Enabling a WCF Service
- Using the AJAX-enabled WCF Service item template pretty much does it all. An additional step can be taken to eliminate the need for the additions to the web.config by configuring the channel factory directly on the service declaration (.svc) file:
<%@ ServiceHost Language="C#" Debug="true"
Service="Trentacular.JsonWcfDemo.StockPriceService"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
CodeBehind="StockPriceService.svc.cs" %>
- Decorate the operation (service method) with the WebGetAttribute to enable the use of HTTP GET for data retrieval and return the response as JSON :
[WebGet(ResponseFormat = WebMessageFormat.Json)]
Our resulting stock price service’s code behind will look like the following:
[ServiceContract(Namespace = JsonWcfDemoNamespace.Value)]
public class StockPriceService
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
public StockPrice GetStockPrice(string ticker)
{
...
}
// Add more operations here and mark them with [OperationContract]
}
Converting Text to JSON and Back
eval() – invokes the JavaScript compiler. The compiler will correctly parse the text and produce an object structure. The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues.
JSON.parse() – To defend against security issues with the eval function, it is preferred to use a JSON parser. A JSON parser will recognize only JSON text, rejecting all scripts. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.
jQuery’s $.getJSON() Method
jQuery provides the getJSON method for easily making calls to services providing JSON-formatted responses and performing the JSON conversion. Its signature is as follows:
$.getJSON( url, [ data ], [ callback(data, textStatus) ] )
url – A string containing the URL to which the request is sent.
data – A map or string that is sent to the server with the request.
callback(data, textStatus) – A callback function that is executed if the request succeeds.
Consuming our stock price service using the getJSON method will look like the following:
$.getJSON("StockPriceService.svc/GetStockPrice", { ticker: tickerValue }, function (data, textStatus) {
if (textStatus != 'success' || !data.d) {
$("#stockPricePanel")
.html('<span class="error">Error looking up stock price. Did you enter a valid ticker?</span>');
} else {
var stockPrice = data.d;
var isIncrease = (stockPrice.Delta >= 0);
var deltaStyle = isIncrease ? 'gain' : 'loss';
$("#stockPricePanel")
.html('<span class="price">' + stockPrice.Price + '</span>')
.append('<span class="delta ' + deltaStyle + '">' + stockPrice.Delta + '</span>')
.append('<span class="percent ' + deltaStyle + '">(' + stockPrice.PercentChange + '%)</span>');
}
});
Working with WCF Serialized JSON Dates
One caveat when working with JSON is that WCF serializes DateTimes to JSON in the format:
/Date({milliseconds since 01/01/1970}-{time zone})/

Unfortunately, native JSON conversion does not automatically convert the date string to a JavaScript date object. The following method shows an example of how to convert a JSON date string to a javascript Date object:
function convertJSONToDate(json) {
return eval(json.replace(/\/Date\((.*?)\)\//gi, "new Date($1)"));
}
Download the Demo Application

Download Now
no comments | tags: asp.net, asp.net 3.5, jquery, json, soap, visual studio 2010, wcf, web services | posted in asp.net, javascript, wcf
Aug
5
2009
Working with object trees is risky business when combined with remoting. Object trees often have very deep branches and circular references that will clog your pipes and overflow your stack when not handled properly.
NHibernate has addressed this same problem in the object-relational space with a very cool feature called lazy initialization, implemented using the Castle DynamicProxy library. By default, when an entity is loaded, its related entities are populated with proxies. The use of a proxy allows the entity to remain uninitialized until the moment one of its non-identifying properties is accessed, which in many cases is never – thus minimizing database queries. This strategy also eradicates the problem with loading an entire object tree from the database when only a single entity is needed.
Proxies become a problem when combined with Web services or WCF. Serialization of objects to XML requires knowledge of the data type to be serialized (accomplished with the KnownType attribute in WCF). The dynamically generated nHibernate proxies are not known to the serializer and thus a request to the service results in an exception such as System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
In order to make these entities safe for sending through the pipes, we must “unproxy” them and impose a limit to the object tree depth. The following utility class can be used for doing both by simply calling possiblyProxiedEntity.UnproxyObjectTree(mySessionFactory, maxDepth):
using System;
using NHibernate;
using NHibernate.Metadata;
using NHibernate.Proxy;
namespace Trentacular.Data.NHibernate.Util
{
public static class NHibernateProxyUtils
{
/// <summary>
/// Force initialization of a proxy or persistent collection.
/// </summary>
/// <param name="persistentObject">a persistable object, proxy, persistent collection or null</param>
/// <exception cref="HibernateException">if we can't initialize the proxy at this time, eg. the Session was closed</exception>
public static T Unproxy<T>(this T persistentObject)
{
var proxy = persistentObject as INHibernateProxy;
if (proxy != null)
return (T)proxy.HibernateLazyInitializer.GetImplementation();
return persistentObject;
}
/// <summary>
/// Gets the underlying class type of a persistent object that may be proxied
/// </summary>
public static Type GetUnproxiedType<T>(this T persistentObject)
{
var proxy = persistentObject as INHibernateProxy;
if (proxy != null)
return proxy.HibernateLazyInitializer.PersistentClass;
return persistentObject.GetType();
}
/// <summary>
/// Force initialzation of a possibly proxied object tree up to the maxDepth.
/// Once the maxDepth is reached, entity properties will be replaced with
/// placeholder objects having only the identifier property populated.
/// </summary>
public static T UnproxyObjectTree<T>(this T persistentObject, ISessionFactory sessionFactory, int maxDepth)
{
// Determine persistent type of the object
var persistentType = persistentObject.GetUnproxiedType();
var classMetadata = sessionFactory.GetClassMetadata(persistentType);
// If we've already reached the max depth, we will return a placeholder object
if (maxDepth < 0)
return CreatePlaceholder(persistentObject, persistentType, classMetadata);
// Now lets go ahead and make sure everything is unproxied
var unproxiedObject = persistentObject.Unproxy();
// Iterate through each property and unproxy entity types
for (int i = 0; i < classMetadata.PropertyTypes.Length; i++)
{
var nhType = classMetadata.PropertyTypes[i];
var propertyName = classMetadata.PropertyNames[i];
var propertyInfo = persistentType.GetProperty(propertyName);
// Unproxy of collections is not currently supported. We set the collection property to null.
if (nhType.IsCollectionType)
{
propertyInfo.SetValue(unproxiedObject, null, null);
continue;
}
if (nhType.IsEntityType)
{
var propertyValue = propertyInfo.GetValue(unproxiedObject, null);
if (propertyValue == null)
continue;
propertyInfo.SetValue(
unproxiedObject,
propertyValue.UnproxyObjectTree(sessionFactory, maxDepth - 1),
null
);
}
}
return unproxiedObject;
}
/// <summary>
/// Return an empty placeholder object with the Identifier set. We can safely access the identifier
/// property without the object being initialized.
/// </summary>
private static T CreatePlaceholder<T>(T persistentObject, Type persistentType, IClassMetadata classMetadata)
{
var placeholderObject = (T)Activator.CreateInstance(persistentType);
if (classMetadata.HasIdentifierProperty)
{
var identifier = classMetadata.GetIdentifier(persistentObject, EntityMode.Poco);
classMetadata.SetIdentifier(placeholderObject, identifier, EntityMode.Poco);
}
return placeholderObject;
}
}
}
There are several approaches on where and when this should take place depending on if you are using ASP.Net 2.0 Web services or WCF which I am not going to go into in this post. If you are working with WCF, Tim Scott has written about a good approach here.
16 comments | tags: lazy initialization, nHibernate, proxy, remoting, wcf, web services | posted in nHibernate
Recent Comments