ServiceStack doesn't populate error responses - servicestack

We're working on a project using ServiceStack (loving it) but need some help with a strange problem. In our project we throw or return various types of HttpError with ErrorResponse and ResponseStatus objects using a helper method.
It follows the pattern described here. Something like this:
protected HttpError BusinessError(string summaryMessage = "Some generic validation summary.")
{
return new HttpError(HttpStatusCode.BadRequest, "MyValidationType", summaryMessage)
{
Response = new ErrorResponse
{
ResponseStatus = new ResponseStatus
{
ErrorCode = "MyValidationType",
Message = summaryMessage,
Errors = new List<ResponseError>()
},
}
};
}
In a service call we would use it like so:
throw BusinessError("Help I've fallen and can't get up!");
This would work a treat, and we'd feed it in to the ss-validation JS library to render our validation messages. Worked fine.
The problem is that now ServiceStack won't serialize any of the HttpError's details into the response. All we get is a response with the 400 status code, the 'MyValidationType' error code, and empty JSON response {}.
I've tried playing with combinations of throwing/returning the error and switching the service method's return type to object etc, but nothing seems to make a difference. To be honest I'm not sure what we could have changed in our project to cause this behavior.
I'd appreciate any advice or pointers as to what could cause this?

This can happen if you're using a {RequestName} and {RequestName}Response naming convention and the Response DTO does not have a ResponseStatus property:
The {RequestDto}Response is returned, regardless of the service method's response type. If the {RequestDto}Response DTO has a ResponseStatus property, it is populated otherwise no ResponseStatus will be returned. (If you have decorated the {ResponseDto}Response class and properties with [DataContract]/[DataMember] attributes, then ResponseStatus also needs to be decorated, to get populated).
In which case the solution is just to add a ResponseStatus property to the Response DTO:
public class RequestNameResponse
{
public ResponseStatus ResponseStatus { get; set; }
}

Related

ServiceStack Fluent Validation - Message Issue

