4
votes

I would like to post a JSON object to my service stack service and use a dynamic property in the request DTO. All approaches I have tried so far leave the object being a NULL value.

The javascript code I use:

$.getJSON(
  "/api/json/reply/Hello",
  {
    Name: "Murphy",
    Laws: {
      SomeProp: "A list of my laws",
      SomeArr: [
        { Title: "First law" },
        { Title: "Second law" },
        { Title: "Third law" }
      ]
    }   
},
function(data) {
    alert(data.result);
  }
);

The DTO to receive the request:

public class Hello
{
    public string Name { get; set; }
    public dynamic Laws { get; set; }
}

I also tried to use an object and JsonObject instead of dynamic in the DTO.

To be complete, here's the service too:

public class HelloService : Service
{
    public object Any(Hello request)
    {
        return new HelloResponse { Result = "Hello, " + request.Name };
    }
}

Murphy comes through in the Name property without any problems, but the Laws property remains NULL.

In the end, I want to somehow iterate (using reflection?) over the Laws property and get all the contained properties and values.

I cannot use a typed DTO here, because I don't know the JSON of the Laws property at development time (and it can change quite frequently).

Thanks for any help!

1

1 Answers

5
votes

The .NET 3.5 library builds of ServiceStack on NuGet doesn't have native support for the .NET 4.0+ dynamic type. You can pass JSON into a string property and dynamically parse it on the server:

public object Any(Hello request)
{
    var laws = JsonObject.Parse(request.Laws);
    laws["SomeProp"] //
    laws.ArrayObjects("SomeArr") //
}

Otherwise You can use Dictionary<string,string> or if you specify in your AppHost:

JsConfig.ConvertObjectTypesIntoStringDictionary = true;

You can use object which will treat objects like a string dictionary.

Otherwise dynamic shouldn't be on the DTO as it's meaningless as to what the service expects. You could just add it to the QueryString. You can use the JSV Format to specify complex object graphs in the QueryString, e.g:

/hello?laws={SomeProp:A list of my laws,SomeArr:[{Title:First Law}]}

Note: the spaces above gets encoded with %20 on the wire.

Which you can access in your services with:

public object Any(Hello request)
{
    var laws = base.QueryString["laws"].FromJsv<SomeTypeMatchingJsvSent>();
}