I want to store some information for a member in Umbraco using the AdditionalData dictionary field.
First I get the member (this code is located in a SurfaceController):
var member = Services.MemberService.GetByUsername("username");
Then I add the data
member.AdditionalData.Add("SomeDataKey", "SomeData");
And save it.
Services.MemberService.Save(member);
When I fetch the same member again after it has been saved, the member does not contain the AdditionalData anymore.
I don't want to create an extra property to save this data. I want to use it as described in the documentation. (IUmbracoEntity: AdditionalData property)
Some entities may expose additional data that other's might not, this custom data will be available in this collection
Q: Am I missing something or could someone point me in the right direction?
Q: Is the AdditionalData stored somewhere or is this temporary
(Umbraco 7.2.4)
Best regards,
Tom
(Umbraco forum: link)
To retrieve custom property values for the member you can use:
var member = Services.MemberService.GetByUsername("username");
var myPropertyValue = member.GetValue<string>("myPropertyAlias");
Related
In my previous question I was looking for a way to access and store return value of the function in qaf step. I was provided with the following:
When create new user using "{'name':'user1','password':'user123'}"
And store into 'newUser'
Then system should have user '${newUser}'
Now, I'd like to know how to get value from object/collection stored.
If it is a simple object named newUser which has field Id. How would I pass Id on next step?
And, if return is List, how to get by index from stored list?
Resolved issue on my own. If anyone faces same unknowns, here is how I solved it.
For requirements to work around response data, parsing same stored objects in properties by specific fields or collecting data from other structures such as Maps or Lists, create common functions with #QAFTestStep annotation to get data for class member name, map by key or list by index and so on... Add those in common steps and then write stepname text in gherkin format with parameters specified. Let me know if someone needs help, always ready to help out...
I understand how to retrieve data from an XML source using type providers. However, I need to then modify a particular part of the XML and save it to disk. I have tried assigning a value to the node using <- but the property is read-only.
For example:
let doc = MyXml.load fileName
doc.ItemId.Id <- "newId" // doesn't work
doc |> saveXml
There is a similar question for JSON where the suggestion is to create a new object, but this is specifically for XML.
While researching my question I found that you can use the .XElement accessor to get a reference to a mutable XElement object. Thus a solution is:
let doc = MyXml.load fileName
doc.ItemId.XElement.Element(XName.Get "Id").Value <- "newId" // tada
doc.XDocument.Save(...)
Note that you have to use the .XElement accessor on the parent if you're modifying a leaf node. This is because the leaf node's type is a primitive and doesn't have an .XElement accessor of its own. A slight shame, but I suppose it makes life easier on the other side when you want read-only access to the value.
I'm trying to get information from an indexedDB, and I want to get just the object from one store by key, and not all the objects from the database. In some examples of javascript and IndexedDB they use the method get() to get the value depending of the key. In DART there is not such method but there is getObject().
How do I get the value of the object when using getObject(key)?
Thanks a lot in advance!
Actually it has getObject(key) method, take a look here https://api.dartlang.org/apidocs/channels/stable/#dart-dom-indexed_db.ObjectStore#id_getObject
The other way for fetching data is Cursor. Here is a good tutorial https://www.dartlang.org/docs/tutorials/indexeddb/#getting-data
So all needed to do was to create a callback. This is how I got the objects value:
var id = "example";
var trans = _db.transaction('myDB', 'readwrite');
var store = trans.objectStore(_TODOS_STORE);
// Get the value from one object ! and render it
var request = store.getObject(id).then((val){functionFor(val);});
Futures need from callbacks to be able to use their values.
In my scenario i've a MVC on iis serializing objects from entity framework where i've overridden GetHashCode and Equal methods since the Id of those objects is immutable once committed to the database.
i also have some client, who can't reach the database, but connect to iis to get those entities serialized via json and deserialize them locally using newtonsoft.json.
When i deserialize them in the clients for a second time, to refresh the data in them, i was expecting the existing instances to be updated automatically.
I'm expecting a little too much?
Should i write some clone method to copy properties and check a cache for existing ids?
Did i wrote something wrong in the Equal and GetHashCode methods?
For instance:
I've a blog entity with a title in the database
The client connect to iis
get a json string containing {"Id" : 1, "Name" : "blogName"}
deserialize it and store it locally
add post to the blog in the same way to an observable collection in the class blog i've used client side
Someone or something Change the blog name in the database
The client try to refresh
get the json string containing {"Id" : 1, "Name" : "newBlogName"}
deserialize it to a new instance of class blog, with same id
What's next? copy the new instance name to the old one, ore there's a better way?
Yes, you expect too much. You can attach new entity (because entity framework context doesn't know about this entity, because you get it from somewhere outside dbcontext) and then save it.
Answer here
//This place is where you can deserialize your entity
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };
using (var context = new BloggingContext())
{
context.Blogs.Attach(existingBlog);
// Do some more work...
context.SaveChanges();
}
I think the best solution is to have two database one server side and one client side, with the same shared entity framework but different connection strings, json.net with the keep object reference setted and use the network only to sync the databases and then query it client side.
I am looking for a simple way to hydrate a related object. A Note belongs to a Document and only owners of a Document can add Notes so when a user tries to edit a Note, I need to hydrate the related Document in order to find out if the user has access to it. In my Service layer I have the following:
public void editNote(Note note)
{
// Get the associated Document object (required for validation) and validate.
int docID = noteRepository.Find(note.NoteID).DocumentID;
note.Document = documentRepository.Find(docID);
IDictionary<string, string> errors = note.validate();
if (errors.Count > 0)
{
throw new ValidationException(errors);
}
// Update Repository and save.
noteRepository.InsertOrUpdate(note);
noteRepository.Save();
}
Trouble is, noteRepository.InsertOrUpdate(note) throws an exception with "An object with the same key already exists in the ObjectStateManager." when the repository sets EntityState.Modified. So a number of questions arise:
Am I approaching this correctly and if so, how do I get around the exception?
Currently, the controller edit action takes in a NoteCreateEditViewModel. Now this does have a DocumentID field as this is required when creating a new Note as we need to know which Document to attach it to. But for edit, I cannot use it as a malicious user could provide a DocumentID to which they do have access and thus edit a Note they don't own. So should there be seperate viewmodels for create and edit or can I just exclude the DocumentID somehow on edit? Or is there a better way to go about viewmodels such that an ID is not required?
Is there a better way to approach this? I have read that I should just have a Document repository as an aggregate and lose the Note repository but am not sure if/how this helps.
I asked a similar question related to this but it wasn't very clear so hoping this version will allow someone to understand and thus point me in the right direction.
EDIT
Based on the information provided by Ladislav Mrnka and the answer detailed here: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key, it seems that my repository method need to be like the following:
public void InsertOrUpdate(Note note)
{
if (note.NoteID == default(int)) {
// New entity
context.Notes.Add(note);
} else {
// Existing entity
//context.Entry(note).State = EntityState.Modified;
context.Entry(oldNote).CurrentValues.SetValues(note);
}
}
But how do I get the oldNote from the context? I could call context.Entry(Find(note.NoteID)).CurrentValues.SetValues(note) but am I introducing potential problems here?
Am I approaching this correctly and if so, how do I get around the exception?
I guess this part of your code loads the whole Node from the database to find DocumentID:
int docID = noteRepository.Find(note.NoteID).DocumentID;
In such case your InsertOrUpdate cannot take your node and attach it to context with Modified state because you already have note with the same key in the context. Common solution is to use this:
objectContext.NoteSet.ApplyCurrentValues(note);
objectContext.SaveChanges();
But for edit, I cannot use it as a malicious user could provide a DocumentID to which they do have access and thus edit a Note they don't own.
In such case you must add some security. You can add any data into hidden fields in your page but those data which mustn't be changed by the client must contain some additional security. For example second hidden field with either signature computed on server or hash of salted value computed on server. When the data return in the next request to the server, it must recompute and compare signature / hash with same salt and validate that the passed value and computed value are same. Sure the client mustn't know the secret you are using to compute signature or salt used in hash.
I have read that I should just have a Document repository as an aggregate and lose the Note repository but am not sure if/how this helps.
This is cleaner way to use repositories but it will not help you with your particular error because you will still need Note and DocumentId.