4

I am using WCF REST service (GET method) to retrieve my EF4 POCOs. The service seem to work just fine. When I query the uri in my browser I get the results as expected.

In my client application I am trying to use WCF REST Starter Kit's HTTPExtension method - ReadAsDataContract() to convert the result back into my POCO. This works fine when the POCO's navigation property is a single object of related POCO. The problem is when the navigation property is a collection of related POCOs. The ReadAsDataContract() method throws an exception with message "Object reference not set to an instance of an object."

Below are my POCOs.

[DataContract(Namespace = "", Name = "Trip")]
public class Trip
{
    [DataMember(Order = 1)]
    public virtual int TripID { get; set; }

    [DataMember(Order = 2)]
    public virtual int RegionID { get; set; }

    [DataMember(Order = 3)]
    public virtual System.DateTime BookingDate { get; set; }

    [DataMember(Order = 4)]
    public virtual Region Region { // removed for brevity 
    }
}

[DataContract(Namespace = "", Name = "Region")]
public class Region 
{
    [DataMember(Order = 1)]
    public virtual int RegionID { get; set; }

    [DataMember(Order = 2)]
    public virtual string RegionCode { get; set; }

    [DataMember(Order = 3)]
    public virtual FixupCollection<Trip> Trips { // removed for brevity
    }
}

[CollectionDataContract(Namespace = "", Name = "{0}s", ItemName = "{0}")]
[Serializable]
public class FixupCollection<T> : ObservableCollection<T>
{
    protected override void ClearItems()
    {
        new List<T>(this).ForEach(t => Remove(t));
    }

    protected override void InsertItem(int index, T item)
    {
        if (!this.Contains(item))
        {
            base.InsertItem(index, item);
        }
    }
}

And this is how I am trying retrieve a Region POCO.

static void GetRegion()
    {   
        string uri = "http://localhost:8080/TripService/Regions?id=1";
        HttpClient client = new HttpClient(uri);

        using (HttpResponseMessage response = client.Get(uri))
        {
            Region region;
            response.EnsureStatusIsSuccessful();
            try
            {  
                region = response.Content.ReadAsDataContract<Region>(); // this line throws exception because Region returns a collection of related trips
                Console.WriteLine(region.RegionName);                    
            }
            catch (Exception ex)
            {
               Console.WriteLine(ex.Message);
            }
        }
    }

Would appreciate any pointers.

muruge
  • 4,083
  • 3
  • 38
  • 45
  • Show code of your POCO class. Also check that collections are included in response (use Fiddler) and describe how do you retrieve object and loaded collections (are you using dynamic proxies, lazy loading, etc?). – Ladislav Mrnka Mar 02 '11 at 10:27
  • @Ladislav Mrnka: I have edited my question to add the code that I am using. – muruge Mar 02 '11 at 15:28
  • @Greg Sansom: Thanks for sharing that link. – muruge Mar 02 '11 at 15:29
  • I wonder how can this even serialize itsef. It contains circular references. – Ladislav Mrnka Mar 02 '11 at 16:20
  • @Ladislav Mrnka: How do I go about it then? The collection is included in the response when I query the service from a browser. – muruge Mar 03 '11 at 17:58
  • With circular references? You can't have DataMember attribute on both navigation properties pointing to each other or you must add IsReference=true to both DataContracts. – Ladislav Mrnka Mar 03 '11 at 18:01
  • @Ladislav Mrnka: I have already tried both the options you have mentioned and it throws the same error. – muruge Mar 03 '11 at 18:28

3 Answers3

2

another thing to check is if proxy generation & lazy loading are breaking your operation that is querying and returning results. The fact that your properites are all marked virtual would cause proxies to be generated and lazy loading to be enabled. When you searialize with those two features working, it wreaks havoc on the serializer.

What I do in this case is in the operation that returns the data I turn those off e.g., (note I am typing from memory without the aid of intellisense...)

public List GetSomeTrips { context.ContextOptions.LazyLoadingEnabled=false; contxt.ContetOptions.ProxyGenerationEnabled=false;
return context.Trips.ToList(); }

Julie Lerman
  • 4,602
  • 2
  • 22
  • 21
1

As I can not comment to the question. Have you tried setting public virtual FixupCollection Trips

as a properity with the standard get; set;

Ive had difficulties with datacontracts and defining custom getter and setters. That logic should be in the entity / object itself as it will be overridden.

That has been a fix for a ton of things for me.

Dimentox
  • 189
  • 6
0

This may already be in your POCOs just not included - do they have constructors? You could try

public Region(){
    this.Trips = new FixupCollection<Trip>();
}

That may solve the null ref error. Same in FixupCollection if that is your class.

cofiem
  • 1,384
  • 1
  • 17
  • 29