Is it possible to send raw json with IRestClient - servicestack

I love the simplicity of using servicestack's IRestClient to test my api, but I need to replicate a test scenario when someone sends an incomplete object. For instance if my dto looks like this:
public class Todo
{
public long? Id { get; set; }
public string Content { get; set; }
public int? Order { get; set; }
public bool? Done { get; set; }
}
And I want to do a PUT with partial json like this:
{"Id": 99999, "Order":1}
How do I send just the above with the json client. If I use the typed version the client sends the entire object with defaults.

I think it might be easier to use ServiceStack's Http Utils (link is to POST but applies to PUT) to PUT the data.
"http://localhost/todo"
.PutJsonToUrl(#"{""Id"":9999,""Order"":1}");
Also, I'm not sure exactly what you are trying to test. But, if you're testing your Service the request (your json string) will be deserialized (pretty sure using ServiceStack.Text) into the Todo class so it will get the object with defaults for missing fields. See the test below.
[Test]
public void TestJson()
{
var json = #"{""Id"": 99999, ""Order"":1}";
var todo = new ServiceStack.Text.JsonSerializer<Todo>().DeserializeFromString(json);
Assert.IsNull(todo.Done);
Assert.IsNull(todo.Content);
}

Related

Change Autoquery return type in DTO generation

I want to return a custom class from my custom AutoQuery endpoint that inherits QueryResponse<T> but adds a few extra properties.
public class WritingAssignmentBlogLookUpResponse : QueryResponse<BlogDto>, IResponse
{
public bool Success { get; set; }
public string Message { get; set; }
public string DebugMessage { get; set; }
}
But if I specify request like so:
[Route("/assignment/blogs/", "POST")]
public class WritingAssignmentBlogsLookUpRequest : QueryDb<Blog, BlogDto>, IReturn<WritingAssignmentBlogLookUpResponse>
{
}
Then the return type specified in generatd DTO for client.post(req) is QueryResponse<BlogDto> and it doesn't generate WritingAssignmentBlogLookUpResponse at all.
Do I just have to specify return type as any from my typescript service or is there a way to make the types match so I can strongly type it?
You can’t change AutoQuery responses which are already fixed in their service contract definition to return a QueryResponse<T>.
You can add extra info to the Meta Dictionary of the Response DTO (exists for this reason) otherwise if you need to change the Service Contract you’d need to convert it into a normal (I.e. non-AutoQuery) API which could use the Service Gateway to call an existing AutoQuery API that decorates the response.

Get request with multiple inputs in ServiceStack API

I am creating a endpoint that accepts multiple parameters. I was wondering what the proper way of doing this in ServiceStack is, as I know that the routes can be defined like this:
[Route("/Cars/{EquipmentIds}/{ManufacturerIds}/{ColourIds}")]
But does not that mean that EquipmentIds has to be defined before ManufacturerIds and ColourIds, otherwise the API will interpret it incorrectly?
I would like to specify the parameters I use, and then not include the rest when they are not used.
A unclean url would then look like this ?EquipmentIds=1&ColourIds=1
I found the following solution, but this one was from 2011
Multiple Optional Parameters with ServiceStack.Net.
Is there a new solution for this, or is that still the proper way of doing things?
The URL should be a "resource identifier" where any Query String arguments are modifiers to that resource request.
So you shouldn't put complex types in the /path/info which are unlikely to form part of Resource Identifier for that route.
Your route should be self-describing as to what it's a resource identifier of. Stuffing a an anonymous bunch of ids in the URL doesn't make it a clean URL, it still needs to be semantically correct and self-describing at what the different path components contain.
It's hard to know the right Route to use when it's not clear what Service this is used for, but if this was a Car Search Service the appropriate URL would be something like:
/cars/search?EquipmentIds=1,2,3&ManufacturerIds=4,5,6&ColourIds=7,8,9
Just as when you use a Search Service like Google, they don't try to pack everything in the route, which is only used to identify you're making a search request. Everything else including the search query is added to the query string, e.g;
https://www.google.com/search?q=test
Which in ServiceStack would just be defined as:
[Route("/cars/search")]
public class SearchCars
{
public List<int> EquipmentIds { get; set; }
public List<int> ManufacturerIds { get; set; }
public List<int> ColourIds { get; set; }
}
Or it can be easily auto implemented in AutoQuery with:
[Route("/cars/search")]
public class SearchCars : QueryDb<Car>
{
public List<int> EquipmentIds { get; set; }
public List<int> ManufacturerIds { get; set; }
public List<int> ColourIds { get; set; }
}

How do I perform model binding on a HTTP POST in Azure Functions?

I want to bind my HTTP POST parameters to Azure functions, and want to ensure the untrusted data is correctly mapped to my model class.
Right now I'm using a mime type of application/json , and I may need to also support FORM Post and Protobuf.
Since I know support for the latter is a bit complex, how can I perform simple model binding for JSON data?
I've spent a lot of time reading about HTTP triggers, skimming all pages of the Azure Function docs, but don't see anything that helps with this issue. I suspect there is a lower level technology I need to research (webjobs?) for this.
If your HttpTrigger function is configured to accept JSON POST requests, you can bind to your custom model type as follows:
using System.Net;
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
public static async Task<HttpResponseMessage> Run(Person person, HttpRequestMessage req)
{
return person.FirstName == null
? req.CreateResponse(HttpStatusCode.BadRequest, "Who are you?")
: req.CreateResponse(HttpStatusCode.OK, $"Hello {person.FirstName}!");
}

How can I bind multiple 'Keys' to a single property on a Service Stack Request DTO

I have a DTO that goes something like this:
public class Request {
public id ASpecificIdentifier { get; set; }
public string PreciseDescription { get; set; }
public string FirstPartOfSomeonesName { get; set; }
}
Whilst I'm happy accepting this as the official 'Input', I would also like to be able to bind them to multiple keys. The reason for this will be serialized to a client in an encrypted JSON object, so I would like to keep the length down.
For example they should also be able to pass:
{
"Id":1,
"Desc":"My Issue",
"Name":"Bob"
}
How can I achieve this? I have looked around at the Attributes supplied but non seem to be able to allow this behaviour?
You could create multiple DTOs for each scenario you allow (set of named parameters). Then in your service you would have to handle each DTO and translate them a common DTO to take action.
Or Another way would be to have a DTO that takes a generic key/value parameter. This will make your DTOs very flexible but you will lose some of the advantages of strong typing.
For Example:
public class Request {
Dictionary<string,string> Properties { get; set; }
}

ServiceStack version 3.9.56 gives NullReferenceException error at metadata json page

I just downloaded ServiceStack with NuGet. Version 3.9.56.
I am trying simple webservice but when i open metadata json page it gives NullReferenceException error.
My service is here:
[Route("/users")]
[Alias("Users")]
public class User
{
[Alias("UserID")]
public int id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
}
public class UsersService:Service
{
public object Get(User request)
{
var result = new List<User>();
result = Db.Select<User>();
return result;
}
}
There is a known issue that might explain your null reference exception. However, you do not want IReturnVoid, unlike in your other post, so the answer here is not to wait for ServiceStack to be fixed but to improve your DTO's declaration:
Your UsersService implementation is returning a List<User> object for your User request. You can document this in ServiceStack like so:
public class User : IReturn<List<User>>
{
...
}
This may fix the issue you are seeing on the metadata page as ServiceStack now knows the type of response to expect for the User message. There are other benefits to decorating your request DTOs with IReturn:
The typed C# client will be easier to use, as the client can know the type of your response message
The Swagger UI, if you use it, will know about and automatically document the response type

Resources