I am using ServiceStack Fluent Validation and it works great. I did see an issue.
If my return object name is "xxxxStatusResponse", validation works but I do not see the validation message. If the return object is named as "xxxxStatusResult", I can see the validation message.
Am I missing something here?
Thanks
rudrvij
This behavior is documented in ServiceStacks Error Handling docs. If you use the {RequestDtoName}Response naming convention for the Response DTO ServiceStack will return an instance of that Response DTO, so in order for it to be populated with a structured Error Response it must have a ResponseStatus property, e.g:
public class MyExampleResponse
{
public ResponseStatus ResponseStatus { 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

Swagger UI displaying extra parameter using ServiceStack

I'm having issues with displaying the correct notes in swagger using ServiceStack.
Given this structure:
[Route("/Widget/{WidgetId}", Summary = "Updates a widget by id", Verbs = "POST",
Notes = "Updates a widget by id.")]
public class UpdateReqWidget : IReturnVoid
{
[ApiMember(Name = "WidgetId", Description = "The id of widget to delete.")]
public int WidgetId { get; set; }
}
public class WidgetService
{
public void Put(UpdateReqWidget req)
{
//do code here
}
}
It's producing:
I would expect the parameters list only to have WidgetId, but it's displaying WidgetId and UpdageReqWidget, the class name for the request. any ideas what I'm doing wrong?
EDIT: I'm using versions 3.9.55 for both ServiceStack and ServiceStack.API.Swagger. I've changed the templates to better suit our needs.
There is a recent addition to ServiceStack.Api.Swagger to automatically generate a request body parameter in the Swagger UI. I think there's an edge case in which the request DTO has no properties that aren't designated as path or query parameters, as in your case here, the code will still generate that UpdateReqWidget request body parameter, but it will be an empty object in Swagger.

Service Stack IRequiresHttpRequest Pattern

How does this work? I've read the docs but am hoping for some more info.
From reading the docs I understand that when my DTO implements IRequiresHttpRequest, then the DTO's properties will not get automatically populated, but in my DTO I now have access to the HttpRequest object so I can change my DTO to have 'get' properties that pull things from the request object.
What is meant to inject the HttpRequest into my DTO? The docs suggest that service stack does this behind the scenes, however I can only get it to work if I register a custom request binder and manually inject the HttpRequest object.
RequestBinders.Add(typeof(MyDto), httpReq => {
var dto = new MyDto();
dto.HttpRequest = httpReq;
return dto;
});
Question 1: How exactly is the injection for IRequiresHttpRequest meant to work?
Question 2: Is there a way to gain access to the HttpRequest object so that my DTO can support custom 'get' properties, by still have service stack run it automatic mapping? For example:
public class MyDto
: IRequiresHttpRequest
{
public Int32 AutoMappedProperty1 { get; set; }
public Int32 AutoMappedProperty2 { get; set; }
public Int32 AutoMappedProperty3 { get; set; }
public Int32 AutoMappedProperty4 { get; set; }
public Int32 CustomMappedProperty { get { return customMappedProperty; } }
IHttpRequest httpRequest;
public IHttpRequest HttpRequest
{
get
{
return httpRequest;
}
set
{
httpRequest = value;
// lets say this searches the query string for a variety of
// different keys, and then maps one of them of
// CustomMappedProperty based upon a specific set of rules
customMappedProperty = [...]
}
}
}
In the case above I am defining how CustomMappedProperty gets populated, but I still want service stack to go ahead and map all of the 'set'-able properties. Is there a way to achieve this? Can I manually invoke the service stack dto mapper?
Which docs did you read about IRequiresHttpRequest? IRequiresHttpRequest works the same as IRequiresRequestContext which is only for decorating on Services and Validators to tell ServiceStack that it requires access and to inject the current IHttpRequest or IRequestContext.
The Custom Serialization / Deserialization wiki only mentions that IRequiresRequestStream and IRequiresSoapMessage can be used on Request DTOs to signal to ServiceStack to skip processing the Request body and allow you to manually deserialize the request yourself.

ServiceStack Custom ErrorResponse DTO

We are currently using ServiceStack as our core framework for service provisioning.
Does anyone know if it's possible to wrap custom exceptions into custom ErrorResponse objects?
From SS wiki:
"In addition to the above options, you can override the serialization of ad-hoc exceptions by implementing the IResponseStatusConvertible.ToResponseStatus() method and have it return your own populated ResponseStatus instance instead."
That seems to fit with my needs, but I cannot figure out where I can override this serialization.
Again, I've tried to use custom httphandler by registering them within the AppHost, but they are not invoked when exceptions occur.
I am certainly missing something, is there anyone who can guide me through this?
Here is ServiceStack's Error Handling wiki page.
What it's saying is that you can control how the ResponseStatus is serialized if your custom exceptions implement IResponseStatusConvertible. Here is the source code example of ValidationException implementing it:
public class ValidationException : ArgumentException, IResponseStatusConvertible
{
public IEnumerable<ValidationFailure> Errors { get; private set; }
public ValidationException(IEnumerable<ValidationFailure> errors) : base(BuildErrorMesage(errors)) {
Errors = errors;
}
private static string BuildErrorMesage(IEnumerable<ValidationFailure> errors) {
var arr = errors.Select(x => "\r\n -- " + x.ErrorMessage).ToArray();
return "Validation failed: " + string.Join("", arr);
}
public ResponseStatus ToResponseStatus()
{
var errors = Errors.ConvertAll(x =>
new ValidationErrorField(x.ErrorCode, x.PropertyName, x.ErrorMessage));
var responseStatus = ResponseStatusUtils.CreateResponseStatus(typeof(ValidationException).Name, Message, errors);
return responseStatus;
}
}
But this only controls how ResponseStatus is serialized, not how the generic responses are created. Look at the description of IAppHost.ServiceExceptionHandler or use a custom service runner if you want to change the error response returned.

Resources