3

So I have a couple of tables in a linq-to-sql dbml file:

my dbml layout

I have set up a WCF REST get endpoint to user. I cannot get it to pass back a JSON structured like this:

{
    ID: '123',
    Username: 'fdsaf',
    ...
    Role: 
    {
        ID: '123',
        ...
    }
}

If I set the DBML serialization mode from "None" to "Unidirectional," I can get the user object without the role. If I leave the serialization mode on none and remove the association, I can also get the user object. As a sanity check, I can also get the role with no user. As soon as I try to include a reference, it attempts to serialize twice (in the debugger) and I get the following error after what appears to be a successful function call on the client:

client error

Additionally, I can get what I'm looking for if I open the association and turn the child property access to internal. However, I will sometimes want to pass back roles with collections of users, so this will not be sufficient.

insufficient workaround

I include this piece of information because it seems to indicate that the serializer is trying to serialize User > Role > User > Role ... etc., which is obviously insufficient. But there must be a middle ground between a circular and a zero-level-deep reference.

Code below:

using (DataContext context = new DataContext())
{
    DataLoadOptions opts = new DataLoadOptions();
    opts.LoadWith<User>(u => u.Role);
    context.LoadOptions = opts;

    return context.Users
        .Where(u => u.ID == id)
        .Where(u => u.Hash == hash)
        .FirstOrDefault();
}
Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90

1 Answers1

1

I would create a mapped object instead of a user and give it an array of roles, Mainly because you are passing back a raw data object which includes the password and raw hash of a user. You can then hide these in the mapping

Have one model for each, UserObject with a child of Roles and a RolesObject with a child of User.

Alternatively, have a property that you can serialize on each that will return pseudo objects so roles could be an array of id/strings and so could users (then you ignore serialization on the relationship and serialize that instead, no circular reference problems)

finman
  • 545
  • 6
  • 16
  • This almost makes using linq-to-sql useless, though. – Matthew James Davis Oct 08 '13 at 16:54
  • 1
    Not really, you are querying a relational database which if you want to serialize out everything will give you circular references. The xml cannot have circular references due to the nature of the doc type, so you have to get creative in how you pass the items through, to include children they must be orphaned, unless you serialize a different item without relationship info your object will have links to the hierachy and throw a wobbly EntityFramework will do the same issue, in fact I'm pretty sure almost all ORMs will. It's not a library specific issue. You get the same issue with SOAP – finman Oct 11 '13 at 15:17
  • You need a specialised serialised object to do this (you can retain Ids fine, but the serialized object cannot contain a reference to the parent object as you do currently with the user/role) Linq2SQL may have a way to add attributes to the parent/child to not serialize the item but I'm not aware of it. A disconnected mapping class lets you avoid exposing sensitive items as well as control exposed relationships for each set, you would return inactive roles that are linked. To put it simply... you don't use linq to sql to serialize an objects as it's a query tool – finman Oct 11 '13 at 15:23
  • I was just hoping the simple logic to avoid circular references in the very obvious use case would have been included in the default json serializer: When serializing this child, do not include a reference to this parent. JSON.net includes this logic, but I can't figure out how to point WCF to use JSON.net as the default serializer. – Matthew James Davis Oct 11 '13 at 16:02
  • You set the default endpoint behaviour to Json. There is an example here: http://stackoverflow.com/questions/12902319/is-it-possible-to-set-the-request-response-format-in-web-config – finman Oct 21 '13 at 14:36