Encoding, MemoryStream, XDocument

Edit: As mentioned in the comments, an easier alternative to what I show below is to directly use the XDocument.Parse call, ie.

XDocument = XDocument.Parse(xmlString);

Just recently I had one of those tasks where you are given a string that is xml.  In this case it was xml from a WebClient call asynchronously.  So the result coming back was a string.

There are several classes that work well to do this task, and each is probably a topic of it’s own.   Personally, Linq in all it’s flavors is one of my favorite things about the C# language.  Take for example the XDocument class- it allows us to use XPath style queries using a Linq syntax.

When you look at XDocument, you’ll notice it has the XDocument.Load() function with it’s various overloads.  One option is a string, however, this is a path to an xml file.  That leaves us with Streams, TextReader, XmlReader, etc…

So, we have a string, that is xml, we want to load it into a XDocument that takes a XDocument.Load(Stream).

I’ve decided to use a MemoryStream, as a MemoryStream will create a stream that is in memory vs. on disk, etc…  What we find out though, is our MemoryStream is expecting an array of bytes! 

In order to get our string into an array of bytes, we will need to use the C# Encoding class.  There are many different of encoding, which you can check out in the Encoding class.  In this case, I’m going to use UTF8Encoding.  If your new to Encoding, or want to learn more, I suggest reading the MSDN topic ‘Character Encoding in the .NET Framework’. 

So our Encoding.UTF8.GetBytes(string) will take our xml string and produce our byte array for the MemoryStream – we’ll take that stream and give it to our XDocument.Load to populate our XDocument object.

string xml = ...some xml...
byte[] bytes = Encoding.UTF8.GetBytes(xml);
using(MemoryStream stream = new MemoryStream(bytes))
{
    XDocument document = XDocument.Load(stream);
}

I’m not going to go into too much detail on linq to xml here but just to show what can be done with the XDocument will help close the topic – ie. pulling out all the titles in an Atom feed:

var entries = from feed in doc.Root.Elements()
    .Where(i => i.Name.LocalName == "entry")
        select new Feed
        {
            Title = feed.Elements()
                .First(i => i.Name.LocalName == "title")
                .Value
        };
return entries.ToList();

Hope this helps next time you need to work with a string of xml in C#  Smile

Advertisements

WCF RESTFul Service with Entity Framework CodeFirst

I’m going to try to kill two birds with one stone in my post today.  My first goal was to setup a WCF RESTful service – but spice it up a bit to show off some Entity Framework CodeFirst goodness at the same time.

This isn’t some sort of ‘best practices’ post – more of a quick (hopefully) and dirty sample walkthrough for anyone interested in doing this as well.

This sample will be done with Visual Studio 2010, .NET framework 4.0.

The first step is to setup a WCF REST Service Application.  I used, what I think, is an out of the box C# template, under ‘Web’:

image

I used the default name it provided (‘WcfRestService1’).

The default template will create some boilerplate code for us.  I recommend as well to goto the project settings for the service and set the port to be 2023. 

The WCF RESTFul service provides an operations help page to view the available endpoints:

http://localhost:2023/Service1/help

image

Clicking on the method ‘GET’ and/or ‘POST’ will highlight the services available.  You might see more than these two items at this time.  But first I’m going to make some changes and introduce Entity Framework Code-First.

Let’s go ahead and get our Code-First setup before we refactor the service.  Assuming you have Nuget installed (if not, go get it!), inside the Package Manager Console you can easily install Code-First.  Type into the console the following:  Install-Package EFCodeFirst.

As of this writing I’m using version 0.8.  You should see something similar to the following:

 

PM> Install-Package EFCodeFirst
Successfully installed 'EFCodeFirst 0.8'.
Successfully added 'EFCodeFirst 0.8' to WcfRestService1.

Great – we now have EFCodeFirst, it will add some assemblies to the mix. 

The default WCF RESTful template included a class ‘SampleItem’, so we will use that – it takes advantage of the Code-First convention over configuration by providing an ‘Id’ field – so it makes like easy for us.  If you don’t’ it, the class looks like the following:

public class SampleItem
    {
        public int Id { get; set; }
        public string StringValue { get; set; }
    }

