(Go: >> BACK << -|- >> HOME <<)

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way of DTO entity partial update (particular fields) on PUT? #560

Open
agat366 opened this issue Oct 4, 2018 · 3 comments
Open

Comments

@agat366
Copy link
agat366 commented Oct 4, 2018

I am not sure if I want to much, but still, is there any way to achieve partial update of DTO models?

For instance, if I have a DTO:

public class MyDto {
public int Id {get;set;}
public string Field1 {get;set;}
public string Field2 {get;set;}
public string Field3 {get;set;}
}

sometimes I might need to send only one of the Fields to update (only Field1, for instance).

But when I use
[Put("/myapi/{id}")]
Task SavePartial([Body] MyDto data);
all the fields are sent to the server, so if they are even null, some servers just update those values to "null" (or even throw array).

So, is there any way to send only needed data.
I understand, that that's kind of quite custom logic, but in multi-technologies world, that is very handy sometimes.
I imagine that that can be implemented in way of passing dynamic (anonymous) classes, or via Expressions when enumerating the fields to pass.
There possibly already some sort of functionality implemented to support that in Refit. If not, what easy way it can be extended to achieve the goal mentioned?

@xljiulang
Copy link
Contributor
xljiulang commented Oct 13, 2018

well, json patch is what you need, it's supported in WebApiClient:

public interface IMyWebApi : IHttpApi
{
    [HttpPatch("webapi/user")]
    Task<UserInfo> PatchAsync(string id, JsonPatchDocument<UserInfo> doc);
}

var doc = new JsonPatchDocument<UserInfo>();
doc.Replace(item => item.Account, "laojiu");
doc.Replace(item => item.Email, "laojiu@qq.com");
var client = HttpApiClient.Create<IMyWebApi>();
await client.PatchAsync("id001", doc);

in asp.net server:

[HttpPatch]
public async Task<UserInfo> Patch(string id, [FromBody] JsonPatchDocument<UserInfo> doc)
{
    var user = await GetUserInfoFromDbAsync(id);
    doc.ApplyTo(user);
    // save user to db ..
    return user;
}

@agat366
Copy link
Author
agat366 commented Oct 16, 2018

Thanks for the response, and the approach you've offered is great indeed, however, in my case this is not an option, as the api I use is kind of "public" one (at least, from the project architecture perspective) (and if to touch details, the backend is not even .NET, so it lives on its own rules).
So I just should "remove" particular dto properties to post (otherwise the server just fails). Currently I am creating a separate dto per operation per item, like so:

public class Vehicle_Create_Dto
{
    public string Model { get; set; }
    public string Vin { get; set; }
}

Which is far not handy option. So, ideal solution for me would be sending kind of "dynamic" approach. So, do I have any other options in this case?

@natelaff
Copy link
natelaff commented Mar 30, 2020

Was having issues implementing Patch with Refit and ASP.NET Core, so I thought I'd offer some help in case anyone else runs into this.

[Patch("{id}")]
[Headers("Content-Type: application/json-patch+json")]
Task<UserInfo> PatchAsync(string id, JsonPatchDocument<UserInfo> doc);

You'll notice the addition of the Content-Type header to use json-patch, which is what was required in this case. Hope it helps someone :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants