Well one thing I notice is that the LoadContext for the new Note isn't set in either case.
The NoteId property reads out of the LoadContext, but doesn't push into it.
Both of those cases are going to use the default ctor, so maybe that's part of the problem. I'm not sure I understand with the INotifyPropertyChanged implementation has to do with it, since ModelItemBase already implements that.
In any case, I'd verify that the object that's being returned from DeserializeCore is property formatted, has a LoadContext that matches it's ID, etc.
An easy way to do this would be the following:
protected override object DeserializeCore(LoadContext loadContext, Type objectType, Stream stream)
using (var reader = new StreamReader(stream, Encoding.UTF8))
var jsonReader = new JsonTextReader(reader);
// Load JObject from stream
JObject jObject = JObject.Load(jsonReader);
// Create target object based on JObject
Note target = new Note(jObject.getInt('id')); // I'm guessing at the syntax for JSON.net here.
var serializer = new Newtonsoft.Json.JsonSerializer();
// Populate the object properties