[ServiceContract]
    public interface IService1
    {
        [WebGet(UriTemplate = "")]
        List<SampleItem> GetCollection();

        [WebGet(UriTemplate = "{id}")]
        SampleItem Get(string id);

        [WebInvoke(UriTemplate = "", Method = "POST")]
        SampleItem Create(SampleItem instance);

        [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
        SampleItem Update(string id, SampleItem instance);

        [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
        void Delete(string id);
    }

[ServiceContract]
    public interface IService1
    {
        [WebGet(UriTemplate = "")]
        List<SampleItem> GetCollection();

        [WebGet(UriTemplate = "{id}")]
        SampleItem Get(string id);

        [WebInvoke(UriTemplate = "", Method = "POST")]
        SampleItem Create(SampleItem instance);

        [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
        SampleItem Update(string id, SampleItem instance);

        [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
        void Delete(string id);
    }

[ServiceContract]
    public interface IService1
    {
        [WebGet(UriTemplate = "")]
        List<SampleItem> GetCollection();

        [WebInvoke(UriTemplate = "", Method = "POST")]
        SampleItem Create(SampleItem instance);
    }

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class Service1 : IService1
    {

        public List<SampleItem> GetCollection()
        {
            using (ItemContext context = new ItemContext())
            {
                return context.SampleItems.ToList();
            }
        }

        public SampleItem Create(SampleItem instance)
        {
            using (ItemContext context = new ItemContext())
            {
                context.SampleItems.Add(instance);
                context.SaveChanges();
            }
            return instance;
        }

        public SampleItem Get(string id)
        {
            using (ItemContext context = new ItemContext())
            {
                var item =
               (from c in context.SampleItems
                where c.Id == Int32.Parse(id)
                select c).FirstOrDefault();

                if (item == null)
                {
                    throw new WebFaultException(HttpStatusCode.NotFound);
                }

                return item;
            }
        }

        public SampleItem Update(string id, SampleItem instance)
        {
            using (ItemContext context = new ItemContext())
            {
                 SampleItem sampleItem =(from c in context.SampleItems
                 where c.Id == Int32.Parse(id)
                 select c).FirstOrDefault();
                sampleItem = instance;
                context.SaveChanges();
                return sampleItem;
            }
        }

        public void Delete(string id)
        {
            using (ItemContext context = new ItemContext())
            {
                SampleItem sampleItem = (from c in context.SampleItems
                                         where c.Id == Int32.Parse(id)
                                         select c).FirstOrDefault();
                context.SampleItems.Remove(sampleItem);
                context.SaveChanges();
            }
        }
    }

Just a quick overview here – we can use Linq style queries to handle all our query needs.  You can see from the GetCollection call above that the context exposes the SampleItems DbSet that is queryable. 

I added one piece to the above that is a nicety of working with REST.  I made a decision to throw a ‘404’ not found exception on the Get call.  If a value is passed in that is not valid, it should show a 404 response back.

ie.

throw new WebFaultException(HttpStatusCode.NotFound);

I hope this provides some insight into use the WCF RESTful services along with EF Code First.

Craftmanship vs. Product/Tech Knowledge

More and more I see both in job request, and in general overall conversations – that MS (or probably any technology) developers tend to get really wrapped around what technology they are using vs. understanding the core software development/craftsmanship.

The common thing I will hear is ‘do you know Sharepoint’, or ‘do you know MVC’, ‘do you know Unity’, etc…   Quite honestly, I think any developer who has a firm grasp of software principles and patterns can easily pick up and learn these technologies.

On the flip side, what I tend to notice though is that these solutions are typically cobbled together and not really designed properly.  This leads to a tangled code mess, lack of good testing, etc… and the projects quickly become unwieldy.

I’ve seen this both in a few webform projects as well as a silverlight project.  The concentration was on ‘using ajax’ or ‘knowing how to use a GridView’ – and meanwhile the entire application was very poorly constructed  – with 1000 line code behind files and data access inside the code behind.  There wasn’t an SRP or cohesion in the code base.  The result was buggy and hard to maintain code.  Performance issues crept in from every side.  Whether or not you use webforms or not, there is such a thing as proper construction and design patterns.  Within a few moments of inspecting the code, I saw three or four different signs of how some composition and layering would help.

The other example was with Silverlight.  The core focus was on ‘RIA Services’ and ‘Telerik’ and ‘MEF’.  All very important tools – and yet, the lack of layering, no DTO, etc… was a cause of problems.  One database change would wreck the entire app as this code generated entities were used all throughout the code.   This was done to be ‘RAD’ and yet by not properly separating out these features it caused it to be brittle and difficult to manage.  Checking in a database change caused build errors across the entire app.

The one positive was the use of MVVM.  That said, I think knowing MVVM, composition, design patterns, loose coupling,  how to write tests, etc… are much better things to be grasping than ‘do you know Sharepoint’ or ‘Silverlight’.  Understanding source control systems – like merging, branching, etc… are far more useful than just ‘knowing git’ or ‘knowing TFS’.

I encourage developers to disassociate themselves from being ‘specialists’ in a particular technology and really understand software craftsmanship.  Not just ‘knowing’ what SOLID is – but applying something like SOLID even when working with whatever technology or tool your using.  Not all tools are bad, I might add, some tools help at least spot issues and make developers think – ie. FXCop – I’ve been on a product using it, and it can be very particular about the syntax and code use.  Certainly it might slow down a sloppy developer, yet it means the rest of the team is working with a code base that has checks and balances.  The main premise is that we are building code with craftsmanship at it’s core, regardless of what web or desktop technology was chosen to be used.

Quite honestly, the best possible development environment is one where you have some senior staff members who can do code reviews, discuss proper design, etc…  Projects that attempt to cut corners and not have these valuable resources in place, end up really shooting themselves in the foot.  I hear sometimes the same old adage, ‘well we can’t afford to spend time writing tests’ – and quite honestly, I think the answer is ‘you can’t afford NOT to be writing tests’.  Tests uncover design flaws and bugs – they are proactive – they provide a place to review how the code works, etc…

I’ll last just suggest that perhaps the next book you pick up might be something like ‘Clean Code’ by Bob Martin vs. some book on ‘Silverlight’, or whatever the latest greatest fad is.  The principle and concepts of understanding how to write good clean code will take you much further than knowing just a particular technology.   If you want to be a specialist, specialize in being a software craftsman.   Lastly, be careful wrapping your head in a particular technology and throwing out your good sense of building software. ie. many of these API’s are not designed to be just exposed and used directly.  Encapsulate what varies, maintain SRP, look for flaws in the design that later will lead to a more cohesive and manageable code base for you and your team.