How to test for key present using WCF Data Service Reference classes? RRS feed

  • Question

  • When I issue a query like

    Truck x = context.Trucks.FirstOrDefault(r => r.Id == "Tonka23");

    My client-side query uses FirstOrDefault meaning give me the first match or give me a null, but don't throw an exception.

    This use of FirstOrDefault fails at runtime with "Method not supported."  

    Hmph.  Ok, I can turn it around into a Where clause to do the same thing (why doesn't it do this internally?):

    Truck x = context.Trucks.Where(r => r.Id == "Tonka23").FirstOrDefault();

    I can see that this gets converted into a request URI of "http://localhost/svc/Trucks('Tonka23')"

    At runtime, this client side statement throws an exception because the server returns a 404 error.

    On the server side, I have a self-hosted WCF service running WCF Data Services 5.5. I have implemented "GetOne(string id)" to look up the given id in an internal dictionary and return the object.  If the id doesn't exist, it throws a KeyNotFound exception, which I convert in HandleException into a DataServiceException with an HttpStatus code of 404.

    If I change my server code to return null for an unknown id, an exception is still thrown by the WCF Data Services core for the null value and the service still returns 404. So the client code throws no matter what I do on the server. And given that the URI is requesting an entity by a key value that does not exist, I would think that 404 is the proper response from the server.

    The only workaround I've found is to change the Where clause to disrupt the key field pattern matching to prevent WCFDS from using the index uri and persuade it to use a $filter expression instead:  

    Truck x = context.Trucks.Where(r => r.Id == "Tonka23" || r.Id == "Tonka23").FirstOrDefault().

    This produces a Request URI like "http://localhost/svc/Trucks?$filter=Id eq 'Tonka23' or Id eq 'Tonka23'

    That query causes FirstOrDefault on the client to behave correctly - to return the target object if it exists, or return null if it does not exist, and not throw an exception.

    How do I achieve the FirstOrDefault semantic using WCF Data Service Reference generated proxy classes without using this where clause hack? Is there a way to turn off the key field pattern matching?  Does the server need to return something special for WCF Data Services Client to behave correctly?


    Tuesday, July 9, 2013 12:57 AM


  • Solution:  

    svc.IgnoreResourceNotFoundException = true;

    Considering that the default behavior breaks the semantic of FirstOrDefault(), why isn't this set to true by default?


    • Marked as answer by Danny Thorpe Tuesday, July 9, 2013 9:26 PM
    Tuesday, July 9, 2013 9:26 PM

All replies