3
votes

Are there any extra configurations that are necessary to get ServiceStack to deserialize a JSON request into an appropriate dynamic object? I have compiled the Net40 version of the ServiceStack.Text library that includes the DynamicJson class and have added it to my project(s). I have a standard request and response DTO. The request DTO has a dynamic (ExpandoObject) public property. Once inside my service operation, the dynamic property does not seem to be serialized properly. On the client side, the JSON is deserialized perfectly.

Here is what I am working with:

Request, Response and Service

[Route( "/foo/subscriptions", "POST")]
[DataContract( Name = "UpdateSubscription")]
public class UpdateSubscriptionMessage 
    : IReturn<UpdateSubscriptionMessageResponse>
{
    dynamic _subscription;

    public UpdateSubscriptionMessage() {
        _subscription = new ExpandoObject();
    }

    [DataMember( Name = "subscription" )]
    public dynamic Subscription { 
        get { return _subscription; } 
        set { _subscription = value; } 
    }
}

[DataContract( Name = "UpdateSubscriptionResponse")]
public class UpdateSubscriptionMessageResponse
{
    [DataMember( Name = "success" )]
    public bool Success { get; set; }

    [DataMember( Name = "subscriptionId" )]
    public int Id { get; set; }
}

public class SubscriptionTestService : BaseService
{
    private IAdminComponent _adminComponent;

    public SubscriptionTestService() : this (null) { }

    public SubscriptionTestService(IAdminComponent adminComponent) {
        _adminComponent = adminComponent;
    }

    public UpdateSubscriptionMessageResponse Post( UpdateSubscriptionMessage request)
    {
        var response = new UpdateSubscriptionMessageResponse();

        dynamic subscription = request.Subscription;

        return response;
    }
}

JSON POST Body

{ 
  "subscription": 
  { 
    "name":"foo subscription title", 
    "description":"the description" 
  }
}

After posting the JSON and stepping into my service operation, a quick peek at the request shows the dynamic Subscription as a string. Can ServiceStack serialize the JSON request into a dynamic?

Peek at request.SubscriptionVisualizerQuickWatch confirms the type is a string

1
I'll be following this question, because I need the answer for my own work. Can you point me at the 'Net40 version of the ServiceStack.Text library' you're using?Pauli Price
@marfarma You will need to pull the ServiceStack.Text source. Once you have it, you will find a ServiceStack.Text.Net40 .sln. I compiled from there and added ServiceStack.Text assembly to my project(s).Allan

1 Answers

2
votes

You may have seen this announcement:

The next major v4.0 will also be a "breaking-release", with new features protected under an "AGPL/FOSS License Exception" and include a number of breaking changes that have built up over time, including upgrading all projects (to .NET 4+), major code and NuGet package re-factoring, clean-up and removal of deprecated code, better consistency / simplification of some concepts and implementation of some roadmap features I've been wanting to add but never had time for. Fixes and releases will continue to v3.x and be maintained in a separate v3 branch until v4.0 comes out of beta.

As there's no reason to fix dynamic object support in the current 3.x branch, which doesn't support .Net4.0, the answer is 'No, ServiceStack can't serialize the JSON request into a dynamic.'

You can always fork the code and add the missing support in a ">= .Net4.0 only" branch. A pull request with that fix might not be accepted into the 3.x core, but might be welcome for the coming v4.0 release.

Alternately, there are hooks for custom serialization functions in ServiceStack's JSON Serializers, JsConfig<T>.RawSerializeFn and JsConfig<T>.RawDeserializeFn. In combination with this answer on serializing ExpandoObjects in .Net 4.0, that would allow you to add ExpandoObject serialization support without having to 'fix' the core code.