I've created a custom user control for the back-end of my Umbraco site that allows administrators to quickly update certain fields on nodes without having to navigate through the content tree.
So far my code is working as expected: I can update simple true/false properties without a problem. However now I'm trying to update a property that's of a custom data type and I'm running into difficulties.
The data type itself is just a simple drop down that lists a series of availability statuses ie. Available, Unavailable, Sold and Reserved. The datatype is storing the text values.
Here's the code I have that allows me to update my true/false properties:
public void ChangeInteractiveStatus(string nodeId, bool chkValue)
{
var cs = ApplicationContext.Current.Services.ContentService;
var apartment = cs.GetById(Convert.ToInt32(nodeId));
apartment.SetValue("displayOnInteractive", chkValue);
cs.SaveAndPublish(apartment);
}
This works absolutely fine as the data type of this property is a regular true/false data type.
Here's the code I'm using to change the value of my custom dropdownlist data type:
public void ChangeAvailabilityStatus(string nodeId, string status)
{
var cs = ApplicationContext.Current.Services.ContentService;
var apartment = cs.GetById(Convert.ToInt32(nodeId));
apartment.SetValue("status", status);
cs.SaveAndPublish(apartment);
}
As you can see there's very little difference and yet this code isn't working.
In order to check what was happening when I was updating the properties with the above code, I checked the umbraco.config file only to find that the property in question was displaying as follows:
<status><![CDATA[]]></status>
However when I change the value in the content tree (without using my admin control) the value gets saved properly as:
<status><![CDATA[Sold]]></status>
So for whatever reason, when I try to update the value it's being rejected and I can't work out why.
FYI I tried entering the value as:
"<![CDATA[" + status + "]]>"
Yet that made no difference.
Does anyone know how I can fix this? How can I get the property to update correctly?
Thanks
Okay I've figured out what the problem was. It seems the values were being stored as name-value pairs, so the actual value getting stored in the database was an integer. Once I updated the code to insert the integer id it all worked as expected! Hooray.
Related
Having problem using update User with the google Admin SDK for C#.
https://developers.google.com/admin-sdk/directory/reference/rest/v1/users/update
This method supports patch semantics, meaning you only need to include the fields you wish to update. Fields that are not present in the request will be preserved, and fields set to null will be cleared.
This differs from the Patch as patch won't clear fields that are null but only update fields that have a value.
Problem is that I have to pass a full Google.Apis.Admin.Directory.directory_v1.Data.User class to the function which will contain null of even properties i do not want to clear.
example:
public User UpdateUser(Google.Apis.Admin.Directory.directory_v1.Data.User gUser)
{
UsersResource.UpdateRequest userUpdateRequest = _service.Users.Update(gUser, gUser.Id);
User updatedUser = userUpdateRequest.Execute();
return updatedUser;
}
Is there any way of modifying the Body in UpdateRequest before executing it?
Edit:
The UpdateRequest has a ModifyRequest Property that looks like this
I just have no Idea how to use it, any ideas?
public Action<HttpRequestMessage> ModifyRequest { get; set; }
As far as updating things to the concept of Null that is not something that can be done with PATCH. I recommend setting it to an empty string.
You should also not be sending the full user object if thats what you are currently doing. I am going to assume that you have done a users.list to find the user you want to update and change something in that user, say the name. Then you have simply submited the full user object to your method
UpdateUser(Google.Apis.Admin.Directory.directory_v1.Data.User gUser)
This wont work as some of the fields you have sent as part of the update/patch are not actually writeable.
What you should do instead would be to create a new user object change what ever it is you want
public User MakeUserAdmin(Google.Apis.Admin.Directory.directory_v1.Data.User gUserId)
{
var updateFields= new Google.Apis.Admin.Directory.directory_v1.Data.User();
change.IsAdmin = true;
change.Addresses = ""; // will set it to empty yes not null but the best you can do with this api.
UsersResource.UpdateRequest userUpdateRequest = _service.Users.Update(updateFields, gUserId);
User updatedUser = userUpdateRequest.Execute();
return updatedUser;
}
Notice how you just need to create a new object and update only the fields you need then send that.
Dont try to update every field, just update the ones that you know have changed. Dont include the id in the object that is not writeable either.
On a SharePoint 2010 site, I have an ItemAdded event receiver which detects pages added to the Pages library, fills it with information from a file, and from that information sets some custom columns so that the pages can be searched based on their contents. The portion of the function that sets the columns is similar to this:
page.SetProperty("Column1", ExistsOrEmpty("Property1", dictionary));
page.SetProperty("Column2", ExistsOrEmpty("Property2", dictionary));
...
page.Update();
Where page is of type SPFile and is the page that has been added to the library. ExistsOrEmpty is a function I wrote to prevent a KeyNotFound exception:
private static string ExistsOrEmpty(string key, Dictionary<string, string> dict)
{
try
{
return dict[key];
}
catch
{
return "";
}
}
My issue is that there is one column in particular, Description, that isn't updated on the site, even though the rest are updated without any problems. Here are the steps I've taken to debug this code when stepping through line by line:
I make sure ExistsOrEmpty("Description", dict) returns the correct value, which it does.
I execute page.SetProperty("Description", ExistsOrEmpty("Description", dict)), along with all of the other properties I wish to set. All of the properties I update are single-line strings.
I update the page using page.Update().
I check the page's properties using page.GetProperty to confirm that all properties have been updated correctly, which they have.
I finish debugging and check the page's properties on the SharePoint site itself using View Properties. All the properties I've set except the Description have been updated.
I can't imagine why this one column wouldn't update when the others have updated without a problem. Am I missing something?
EDIT: I've done some tweaking to try to fix this issue, and it has begun happening for multiple other columns as well. I noticed that, for the other columns, the error occurs where the column name used to have a space and I removed it. I've made sure to update my code to account for these changes, and my debugger still shows the columns as being updated, but the UI does not reflect these changes. Using internal names rather than display names fixed this problem, but not the main problem I'm having with the Description.
Can you try this please.
Your SPFile object should have an SPListItem object on it.
it will be something like page.item["Description"] = "desc"
Then call an update.
Cheers
Truez
There are some posts about this, but nothing specific that works in my project.
I read the docs on Breeze about Extending Entities, but they use knockout and I am using Angular.
I have defined a custom property on the server and it is being passed down in my JSON.
However, Breeze js ingnores it because there is no meta data for it.
I need to define the meta data on the client so that Breeze can read the property.
Here is what I have the client so far, but it does not work. By not working... I mean when I call it with {{item.MyProp}} nothing ever shows up on the screen. However, all the other properties from the actual meta data show up just fine.
configureBreeze();
var serviceName = 'api/Entity';
var manager = new breeze.EntityManager(serviceName);
manager.enableSaveQueuing(true);
var store = manager.metadataStore;
addMyPropType(store);
function addMyPropType(store) {
store.registerEntityTypeCtor("Merchant", MyProp);
}
// custom Merchant constructor
var MyProp= function () {
//'MyProp' is a server-side calculated property of the Merchant class
// This unmapped property will be empty for new entities
// but will be set for existing entities during query materialization
this.MyProp= "test";
};
var dataservice = {
store: store,
List: List,
Create: Create,
ListDetail: ListDetail,
Save: Save
};
return dataservice;
I have ready the NODB sample, but I do have a DB and it also uses KO.
UPDATE:
Ok. So I found something that partially works. The default value is now getting displayed on the view. However, the value from the JSON is not being filled in. It always uses the default value.
This is what I have now:
var Merchant = function () {
this.MyProp = "5";
};
store.registerEntityTypeCtor("Merchant", Merchant);
What needs to happen for MyProp to be filled by the actual value from the JSON?
If camelCasing is not your case as PWKad suggested then check breeze documentation for the Breeze Angular SPA template here http://www.breezejs.com/samples/breezeangular-template . There is a section in that link called "Extending entity definitions on the client" .
If I understand correctly you have a "Merchant" object with a "MyProp" calculated property. Try this
store.registerEntityTypeCtor("Merchant",Merchant, merchantInitializer);
function Merchant(){
this.MyProp="";
}
Well, it seems this is a bug in Breeze. You actually have to edit the breeze.js file to get it working. I never would have thought it was a bug.
I found the answer here:
Breeze Extended Entity Property Only Loads on Second Query
UPDATE:
Today I updated to the latest version of breeze.js and the bug does not exist anymore. So this was basically a lot of pain for no reason. Thanks everyone for the help. If you cannot update for some reason use the link above.
I'm using WSS3 and C# to create site and I am creating a class to change fields on lists after they have been created. I have already created an SPField.Boolean type with no default value, but after upgrade I need the default value to be set to true. My current code that does not work follows:
//web is already defined as the current web
var list = web.Site.RootWeb.Lists["ListWithFieldOnIt"];
var field = list.Fields.GetField("booleanfield");
field.DefaultValue = "1";
field.Update(true);
list.Update(true);
I have tried to change the default value through the sharepoint instance and sharepoint manager 2007 and neither of those have worked. Does anyone know of any way to set the default value or what I am doing wrong?
Thanks in advance
Looks like you're doing it correctly according to Programmatically setting the default value of a SPFieldBoolean field. I can't see anything really wrong. My only suggestion would be to try the Update calls without the boolean parameter. From MSDN, SPField.Update Method (Boolean) seems to be meant for site columns rather than columns within a list. Whenever I'm updating a field or list in code, I almost always use the parameterless Update method.
Code below should be more than enough to update list field definition:
var list = web.Site.RootWeb.Lists["ListWithFieldOnIt"];
var field = list.Fields.GetField("booleanfield");
field.DefaultValue = "1";
field.Update();
You don't need to update the list or pass 'true' to SPField.Update method.
Here's my scenario - I am working with SL3 (and WCF Data Services) and I have a custom form that manages Employees. On the form, I have some simple TextBox(es) and some ComboBox(es) for entering basic information for an Employee. In my architecture, I have some base classes, one to handle the Collections of objects (ObservableCollection and INotifyPropertyChanged implemented) and one that is for the Entity (catches and calls OnPropertyChanged("prop"). In my code behind file (.cs), I have an event handler that handles the _SelectedItemChanged() for the ComboBox(es), for example, EmployeeType, where in the database, values might be like Director, Staff, Reporter, Manager, etc. for the Code column (other columns exist in the EmployeeType table like Description, ModifiedDate, and ID). I have some constructors on my form control, and when I load the form with an empty constructor and thus nothing is loaded (which is the way it should load and correct), everything works perfectly, i.e. I can enter data like FirstName (TextBox), HireData (TextBox), and EmployeeType (ComboBox). The issue I am having is when, I am loading this form, and I know the EmployeeType before-hand, so I don't know how to set the ComboBox's SelectedItem programmatically?
I tried something like this, say I want the form to load the EmployeeType as Manager, so I have in my Load() method:
private SetEmployeeType()
{
var employeeType = new EmployeeType { Code = "Manager" };
this.EmployeeTypeComboBox.SelectedItem = employeeType;
}
But as I'm tracing through my code (F5), I see employeeType as an EmployeeType, but it's properties not fully populated (all blank except for Code as I explicitly called "Manager" above), so when my _SelectedItemChanged() event is called, the .SelectedItem = null, and thus the ComboBox is loaded with nothing picked (the ItemSource is bound to a list and it does come through properly).
FYI, I have other methods where I load my list of EmployeeTypes, e.g. GetEmployeeTypes() and that loads fine. If the ComboBox is blank and then I pick a value, the correct value is submitted to the database, but like I noted, sometimes I want to pre-define the SelectedItem and thus disable the ComboBox to disallow the User from entering invalid data.
I even tried some LINQ like so and it seems not to work:
var type = from e in employeeTypeList // collection loads fine with 10 items
where e.Code = "Manager"
select e;
When I trace through the above query, the 'type' does come back with the correct EntityType object with all of the properties populated (count=1 which is correct), but it doesn't seem to bind to the ComboBox since the ComboBox's SelectedItemChanged() is expecting something like this:
var employeeType = this.EmployeeType.SelectedItem as EmployeeType; // i.e. expecting EmployeeType
but instead, my LINQ query brings back a value of something like:
IEnumerable<EmployeeType> // with some extra stuff...
PS. I am working off from memory since I am currently at home and this is from my code at work, so please excuse me if I am missing something obvious. I have tried different scenarios, and just can't seem to figure it out. Thanks in advance for any assistance!
It sounds like you want to set the selected item to be the manager.
If so, you want something like this:
var type = (from e in employeeTypeList
where e.Code = "Manager"
select e).FirstOrDefault();
EmployeeType.SelectedItem = type;
Your code is creating a list of managers, which even though it has only one item, does not match the data type expected by SelectedItem. The solution to this is to just extract the one item from the list using FirstOrDefault which will give the first item in the list or null if the list is empty.
Try to set the mode to TwoWay instead of Oneway if you have set so.