0
votes

I'm trying to perform a patch with a JsonServiceClient to a service stack api as follows:

var patchRequest = new JsonPatchRequest
{
    new JsonPatchElement
    {
        op = "replace",
        path = "/firstName",
        value = "Test"
    }
};
_jsonClient.Patch<object>($"/testurl/{id}", patchRequest);

But I'm getting the following error:

Content-Type must be 'application/json-patch+json'

The error is clear. Is there a way to change the content type before perform the request for the JsonServiceClient?

This is the request POCO in the ServiceStack api:

[Api("Partial update .")]
[Route("/testurl/{Id}”, "PATCH")]
public class PartialTest : IReturn<PartialTestRequestResponse>, IJsonPatchDocumentRequest,
    IRequiresRequestStream
{
    [ApiMember(Name = “Id”, ParameterType = "path", DataType = "string", IsRequired = true)]
    public string Id { get; set; }

    public Stream RequestStream { get; set; }
}

public class PartialTestRequestResponse : IHasResponseStatus
{
    public ResponseStatus ResponseStatus { get; set; }
}

Service implementation:

public object Patch(PartialTest request)
    {
        var dbTestRecord = Repo.GetDbTestRecord(request.Id);

        if (dbTestRecord == null) throw HttpError.NotFound("Record not found.");

        var patch =
          (JsonPatchDocument<TestRecordPoco>)
              JsonConvert.DeserializeObject(Request.GetRawBody(), typeof(JsonPatchDocument<TestRecordPoco>));

        if (patch == null)
            throw new HttpError(HttpStatusCode.BadRequest, "Body is not a valid JSON Patch Document.");

        patch.ApplyTo(dbTestRecord);
        Repo.UpdateDbTestRecord(dbTestRecord);
        return new PartialTestResponse();
    }

I'm using Marvin.JsonPatch V 1.0.0 library.

1
This is not an error that's in ServiceStack, please update your post to include the ServiceStack Service implementation.mythz

1 Answers

2
votes

It's still not clear where the Exception is coming from as it's not an Error within ServiceStack. If you've registered a Custom Format or Filter that throws this error please include its impl (or a link to it) as well as the full StackTrace which will identify the source of the error.

But you should never call Patch<object> as an object return type doesn't specify what Response Type to deserialize into. Since you have an IReturn<T> marker you can just send the Request DTO:

_jsonClient.Patch(new PartialTest { ... });

Which will try to deserialize the Response in the IReturn<PartialTestRequestResponse> Response DTO. But as your Request DTO implements IRequiresRequestStream it's saying you're expecting unknown bytes that doesn't conform to a normal Request DTO, in which case you likely want to use a raw HTTP Client like HTTP Utils, e.g:

var bytes = request.Url.SendBytesToUrl(
  method: HttpMethods.Path,
  requestBody: jsonPatchBytes,
  contentType: "application/json-patch+json",
  accept: MimeTypes.Json);

You could modify the ContentType of a JSON Client using a request filter, e.g:

_jsonClient.RequestFilter = req => 
    req.ContentType = "application/json-patch+json";

But it's more appropriate to use a low-level HTTP Client like HTTP Utils for non-JSON Service Requests like this.