-
Notifications
You must be signed in to change notification settings - Fork 47
Support for Json Merge Patch - RFC7396 #52
Comments
Seconded. |
Third. |
This would be great. Seems a lot more appropriate for what I'd imagine the "average" user requires of JSON Patch. |
What does the Has an API for this already been decided? Or is it in discussion -- if so is this public? I have been playing around a bit and I've got a working PoC which allows for uhhh.. this: // Normal DTO/model
public class PersonDetailsUpdate
{
public string GivenName { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
public int? GroupId { get; set; }
} [HttpPatch("Users/{id:int}")]
public IActionResult Patch([FromRoute]int id, JsonMergeDocument<PersonDetailsUpdate> mergeDocument)
{
JsonMergeDocumentMember<int?> groupIdMember = mergeDocument.Member(x => x.GroupId);
if (groupIdMember.IsSet)
{
int? newGroupId = groupIdMember.Value;
if (newGroupId.HasValue) {
// Throw if group is not valid
_groupsService.SetUserGroup(id, newGroupId);
}
_groupsService.UnSetUserGroup(id);
}
using (UsersDbContext usersContext = new UsersDbContext())
{
// Check if user exists
UserEntity user = new UserEntity
{
Id = id
};
EntityEntry entity = dbContext.Users.Attach(dbUser);
foreach(IEnumerable<JsonMergeDocumentMember> member in mergeDocument.Members.Where(x => x.IsSet))
{
PropertyEntry entityProp = entity.Member(member.Name) as PropertyEntry;
if (entityProp != null)
{
if (entityProp.MetaData.ClrType != member.Type)
{
// perhaps try convert type and set
}
entityProp.CurrentValue = member.Value;
}
}
usersContext.SaveChanges();
}
return NoContent();
} Assume the following data is persisted:
With group information being stored in a completely isolated service. That is, a {
"UserId": 10,
"FirstName": "Mardoxx",
"Surname": "",
"Age": 99,
"GroupId" : 100
} Sending {
"Age": 20,
"GroupId" : null
} Will update the user's age to 20, and remove the user from its group, i.e. GroupId to null. A {
"UserId": 10,
"FirstName": "Mardoxx",
"Surname": "",
"Age": 20,
"GroupId" : null
}
This is the sort of functionality I would like from an official impl of Json Merge Patch. Validation is a necessary addition to this, so is an An official solution to something like this would be really desirable! |
Just pitching in from a front-end-dev perspective. Granted that JSON Patch is a nice standard but it's pretty widely accepted to do operations in a JSON-Merge kind of way. To a JS developer, it would be pretty weird if their backend developer told them they couldn't support this kind of operation, it would be generally seen as basically an incapable/not very useful technology. |
Ok so I've cleaned it up a bit, API is a little different now, Shall I write a few tests and do a PR? Or has work on this already begun? I want this to be |
+1 For this. Please add support for Json Merge Patch! |
@Mardoxx - we'll discuss and get back to you next week. We're still planning the set of features we're going to do for 2.1, and this is under consideration. I'm putting a reminder on my calendar right now. If you have an example of this somewhere in a repo that we can look at that would help. |
+1 Please add json merge patch, this is more client-friendly, easier to understand and to manage in a lot of situations. Is a very important feature. |
@rynowak Amazing thanks. Done here - https://github.com/Mardoxx/RJBM.JsonMergePatch Cleaned it up a lot and simplified it... a lot. Hacked together a handful of tests that should give an idea of behaviour. Not happy about a few things, see here, but happy enough about general API for it (not necessarily the names of things though!). Gives a basic idea of what I want. Can add end to end example if you like? |
Hey @Mardoxx, this is a working (non-official) example? I know there are several things to work in it (Mardoxx/RJBM.JsonMergePatch#1), but it works? |
Hey @Mardoxx, thanks for your answer. There's any way to create a NuGet package in order to test this in one of my projects? Thank you! |
@Mardoxx - have you done any work with your code to support cases like the following: Original
Patch
After
Notice in this case that From the .NET point-of-view this seems like the hard part. Here's the pseudo-code from the spec (emphasis mine)
Some of the other challenges that we've run into implementing patch are around casing and the behavior of dictionary types and dynamic types. JSON-Patch and JSON-Merge (and JSON) in general are case-sensitive. We banished most of these issues recently by using |
Totally overlooked that, will have a look later - and also adding properties that don't exist on the original document (i.e. source is a dynamic object)... Haven't looked at (didn't occur to me) Json.Net api! Good idea. Ok, this is very difficult. Does not really fit in with the way I wrote it. Back to the drawing board! |
Hi Folks, sorry for the delay. We don't have an official 2.1 announcement post out yet, but I'm sad to say JSON Merge didn't make the cut. We understand the feedback that this is valuable and we'd like for a good .NET solution to exist, but we're not going to invest in building it right now. I'd suggest teaming up and fleshing out the implementation that @Mardoxx has started working on. We'd be happy to provide advice and help promote the library if it takes off. |
Maybe @Mardoxx could make a library (NuGet Package) at least for the basics. |
@rynowak Understandable, it's something that comparatively few will benefit from. Not at all certain about the current implementation I came up with (besides it only conforming to like 1/3rd of the spec!) -- Not had time to think about it the past few days. Some pointers from someone more experienced than I, or anyone really, would be very welcomed! @mhosman, seeing as it's only 4 files or so, feel free to just copy them to your own project. I would not feel okay publishing this anywhere too public (e.g. NuGet) until it is in an actual working state! |
I just found this.... https://github.com/Morcatko/Morcatko.AspNetCore.JsonMergePatch |
@mhosman good find. Feels uneasy to me re-purposing jsonpatch. But hey, if it works.. it works! |
Since I logged this issue, I have been using the following to perform a patch: public void Patch<TEntity, TViewModel>(TEntity entity, TViewModel updatedModel) where TEntity : class, IEntity
{
// copy the value of properties from view model into entity
PropertyInfo[] entityProperties = entity.GetType().GetProperties();
foreach (PropertyInfo entityPropertyInfo in entityProperties)
{
PropertyInfo updatedModelPropertyInfo = updatedModel.GetType().GetProperty(entityPropertyInfo.Name);
if (updatedModelPropertyInfo != null)
{
var value = updatedModelPropertyInfo.GetValue(updatedModel, null);
if (value != null)
{
entityPropertyInfo.SetValue(entity, value, null);
}
}
}
} |
Seems like most people in this thread are missing the subtle difference between omitting a field from the request and sending a I found this issue because I was trying to solve this problem myself and looking for others talking about the subject. In JavaScript-land this nuance can be modelled with |
No, both my and that other example account for null vs undefined.
…On 24 Sep 2017 21:09, "Jeff" ***@***.***> wrote:
Seems like most people in this thread are missing the subtle difference
between omitting a field from the request and sending a null value in the
request. Checking against null in the implementation means that frontends
sending null back in their payload will be ignored by the backend. This
essentially creates a behaviour where, once being set to a value, a field
will never be able to be set to null again.
I found this issue because I was trying to solve this problem myself and
looking for others talking about the subject. In JavaScript-land this
nuance can be modelled with undefined vs. null values but in C# the
aspnet core middleware will serialize both an omitted field and a null
field to null in the C# model, and therefore (from an information
perspective) you literally cannot tell the difference by the time you've
made it to a Controller. Wondering if perhaps AspnetCore could set
annotations on Omitted fields or similar that could be read out in the
Patch method to differentiate fields that were in the payload vs. fields
that weren't.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#52 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAOoMesFBtV7edaiq48u3STBVGgAJopTks5slrcPgaJpZM4LbYdB>
.
|
Alright, that's my mistake. I hadn't trawled the code, and was merely acting on language cues. |
This issue was moved to dotnet/aspnetcore#2436 |
Hi,
Are their any plans to support the Json Merge Patch
https://tools.ietf.org/html/rfc7396
The text was updated successfully, but these errors were encountered: