Posts archived in .NET

Two methods that I keep finding myself needing are a way to Serialize and Deserialize objects in .NET 3.5.

Either for Unit Testing against a WebService of some kind, or for storing objects in memory to disk in XML for human-readable niceties.

Don’t forget to add in appropriate error handling code as needed.

With .NET 3.5 SP1, these methods will serialize (almost) any object to either XML or JSON, it was based in part off an example given in a long since forgotten forum post.

 

using System.IO;
using System.Runtime.Serialization; // System.Runtime.Serialization.dll (.NET 3.0)
using System.Runtime.Serialization.Json; // System.ServiceModel.Web.dll (.NET 3.5)
using System.Text;
namespace Serialization
{
    public static class Helpers
    {
        /// <summary>
        /// Declare the Serializer Type you want to use.
        /// </summary>
        public enum SerializerType
        {
            Xml, // Use DataContractSerializer
            Json // Use DataContractJsonSerializer
        }

        public static T Deserialize<T>(string SerializedString, SerializerType UseSerializer)
        {
            // Get a Stream representation of the string.
            using (Stream s = new MemoryStream(UTF8Encoding.UTF8.GetBytes(SerializedString)))
            {
                T item;
                switch (UseSerializer)
                {
                    case SerializerType.Json:
                        // Declare Serializer with the Type we're dealing with.
                        var serJson = new DataContractJsonSerializer(typeof(T));
                        // Read(Deserialize) with Serializer and cast
                        item = (T)serJson.ReadObject(s);
                        break;
                    case SerializerType.Xml:
                    default:
                        var serXml = new DataContractSerializer(typeof(T));
                        item = (T)serXml.ReadObject(s);
                        break;
                }
                return item;
            }
        }

        public static string Serialize<T>(T ObjectToSerialize, SerializerType UseSerializer)
        {
            using (MemoryStream serialiserStream = new MemoryStream())
            {
                string serialisedString = null;
                switch (UseSerializer)
                {
                    case SerializerType.Json:
                        // init the Serializer with the Type to Serialize
                        DataContractJsonSerializer serJson = new DataContractJsonSerializer(typeof(T));
                        // The serializer fills the Stream with the Object's Serialized Representation.
                        serJson.WriteObject(serialiserStream, ObjectToSerialize);
                        break;
                    case SerializerType.Xml:
                    default:
                        DataContractSerializer serXml = new DataContractSerializer(typeof(T));
                        serXml.WriteObject(serialiserStream, ObjectToSerialize);
                        break;
                }
                // Rewind the stream to the start so we can now read it.
                serialiserStream.Position = 0;
                using (StreamReader sr = new StreamReader(serialiserStream))
                {
                    // Use the StreamReader to get the serialized text out
                    serialisedString = sr.ReadToEnd();
                    sr.Close();
                }
                return serialisedString;
            }
        }
    }
}

Hopefully others will find this useful.

 

Updated - A little more generic now – can serialize to either Json or Xml as needed by altering the type param.

3 comments

My Android

On Friday my Google Dev Phone 1 (aka HTC Dream / T-Mobile G1) arrived.

It’s about AUD$800 delivered to Australia (USD$399 + USD$50 Shipping + USD$25 Dev Signup). Google recently discovered that Australia wasn’t on Mars, and dropped the shipping cost from USD$150 to USD$50 or so.

Here’s my notes so far:

Device
- Slide out qwerty keyboard – works well, takes a little getting used to the layout, but it’s good enough for reasonable length of text entry.

- Trackball – seems a little gimmicky, but for some apps it’s useful.

- Construction – Feels reasonably solid – the back cover might be a problem later. The only fault is that apparently the battery does come loose from it’s position on some phones (James has this issue). Easily fixed by using paper shims, but it’s not the best experience.

- Screen – It’s fairly bright, but it’s difficult to use in direct sunlight like every other LCD out there. Also, this isn’t a multi-touch device (the hardware supports it – it’s a software / patent issue afaik) so some things like Zooming don’t work like on the iphone

- Sound I havn’t tested much – the speakers are the usual tinny things used in anything smaller than a laptop. The biggest disappointment is a lack of 3.5″ headphone port. It runs (like other HTC Devices) through an adaptor plugged into the single mini-USB port. The same port is used for charging too – so you’ll need a double adaptor (See eBay) if you want to do both at once. The quality seems decent enough for a mobile.

Android Software

- Gmail or death. There is no option to use the device WITHOUT a Gmail account. Don’t like it – tough luck. Until someone implements full Exchange support (including remote wipe), I’d avoid using it for business purposes.

- Over-the-air everything. From Installing/updating apps, to checking email and syncing contacts – it all happens over whatever your internet connection is. There is currently no software to install on your PC.

- Multitasking ftw. Every app runs in it’s own VM, and when you switch tasks the state is suspended and (potentially) saved to storage. This keeps your foreground app running nice and fast. Apps can still run tasks in the background (eg for IM, PUSH Email, etc) – so you can still get notifications. The phone will keep multiple tasks in memory, in the suspended state – but if the phone needs room it’ll dump the least recently used apps to storage.

- Notifications – Background tasks notify through a central Notifications panel – this is a pull-down from almost anywhere on the phone that lets you quickly switch back to other apps.

Market.
- VERY easy to use and install waaaay too much stuff at once.

- I love that you can see what permissions apps are requesting when you go to install them.

- There’s a built in comments/rating system – when you select an app from the Market, it shows this commentary.

- Completely over the air – browsing, downloading, installing and upgrading apps is done over the air.

- App coverage is decent for something with very little market penetration and mostly for geeks. My favorite app is “Zombie, Run!” which harnesses Google Maps and GPS integration to overlay where Zombies are around you. Said Zombies shamble towards you based on three speeds.

Contact / Data Sync:
- Uses GMail Contacts as the sync backend. Because there’s no PC Sync functions, you can’t sync with Outlook.

- You can import from CSV, but this is very error prone (at least, for me and James), and ends up with orphaned, ignored, just plain empty Contacts.

- Won’t connect over Bluetooth with a N95 to transfer contacts (Attempts to connect and fails) – so can’t send all the contacts as business cards.

- Overall Contact management is very disappointing and not well thought out (sure, adding one at a time is fine – but time consuming).

Multiple Account Support:
- Like every other smart phone out there – only supports one account in any sane manner. You CAN set up the other accounts via imap, but this isn’t the best experience (no PUSH, for instance).

Overall summary so far:
Good for gadget freaks and devs looking to launch on the Android platform.

Android is very obviously missing some major pieces of functionality though. I can live without Exchange email, but I can’t live without the Sync’ed contacts. (Exporting back and forth is a PITA). Symbian/Nokia got this right with the Exchange app which, while slow, can manage to sync all the contacts in the Address book with Exchange and vice versa.

The Market functionality is neat, and because apps can run in the background (and have tighter integration with the hardware) unlike the iPhone – has a lot of potential.

Update:
Forgot to mention – Gmail on the Android is done via PUSH – so you get notification of new email as it arrives – just like Exchange with Outlook/iPhone/Blackberry.

So one of the things you find in C# when you move from VB.NET is that you can’t do Optional parameters on methods.

Actually, you can – it’s just that the compiler in VB.NET is giving you a free ride by generating overloaded values for you automatically. Correction, Looks like C# is being difficult, see this FAQ

Anyway, say you have a VB.NET function like so:

Public Sub TestFunction(Param1 as String, Optional Param2 as String = “Default Value”)
    // Do Stuff
End Sub

In C# you can achieve the same thing by writing a stub like so:

public void TestFunction(string Param1)
{
TestFunction(Param1, “Default Value”);
}

public void TestFunction(string Param1, string Param2)
{
// Do Stuff
}

Yeah, it’s a little more code to write – but it’s really not that difficult to manage unless you have truely obscene numbers of optional parameters.

