find a location for property in a new city
Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Wednesday, 16 March 2011

WCF REST: How to get a Request header

Again WCF REST is proving secretive when it comes to getting at your Request Headers.

You can get at any custom Request headers that you may be expecting via the IncomingMessageProperties off of the OperationContext in the same way as before when you were adding custom Headers to your response.

To do this you you can write something like this:
var request = OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
var version = request.Headers["ApiVersion"];

Update:

Actually, there is an easier way I found. Since this is in a REST service it is possible to use WebOperationContext which seems a lot more intuitive and concise:
var version = WebOperationContext.Current.IncomingRequest.Headers["ApiVersion"];

You will then have access to any expected Request Headers as a string.

More WCF REST:

Follow britishdev on Twitter

WCF REST: How to add a response header

I can't believe how difficult it is to add a response header to a response to a WCF REST service. It is so round the houses it really quite difficult.

Whatever happened to Response.Headers.Add from the friendly web code I'm so used to... Oh well, after scratching around for ages I finally found how:
var prop = new HttpResponseMessageProperty();
prop.Headers.Add("ApiVersion", "v1.0");
OperationContext.Current.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, prop);

I know you're kicking yourself, right? "That's so obvious..." Ridiculous - I'm starting to thing WCF REST wasn't made with the developer in mind.

Update:

Actually, there is an easier way I found. Since this is in a REST service it is possible to use WebOperationContext which seems a lot more intuitive and concise:
WebOperationContext.Current.OutgoingResponse.Headers.Add("ApiVersion", "v1.0");

More WCF REST:

Follow britishdev on Twitter

WCF REST: How to get the requested URL

Finding the Request.Url is a lot different from standard web work when working in a WCF REST context. It can be quite difficult to find the URL of the request in your WCF REST service.

I found you can do it with the following code:
var context = OperationContext.Current;
var requestedUrl =  context.IncomingMessageHeaders.To.PathAndQuery;

So there you are... enjoy.

More WCF REST:

Follow britishdev on Twitter

WCF REST: How to get an IP address of a request

It seems to be quite difficult to find the IP of the request when in the Context of a WCF REST service.

I found you can do it with the following code:
var props = OperationContext.Current.IncomingMessageProperties;
var endpointProperty = props[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
if (endpointProperty != null)
{
    var ip = endpointProperty.Address;
}

This seems overly verbose so you may want to consider putting this code into helper methods or a base class for re-use.

More WCF REST:

Follow britishdev on Twitter

Tuesday, 4 January 2011

How to POST to REST WCF web services with Fiddler

After making a set of REST web services with WCF I tested them by making requests with a browser. This is fine for GET requests however you will need some HTTP building tool such as Fiddler to test a POST, PUT or DELETE REST web service.

To begin with I have a WCF REST web service that intends for a Comment object to be POSTed:
[WebInvoke(UriTemplate = "comment", Method = "POST",
  RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
public Comment Comment(Comment comment)
{
    return comment;
}

The definition of Comment is simple:
[DataContract(Namespace = "")]
public class Comment
{
    [DataMember]
    public string Body { get; set; }
}

Note this namespace is very important as it will need to be specified in the XML sent in the request. Personally I set my DataContract with no namespace to save having to write it out in the XML every time.

Now open up Fiddler and lets get testing:

Create a POST to your REST service in Fiddler

  1. Go to the Request Builder tab in Fiddler.
  2. Set the verb to POST
  3. Set the URL to the one of your service
  4. Type "Content-Type: application/xml" into the Request Headers. (This is the bit that got be stumped for hours)
  5. Add your XML to the Request Body like <Comment><Body>colin</Body></Comment>

If you did give your DataContract a namespace other than blank as I did you will need to specify it in the XML of your Request Body. Such as: <Comment xmlns="MyNameSpace"><Body>colin</Body></Comment>

Happy testing!

Follow britishdev on Twitter

Wednesday, 15 December 2010

WCF Data Services for using Entity Framework over REST web services

I spent some time looking into WCF Data Services 4.0 (AKA ADO.NET Data Services & Astoria) as a way to expose our Entity Data Model (EDM) over an easy to create set of RESTful / OData web services. I decided to document my findings.

WCF Data Services 4.0 is service that provides a way of exposing an EDM over RESTful (OData) web services using WCF. It means that if you have an EDM already built, the work is essentially done. The EDM can be exposed using WCF Data Services so that it can be queried directly by the client.

How to begin

I successfully set up some WCF Data Services to expose a Comment part of my model. This helped me. I did find difficulty due to our use of POCOs instead of raw Entity Framework's generated code but I found a post that helped which told me about a weird hack that overrides the CreateDataSource into the Data Service:
public class CommentsService : DataService<SocialEntities>
{
    protected override CommentingEntities CreateDataSource()
    {
        var context = new CommentingEntities();
        var tracestring = context.CreateQuery<Comment>("CommentingEntities.Comments").ToTraceString();
        return context; 
    }
}

Consuming the web services

A client can now access the data by requesting URLs. E.g. http://api.mysite.com/CommentsService.svc/Comments to get a list of messages or http://api.mysite.com/CommentsService.svc/Comments(413L) to get the message with ID 413 (the L is for long since I use long instead of int)

The querying gets a lot more complicated than that too. See how to use your browser to query the data model

There are many SDKs out there to begin developing against your WCF Data Services from a number of popular platforms since it is simply using the OData protocol (e.g. JavaScript, PHP, Ruby, Java, Objective-C, .NET).

Restricting use

You can restrict the number of results to return when returning a list of entities to, say 5, so the client can't overload the server/bandwidth.

You can also restrict access to select parts of your EDM to calm your security nerves too:
public static void InitializeService(DataServiceConfiguration config)
{
    config.SetEntitySetAccessRule("Comments", EntitySetRights.AllRead);
}

Evaluating when to use WCF Data Services

So it does look like a great way to use the existing EDM to instantly have a set of RESTful web services to consume. However I think I would only use this if the developers of the web service client were have knowledge of the data and are expecting to get stuck into some code when consuming our data services.

If were internally designing our own Silverlight apps then this is great. However, expecting an external user to write sometimes complex queries to get to our data using all of our business rules (e.g. IsDeleted = false && SiteID = 21) is a little much to be expected I feel.

Conclusion

So great when providing RESTful web services to a handful of specific clients who have knowledge of your data and business logic. Not so great for making a friendly API for the masses based on a complex EDM as you cannot expect them to understand your business rules as well as you do.

I am not claiming authority on this topic. I am just discussing my findings so far in the hope that you may find this useful. If you have anything you think I have missed please feel free to comment.

Follow britishdev on Twitter

Monday, 22 November 2010

Adding service reference gives the system cannot find the path specified error

I got an "The system cannot find the path specified." error box pop up when I tried to add a WCF web service reference to my web project. Problem with Service References?

Every time I tried to add the service reference to another WCF service I had set up in another web project I kept getting "The system cannot find the path specified." pop up in an alert box in Visual Studio 2010.

Solution

Somewhere along the line I had deleted the "Service References" folder from the project folder I was trying to add the reference to. It is simply solved by creating an new folder (in Windows Explorer) in the correct location called "Service References". Problem solved

Follow britishdev on Twitter