Wednesday, March 31, 2010

The remote server returned an error: NotFound. - Yet Another Cause And Solution

Having encountered this error while working with Silverlight and WCF the number of potential fixes I found while searching was overwhelming. To get an idea of just how many causes there are for this error take a look at this thread. None of the solutions appeared relevant to my application, so I decided to dig further by setting includeExceptionDetailInFault in the service's web.config to true. This yielded no new information so I moved on to observing the HTTP traffic with Fiddler. To my surprise the ASP.NET development server was closing the connection with no response. Even stranger was the fact that this behavior was only exhibited by one of my operation contracts when certain parameters were passed to it--the rest of my operation contracts worked fine! Naturally I stepped through the problematic method and everything appeared to be working. Seeing this I knew that the problem had to be in the data contract returned, so I resorted to trial and error: one by one I tested the service with different data members nulled. Finally I discovered the data member causing the issue and the actual problem: circular references. After setting the IsReference property of my data contract to true the CommunicationException disappeared. Below is a sample WCF service that displays the aforementioned issue along with comments noting the fix.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace NotFoundWcfService1
{
// Setting the IsReference parameter of this
// attribute to true eliminates NotFound error
[DataContract]
public class Item
{
[DataMember]
public List<Category> Categories { get; set; }
}

[DataContract]
public class Category
{
[DataMember]
public List<Item> Items { get; set; }
}

[ServiceContract]
public class Service1
{
[OperationContract]
public Item GetItem()
{
Item c = new Item()
{
Categories = new List<Category>()
{
new Category()
{
Items = new List<Item>()
}
}
};

// Commenting this out makes the operation
// contract appear to work. Tricky!
c.Categories[0].Items.Add(c);

return c;
}
}
}

5 comments:

  1. Why would you add an object to its own children? The code "should" fail, unless I'm missing something, and changing a setting to bypass it doesn't seem appropriate.

    If there is some clever reason for this, I'm curious to know what it is.

    ReplyDelete
  2. Circular references occur all the time, especially in Linq-to-SQL generated classes. Keep in mind this sample is as simple as possible for demonstration purposes--there's just enough there to recreate the error. Also the DataContractAttribute.IsReference property exists for this very purpose; as far as I know it has no other use.

    ReplyDelete
  3. Wow, thanks a lot, this post saved the day. Given the cryptic "Not Found" error, along with failing to see the SOAP response for WCF with Fiddler (giving the error "The server did not return a response for this request" for the request), I thought I was lost in finding an answer, so thanks again, hope this posts helps more people.

    ReplyDelete