TechRepublic has a look at the same issue too, and gives Parameter arrays as an alternative. Under .NET 3.0+ with Anonymous types you can use some reflection niceties to do some other, similar things too.

On a different note, reading VB code after nearly a year straight of C# development feels a little strange.

Because Adobe currently don’t support Kerberos in Flex, that limits the ability to do cool Single Sign On stuff through Air and on various sites.

So, how to solve this?  Well, this is just a theory, but it seems to work ok on paper.

The basic idea is that you have something else do the authentication, and generate a One Time Key. That Key is then passed to your Flex app (eg via the Command Line for Air, or a Flashvar in the browser), which then uses this OTK to authenticate and grab a Session key like you normally would.

The point of using a One Time Key which is then discarded after use,  is so that someone malicious can’t grab (say) your process list and reuse that authentication token.

So, for Windows Air clients – you could build a quick-and-dirty preloader (.NET makes this really easy) which does your Kerberos authentication using (say) your Windows Identity against Active Directory.

For Mac Air clients – You’d also need to build a preloader (Mono? :D ). Whether you can achieve SSO this way would depend on how the OSX Identity stuff works under a domain (or the equivilent analog in OSX world) model, but at the very least you could do your Kerberos authentication here.

And for Server-side components, well, that’s pretty damn obvious – you generate the OTK on the server and deliver it down (over SSL!) as part of the page.

Anyway, hope this helps someone who’s pondering the way to solve this.

I’m working on a new project at work where we’re dealing with data that updates frequently, at unpredictable times, used in across several different front-end services, and needs to scale to pretty decent traffic levels without going nuts on buying more hardware.

So, given all that, one of the things we’re looking at is using a distributed object caching layer, such as memcached.  If you’re not sure what this technology does, the quick summary is that it is used to store commonly accessed data in memory on your servers. One of the most common uses is to cache results from database queries. 

memcached started it’s life at Danga Interactive to solve issues scaling LiveJournal at 20 million+ pageviews per day. It has a proven track record in the Unix world, and a fairly significant base of knowledge on what works and various workarounds and solutions.

Whilst memcached is from Unix, there are also Windows based ports of the server, and also .NET clients so using it in our environment shouldn’t be an issue from the technical side. 

Recently Microsoft also announced their entry into this space with a project code named Velocity. It’s pretty similar to memcached, but also has some additional functions allowing things like Tagging and Regionalising (Partitioning) data.  There’s also more support at the moment for different cache expiry methods, and the roadmap includes additional redundancy bits too.

For anyone who is considering how their applications will scale up, there’s plenty more to read on the subject.

Dare Obasanjo has a post from July 2007 about memcached on Windows, and also more recently about Velocity.  Scott Hanselman (Who I’m happy to say is coming to Tech.Ed Australia 2008!) has a podcast up about Velocity, talking with Anil Nori – one of the smart fellows responsible for Velocity.

I’ll write some more on this as we progress down the build of this application.

So, today I discovered an issue which related to me doing two calls something a little like this:

- Execute dc.sp_Proc1
- If some condition exists, execute dc.sp_Proc2, and then Execute dc.sp_Proc1 again with the same parameters.
- Insert some records into the database.

The problem is, the first time you execute the sproc, it caches the result. This would be okay for most instances, but in mine – I’m actually after the updated result.

A quick bit of googling revealed this post by Chris Rock. This approach of “turn off object tracking” works Ok if you don’t need to insert records on that Data Context.

My quick, dirty, and (possibly) really wrong approach was just to spin up a new Data Context, and re-execute that sproc.

I promise I’ll find a more sane way of fixing this :)

With many web 2.0 applications there’s a basic three-tier architecture..   In our case the client is a Flex 3/Caringorm application, the Services are WCF/ASP.NET Web Services, and the Database SQL 2005.

One of the typical approaches to creating Web Services for this type of system is to use a CRUD type pattern. That is: all methods are based around either Creating, Retrieving, Updating, or Deleting records.  In most usually done on a per-table basis, and means that you’re effectively making the Web Services a HTTP enabled SQL client.

