captncraig
captncraig

Reputation: 23078

Combining URL and POST variables in ServiceStack

I am trying to convert an existing wcf rest api to ServiceStack, and having issues right out of the gate:

[Route("foo/{userId}","POST")]
public class MyInputModel : IReturnVoid
{
    public string userId { get; set; }
    public SomeOtherObject properties { get; set; }
}

The intention here is that I would provide the userId in the url, and an instance of SomeOtherObject in the post body. The error I get is

<Message>Could not deserialize 'application/xml' request using MyInputModel'
Error: System.Runtime.Serialization.SerializationException: 
Error in line 1 position 42. Expecting element 'MyInputModel' 
from namespace 'blahblahblah'.. Encountered 'Element'  with name 
'SomeOtherObject', namespace 'http://blahblahblah'. 

The only things I can think of are to wrap my xml in a MyInputModel to make the serializer happy. This is not really an option for backwards compatibility.

I could also modify SomeOtherObject to be the top level input model, and put a UserId property in there, but this also feels suboptimal since it is an object used throughout the api, and is really not tied to a user id. It is also already published independently, so it would be painful to make changes there.

Is there any way to indicate that the root element of the posted data will be a SomeOtherObject insted of a MyInputModel? In WebApi this would be with the [FromBody] attributes and whatnot. Does servicestack have anything similar?

Upvotes: 2

Views: 3589

Answers (1)

mythz
mythz

Reputation: 143319

The purpose of a DTO is to auto-generate the wire format which is why ServiceStack requires the Request DTO to match the shape of the incoming request. Part of what makes ServiceStack so productive is that it's a code-first web service framework which encourages starting from C# and projecting out, i.e. your clients should bind to your web service outputs and not the other way round of mapping code-first models to existing schema inputs.

Having said that, the Serialization / Deserialization wiki page lists the different ways to override ServiceStack's default request binding with your own.

Access HTTP Request variables in any Service or Filter

Not everything needs to be mapped to a DTO as any HTTP Variable can still be accessed from the IHttpRequest available from any service or filter, i.e:

base.Request.QueryString
base.Request.FormData
base.Request.Headers[name]
base.Request.PathInfo
base.Request.AbsoluteUri

Upvotes: 4

Related Questions