Question

How can I configure ServiceStack v3.x JsonServiceClient to serialize an empty request object and call the service?

I want to get an exception, but instead the JsonServiceClient returns null. I put a breakpoint at the top of the service, and it's never hit. But when the name property is not blank, it gets hit.

Result Message:

Expected: <ServiceStack.ServiceClient.Web.WebServiceException>
But was: null

Here's the failing test, it doesn't raise any ex.

[Test]
public void TestPortfolioBlankNameE2E()
{
    JsConfig.IncludeNullValues = true;
    var client = TestHelpers.ISWJsonServiceClient();
    GetPortfolio request = "{\"name\":\"\"}".FromJson<GetPortfolio>();
    WebServiceException ex = 
           (WebServiceException)Assert.Throws(typeof(WebServiceException), 
           delegate { client.Get(request); });

    Assert.AreEqual(400, ex.StatusCode);
    Assert.AreEqual("Bad Request", ex.StatusDescription);
    StringAssert.Contains("Required parameter missing: name", ex.Message);
}

The equivalent test, calling the service directly, passes.

[Test]
public void TestPortfolioBlankName()
{
    PortfolioService service = TestHelpers.MockServer<PortfolioService>();
    GetPortfolio request = "{\"name\":\"\"}".FromJson<GetPortfolio>();
    HttpError ex = 
            (HttpError)Assert.Throws(typeof(HttpError), 
            delegate { service.get(request); });

    Assert.AreEqual(400, ex.Status);
    Assert.AreEqual(HttpStatusCode.BadRequest, ex.StatusCode);
    StringAssert.Contains("Required parameter missing: name", ex.Message);
}

The DTO:

[Route("/portfolio/{name}", "GET")]
public class GetPortfolio : IReturn<GetPortfolioResponse>
{
    public String name { get; set; }
}

As Doug points out, that explains it. It fails to create a valid route without a value for name. Too bad it doesn't raise an exception when it can't create a valid route. Returning null doesn't suggest the source of the problem.

Was it helpful?

Solution

I don't think your problem lies in serialization.

Setting JsConfig.IncludeNullValues = true won't affect whether your request DTO transfers from client to server correctly. It affects the efficiency of the wire protocol. That configuration only affects the payload size of the serialized JSON.

Rather than sending {"name":null} (13 UTF-8 bytes), serializing with JsConfig.IncludeNullValues = false will send {} (2 UTF-8 bytes).

But the deserialized DTO received by the server will be identical to the DTO on the client in both cases.

(Also, your example code is sending an empty string "" not null. So it will be completely unaffected by the JsConfig.IncludeNullValues setting.)

I'm guessing your problem lies in the routing of your request DTO. There's probably something ambiguous about it (or it conflicts with other request DTOs) such that ServiceStack can't figure out how to route it to your PortfolioService class.

Calling the service directly is bypassing all the ServiceStack routing logic.

Can you include the source for your GetPortfolio request DTO class, so we can see if there is anything obviously wrong?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top