For our situation, this wasn’t really appropriate for a number of reasons, including complex relationships between tables, and a need to reduce the amount of network traffic.

Another concern, although relatively minor, is to reduce the amount of work needed by the Flex team to implement the Web Services. 

Ideally, we wanted to be able to share business objects as widely as possible, to reduce the amount of rework needed by everyone involved in implementing the interfaces.

Therefore we chose to go with task, or semantic based methods, and using the objects as needed by the Flex front-end.  The work of validation, and mapping to appropriate tables would be done by the Web services.

An example of this might be that a Document had many properties, such as Media Items (pictures, video, etc), Tags, Authors, etc.  However, within the database there might be a necessity to track Document Versions, What versions are Live, the relationships between Documents, Document Versions and Media Items. 

Because the objects that I needed to send/receive didn’t match the objects that needed to be saved in the database, I needed to write a lot of “left hand/right hand code”: ServiceDocument.Property =   SQLDocument.Property.  Most of this was fairly simple code to write, but tracking the places where this takes place can be grow to become quite a challenge when the solution grows to dozens of tables.

This is an approximate list of what I need to do to add a property to one table:

  • Add the Property to the Service Types
  • Add conversion pieces to transpose the Service Type to/from the LINQ to SQL Object equivalents.
  • Add the column to the Table in the Database Model for LINQ to SQL
  • Add the column to all Stored Procedures in the Database Model which reference this, removing and re-adding them if this means new properties too.  Don’t forget to ensure the return types on the re-added Stored Procedures are set correctly.
  • Add the columns to the actual Stored Procedures, update parameters, etc
  • Add the column to the actual Table

I can only imagine the Version Control conflict chaos that would ensue if you had several people making these changes concurrently.

I highly recommend grouping changes into a per-table basis, because it can take a while to go through all the additional pieces you have referencing the LINQ to SQL and Service Type object equivilents.

This is the first in (hopefully) a series of quick things I’ve picked up whilst tackling the previously mentioned project

So, I have a table something like this:

