1

in the rest service i am emulating the same as another product, json is GET/POSTed in web form or query string parameters.

My request DTO has another DTO object as a property for the json

I can add a RequestFilter to deserialize the form parameters if it is POSTed, but if GET is used with json in a query variable the service stack code will throw an "KeyValueDataContractDeserializer: Error converting to type" exception in StringMapTypeDeserializer.

In StringMapTypeDeserializer it gets a parse function for the properties of the DTO. Is there anyway of adding something to JsvReader.GetParseFn(propertyType); to handle the de-serialization of my JSON?

Or some other way of adding parsing for this query parameter? without doing a custom handler.

thanks

Damian S
  • 213
  • 1
  • 11

2 Answers2

2

ServiceStack uses the JSV Format (aka JSON without quotes) to parse QueryStrings.

JSV lets you embed deep object graphs in QueryString as seen this example url:

http://www.servicestack.net/ServiceStack.Examples.Host.Web/ServiceStack/Json/
SyncReply/StoreLogs?Loggers=[{Id:786,Devices:[{Id:5955,Type:Panel,
  Channels:[{Name:Temperature,Value:58},{Name:Status,Value:On}]},
  {Id:5956,Type:Tank,TimeStamp:1199303309,
  Channels:[{Name:Volume,Value:10035},{Name:Status,Value:Full}]}]}]

If you want to change the default binding ServiceStack uses, you can register your own Custom Request Binder.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • Do i have to add a Custom Request Binder for every RequestDTO? – Damian S Nov 08 '12 at 12:22
  • is there anyway to automatically register a custom request binder for all dto's in a service? since the routes are automatically registered as a result of the [route] attibute. – Damian S Nov 08 '12 at 13:35
0

i've done this to automatically setup my own custom generic request binder for all the dto's in the apphost.Configure. Is iterating through EndpointHost.Config.ServiceController.AllOperationTypes ok?

    public static void Register(IAppHost appHost)
    {

        foreach (Type t in EndpointHost.Config.ServiceController.AllOperationTypes)
        {
            var method = typeof(MyFormatClass).GetMethod("DeserializationRequestBinder");
            var genericMethod = method.MakeGenericMethod(t);
            var genericDelegate = (Func<IHttpRequest, object>) Delegate.CreateDelegate( typeof( Func<IHttpRequest, object> ), genericMethod);

            // add DeserializationRequestBinder<t> to serivcestack's RequestBinders
            appHost.RequestBinders.Add(t, genericDelegate);
        }
    }


    public static object DeserializationRequestBinder<RequestDTO>(IHttpRequest httpReq)
    {
        // uses a few of the extension methods from ServiceStack.WebHost.Endpoints.Extensions.HttpRequestExtensions
        var requestParams = httpReq.GetRequestParams();            

    // create <RequestDTO> and deserialize into it

    }
Damian S
  • 213
  • 1
  • 11