-
Notifications
You must be signed in to change notification settings - Fork 0
C# client
Using DTOs to define your web service interface makes it possible to provide strong-typed generic service clients without any code-gen or extra build-steps, leading to a productive end-to-end type-safe communication gateway from client to server.
All ServiceStack's C# clients share the same interfaces and are created by passing in the Base URI of your ServiceStack service in the clients constructor, e.g. if your ServiceStack instance was hosted on the root path /
on the 8080 custom port:
var client = new JsonServiceClient("http://host:8080/");
Or if hosted on the /api
custom path:
var client = new JsonServiceClient("http://host/api/");
In addition, the service clients also provide HTTP verbs (Get, Post & PostFile, Put, Delete) letting you call your custom user-defined routes REST-fully e.g:
Using the New Api
HelloResponse response = client.Get(new Hello { Name = "World!" });
response.Result.Print();
Async Example
client.GetAsync(new Hello { Name = "World!" },
r => r.Result.Print(), (r, ex) => { throw ex; });
var response = client.Get<HelloResponse>("/hello/World!");
response.Result.Print();
Async Example
client.GetAsync<HelloResponse>("/hello/World!",
r => r.Result.Print(), (r, ex) => { throw ex; });
C#/.NET Clients can call the above Hello Service using any of the JSON, JSV, XML or SOAP Service Clients with the code below:
Using the New Api
var response = client.Send(new Hello { Name = "World!" });
response.Result.Print();
Async Example
client.SendAsync(new Hello { Name = "World!" },
r => r.Result.Print(), (r, ex) => { throw ex; });
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
response.Result.Print();
Async Example
client.SendAsync<HelloResponse>(new Hello { Name = "World!" },
r => r.Result.Print(), (r, ex) => { throw ex; });
The service clients use the automatic pre-defined routes for each service.
All of ServiceStack's generic Service Clients also allow you to fetch raw string
, byte[]
and Stream
responses of any existing service, or when you need it, the underlying HttpWebResponse
allowing fine-grained access to the HTTP Response. e.g With just the Service below:
[Route("/poco/{Text}")]
public class Poco : IReturn<PocoResponse>
{
public string Text { get; set; }
}
public class PocoResponse
{
public string Result { get; set; }
}
public class NativeTypesExamples : Service
{
public PocoResponse Any(Poco request)
{
base.Response.AddHeader("X-Response", request.Text);
return new PocoResponse { Result = "Hello, " + (request.Text ?? "World!") };
}
}
You can access it normally with the typed API:
PocoResponse response = client.Get(new Poco { Text = "World" });
response.Result //Hello, World
Or as get the JSON as a raw string:
string responseJson = client.Get<string>("/poco/World");
var dto = responseJson.FromJson<PocoResponse>();
dto.Result //Hello, World
Or as raw bytes:
byte[] responseBytes = client.Get<byte[]>("/poco/World");
var dto = responseBytes.FromUtf8Bytes().FromJson<PocoResponse>();
dto.Result //Hello, World
Or as a Stream:
using (Stream responseStream = client.Get<Stream>("/poco/World")) {
var dto = responseStream.ReadFully().FromUtf8Bytes().FromJson<PocoResponse>();
dto.Result //Hello, World
}
Or even access the populated HttpWebResponse
object:
HttpWebResponse webResponse = client.Get<HttpWebResponse>("/poco/World");
webResponse.Headers["X-Response"] //World
using (var stream = webResponse.GetResponseStream())
using (var sr = new StreamReader(stream)) {
var dto = sr.ReadToEnd().FromJson<PocoResponse>();
dto.Result //Hello, World
}
ServiceStack isn't limited to just returning POCO's as you can effectively return anything you want even images
/helloimage/ServiceStack?Width=600&height=300&Foreground=Yellow. These native responses can also be mark on your Request DTO IReturn<T>
interface marker to give you a terse end-to-end API for fetching raw responess, e.g:
[Route("/headers/{Text}")]
public class Headers : IReturn<HttpWebResponse>
{
public string Text { get; set; }
}
[Route("/strings/{Text}")]
public class Strings : IReturn<string>
{
public string Text { get; set; }
}
[Route("/bytes/{Text}")]
public class Bytes : IReturn<byte[]>
{
public string Text { get; set; }
}
[Route("/streams/{Text}")]
public class Streams : IReturn<Stream>
{
public string Text { get; set; }
}
public class BuiltInTypesService : Service
{
public void Any(Headers request)
{
base.Response.AddHeader("X-Response", request.Text);
}
public string Any(Strings request)
{
return "Hello, " + (request.Text ?? "World!");
}
public byte[] Any(Bytes request)
{
return new Guid(request.Text).ToByteArray();
}
public byte[] Any(Streams request)
{
return new Guid(request.Text).ToByteArray();
}
}
Which let you access the results as you would a normal response:
HttpWebResponse response = client.Get(new Headers { Text = "World" });
response.Headers["X-Response"] // "World"
string response = client.Get(new Strings { Text = "World" });
response // Hello, World
byte[] response = client.Get(new Bytes { Text = Guid.NewGuid().ToString() });
var guid = new Guid(response);
Stream response = client.Get(new Streams { Text = Guid.NewGuid().ToString() });
using (response)
var guid = new Guid(response.ReadFully());
All these APIs are also available asynchronously as well:
client.GetAsync(new Strings { Text = "Test" }, r => r, //World
(r, ex) => { throw ex; });
client.GetAsync(new Bytes { Text = Guid.NewGuid().ToString() }, r => new Guid(r),
(r, ex) => { throw ex; });
client.GetAsync(new Streams { Text = Guid.NewGuid() }, stream => {
using (stream)
new Guid(stream.ReadFully());
}, (stream, ex) => { throw ex; });
They all behave the same as the sync versions except for HttpWebResponse
which gets returned just after
the request is sent (asynchronously) and before any response is read so you can still access the HTTP Headers e.g:
client.GetAsync(new Headers { Text = "World" }, r => r.Headers["X-Response"], //World
(r, ex) => { throw ex; });
Which makes a great starting point if you want to stream the responses back asynchronously as seen in this Reactive ServiceStack example by @rodrigobamboo.
More examples can be found in the ServiceClients Built-in native type response tests
ServiceStack's Auth Tests shows different ways of authenticating when using the C# Service Clients. By default BasicAuth and DigestAuth is built into the clients, e.g:
var client = new JsonServiceClient(baseUri) {
UserName = UserName,
Password = Password,
};
var request = new Secured { Name = "test" };
var response = client.Send<SecureResponse>(request);
Behind the scenes ServiceStack will attempt to send the request normally but when the request is rejected and challenged by the Server the clients will automatically retry the same request but this time with the Basic/Digest Auth headers.
To skip the extra hop when you know you're accessing a secure service, you can tell the clients to always send the BasicAuth header with:
client.AlwaysSendBasicAuthHeader = true;
The alternative way to Authenticate is to make an explicit call to the Auth
service (this requires CredentialsAuthProvider enabled) e.g:
AuthResponse authResponse = client.Post(new Auth {
provider = CredentialsAuthProvider.Name,
UserName = "user",
Password = "p@55word",
RememberMe = true, //important tell client to retain permanent cookies
});
var request = new Secured { Name = "test" };
var response = client.Send<SecureResponse>(request);
After a successful call to the Auth
service the client is Authenticated and if RememberMe is set, the client will retain the Session Cookies added by the Server on subsequent requests which is what enables future requests from that client to be authenticated.
All REST and ServiceClients share the same interfaces (IServiceClient
, IRestClient
and IRestClientAsync
) so they can easily be replaced (for increased perf/debuggability/etc) with a single line of code.
Here's a list of all built-in clients:
- implements both
IRestClient
andIServiceClient
:- JsonServiceClient (uses default endpoint with JSON) - recommended
- JsvServiceClient (uses default endpoint with JSV)
- XmlServiceClient (uses default endpoint with XML)
- MsgPackServiceClient (uses default endpoint with Message-Pack)
- ProtoBufServiceClient (uses default endpoint with Protocol Buffers)
- implements
IServiceClient
only:- Soap11ServiceClient (uses SOAP 11 endpoint)
- Soap12ServiceClient (uses SOAP 12 endpoint)
- Why ServiceStack?
- What is a message based web service?
- Advantages of message based web services
- Why remote services should use separate DTOs
- Getting Started
- Reference
- Clients
- Formats
- View Engines 4. Razor & Markdown Razor
- Hosts
- Advanced
- Configuration options
- Access HTTP specific features in services
- Logging
- Serialization/deserialization
- Request/response filters
- Filter attributes
- Concurrency Model
- Built-in caching options
- Built-in profiling
- Messaging and Redis
- Form Hijacking Prevention
- Auto-Mapping
- HTTP Utils
- Virtual File System
- Config API
- Physical Project Structure
- Modularizing Services
- Plugins
- Tests
- Other Languages
- Use Cases
- Performance
- How To
- Future