CREATE TABLE [dbo].[Product](
 
[ProductID] [int] IDENTITY(1,1) NOT NULL,
 
[Name] [nvarchar](100) NOT NULL,
   [Price] [int] NOT NULL,
    [LastSaveTimestamp] [datetime] NOT NULL CONSTRAINT [DF_Product_SaveTimestampDEFAULT (getutcdate())
) ON [PRIMARY]

The key here is the default value on the column: LastSaveTimestamp.

If I then try to, say insert a new column into this table, for example using this code:

  DatabaseContext dc = new DatabaseContext();
  Product product = new Product();
  product.Name = “test product”;
  product.Price = 50;
  dc.Products.InsertOnSubmit(product);
  dc.SubmitChanges(System.Data.Linq.ConflictMode.FailOnFirstConflict);

Then I’d get an exception like:

System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM..

The fix is actually really simple – In the table designer / DBML, you need to tell it that the column is auto-generated. Unfortunately this doesn’t seem to be automatically detected. It’s one of a few ‘just plain weird’ situations. 

AzamSharp has the fix details, with a handy-dandy screenshot over on his blog.

0 comments

Two WCF Stumbles

Here’s two things that caused me a bit of pain when working with WCF. Hopefully these pointers should help you get back to more productive things.

No Output when returning Serialized / Serialised objects.

I had been working on adding a significant number of methods and properties to a series of classes, and when I went to test the service I got literally no output.

Debug points indicated that all properties were there, and valid – but still WCF wasn’t returning anything. There was no exceptions  being returned to the client.

The best tool for debugging these sorts of solutions is to first of all enable Tracing and MessageLogging.  This is done via the WCF Service Configuration Editor, on the Diagnostics tab. 

Once you’ve done that, and re-run the projects – you can open up Service Trace Viewer.  For me under Visual Studio 2008, this was under Microsoft Windows SDK v6.0A > Tools.

image

This tool then lets you open up the trace log generated in your solution directory, and see all the activity that’s been happening.

debugging-wcf-services

From here, it was just a matter of scrolling down to the activity entry that had the yellow hilighting (indicating a warning), selecting it – then clicking on the Errors.

For me, the first time this happened to me, it was because I had stuffed up the DataMember Name values. It has also occurred for other reasons, such as a property not being populated, when I had specified that it was both required, and also that it could not emit a default value.

Can’t get mex to work

No, this isn’t a misguided racial slur. I was having issues setting up the mexHttpBinding on an ASP.NET AJAX WCF Service.

The solutions all point towards the same thing, that you need to set up an endpoint, and set the contract to IMetaDataExchange, then set the behaviour to have <serviceMetadata />. Except that it just wouldn’t let me add that property to my endpoint behaviour, and whenever I changed it to a service behaviour it would then not allow me  to set the other properties I needed for that.

Well, perhaps I’m particularly slow – but hopefully this pointer will help someone else.

1: Create a NEW service behaviour:

<serviceBehaviors>
  <behavior name="MyServiceBehavior">
    <serviceMetadata
      httpGetEnabled="true"/>
    <serviceDebug
     includeExceptionDetailInFaults="true"
     />
  </behavior></serviceBehaviors>

2: Add a new endpoint to your  existing service

<endpoint
   address="mex"
   binding="mexHttpBinding"
   bindingConfiguration=""
   contract="IMetadataExchange" />

3: Add the behaviorConfiguration you added in Step 1 to the Service (NOT the endpoint).

<service
  behaviorConfiguration="MyServiceBehavior"
  name="MyProject.MyService">

I kept trying to add it to the endpoint, and failing miserably. So much time spent back-and-forth on this!

 

That’s it for this instalment of “WCF is great, but I wish the config was a bit easier to understand”. Stay tuned for more exciting episodes!

I’m looking for a few folks to group together to get a dedicated Windows server.

Server Details:

  • CPU: Intel Xeon 3060 (Dual Core)
  • RAM: 2GB
  • HDD: 2x 250GB (not RAID)
  • Network Port: 100Mbit
  • Bandwidth Quota: 2500GB per month
  • OS: Windows Server 2003 R2  (x32)
  • Other Software: .NET 1.1, plus .NET 2.0 to  .NET 3.5.  MS SQL Server 2005 (Express),

The server would be hosted by The Planet (unless you know of a better place?) in the US.

Because there’s 10 IPs allocated, the way I thought it would be set up would be to have one IP for any shared web hosting, etc – plus remote access in. And one IP would be dedicated to a Linux VM Server (for any apache + php + mysql things you want to run).

Then the rest of the IPs would be split up between the  folks sharing the server – for any other things you wanted to do (FTP server,  etc)

Bandwidth, Diskspace and RAM wouldn’t be strictly controlled, but if the performance of the server is suffering, we’re out of disk space, or we’ve got an over-usage charge, then those who’re using far more than their quota will need to pay up (for bandwidth) or reduce their usage (for diskspace and RAM)  

You’d also be expected to know how to use manage IIS properly, and if you’re hosting stuff on the Linux VM, Apache too.  Oh, and also how to use common sense not to stuff with other people’s settings without their OK.

I shouldn’t need to mention this, but you’ll also be responsible for ensuring that you’re not doing anything illegal under US or Australian laws. So – no torrent downloads, thanks.

Total cost per month for the server setup above is USD$230/month. I’m prepared to pay about USD$80/month, so I’m looking for 3-4 people willing to split about USD$150/month.

So, for about $10/month you’d get an allocation of about 100GB of bandwidth quota, and 20GB/disk space (10GB per drive).  IPs would be divvied up based on % of contribution, after I’ve got enough people onboard, but you’d get at least one IP.

So, if you’re interested – add me on MSN – will@hughesfamily.net.au and let me know.

Update: I now have two other people who’re onboard, and another who’s interested…  I need another four people who’re interested in putting in about USD$30/month each.

If that doesn’t happen, then I guess we’ll have to look at trying to get a smaller server, but this is pretty much as small as it gets before things stop being useful.