SetProperty doesn't update all file properties on site - c#

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

Related

C# Outlook Add-in: How can I delete a User-defined property programmatically?

I have tried finding an answer to this question practically everywhere I could imagine, including here on StackOverflow. Unfortunately to no avail. So here it is.
I'm working on an Outlook Add-in (with Outlook 2021), and have developed some code that creates some ItemProperties specifically for use with that add-in. Now, when those properties are created, I can see them when I go to View->Settings->Advanced View Settings->Columns, as illustrated in the screenshot.
Screenshot of User-defined fields in Outlook
In some cases, though, I want to completely delete the properties. And as I know how to do that manually, as pointed out in the figure, I can't find out how to do that programmatically via C#. I have gone that far as to remove the properties from each mail containing that kind of property, like this:
IEnumerable<MailItem> listOfAssignedEmails = itemsToProcess.Where(
t => t.ItemProperties[MailExpiration.ExpirationDatePropertyName] != null);
foreach (MailItem email in listOfAssignedEmails)
{
// Note: The Delete() operation is deprecated. A more up-to-date method must be found.
email.ItemProperties[MailExpiration.ExpirationDatePropertyName].Delete();
email.Save();
}
... and yes, I know that the Delete() operation is deprecated; however, I couldn't find another method for removing the ItemProperty from the email (any suggestions are welcome).
Basically, the deletion of this Property is only going to be done very rarely (t. ex. if the user chooses to uninstall the Add-in. However, if there's any way to remove that property automatically, I would be happy to know.
Any suggestions will be greatly appreciated.
It is really a bad idea to remove a custom property from all emails that already have it: there is really no point since the user will never see them, but you will have to retouch (and thus change the last modified date) of a large number of emails.
Also note that named properties in MAPI are a finite resource - you can have at most 64k of them in a mailbox. Once a particular property mapping is used, you can never unmap it, even if there are no items that use that property.
Thirdly, doing anything Outlook related from an installer (rather than a VSTO addin) is a really bad idea - Windows installer runs in a service.
If you want to make sure the user no longer sees your custom fields as available properties in a view, you need to deal with the folder fields - they ar stored in a blob in a hidden (associated) message in that folder. OOM does not expose folder fields at all (if you don't count the AddToFolderFields parameter when calling UserProperties.Add). If using Redemption is an option (I am its author), it exposed RDOFolderFields object (accessible from RDOFolder2.FolderFields property) that allows to add or delete folder fields.
The list of properties shown on the screenshot belongs to the Folder.UserDefinedProperties property which returns a UserDefinedProperties object that represents the user-defined custom properties for the Folder object.
Use the ItemProperties.Remove method removes an object from the collection (from an item).
Use the ItemProperties property to return the ItemProperties collection. Use ItemProperties.Item(index), where index is the name of the object or the numeric position of the item within the collection, to return a single ItemProperty object.

TFS SDK - How can I tell what fields were changed in a revision?

I need to tell which fields were changed as part of a revision. At the moment I'm checking using
foreach (Field f in revision.Fields) {
if (Equals(f.OriginalValue, f.Value)) { continue; }
// do something with changed field
}
however, this code has an issue and that is that it doesn't list fields, which were changed but to the same value. Looking at https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.workitemtracking.client.revision(v=vs.120).aspx I don't see a way to do so, but since TFS does track this kind of thing (== visual studio & web interface both shows changed fields even to the same value), it should be possible. But I have no idea how to do so.
The history value couldn't be changed by this way: work_item.fields["History"] = "value". Workitem History are not support to changed and modified. It generates according to what you have edit on this workitem.
And this if (Equals(f.OriginalValue, f.Value)) { continue; } won't list the history field. The history field is not simple like other fields(Priority, title,etc). The Revisions represent History of workitems.
Update:
To get which fields changed in each revisions, you could try to list all info in the revisions and write method to compare them. This is an example:
http://geekswithblogs.net/TarunArora/archive/2011/08/21/tfs-sdk-work-item-history-visualizer-using-tfs-api.aspx

After commit transaction doesn't refresh data C#

My program has an entity call Articles. In one form the user can specify how many new articles he wants to buy. This happens in a form called "Purchase order". So, when that happens, the stock musk increase. In another form, where I list all the articles, it must reflect that change.
Now, this is my problem. After I generate the purchase order, if I go to the SQL and I search that article in my DB, I can see the change. If go to my form, where I list the articles, I cant see that change. But, if I close the program and then I run it again, if I search the article, the change appears.
I don't know what could be the mistake. I'm using Entity Framework.
This is how I add the article.
BaseRepository.BeginTransaction();
foreach (Documento_Articulo doc in datos.Documento_Articulo)
{
if (!articuloRepository.Increase(doc.Articulo.Id_Articulo, doc.Cantidad))
{
BaseRepository.RollBackTransaction();
return response.Error("Error: - " + doc.Articulo.Descripcion);
}
}
response.Value = documentoRepository.InsertGetDocument(datos);
BaseRepository.CommitTransaction();
I think that code does not have a problem, because as I say, I can see the change in my database.
Does anybody knows why this happens?
I suspect the client caches the results. If you set a breakpoint in the method which returns the list from the db, is it executed every time you display the it?

Updating a property using the Content Service api in Umbraco 6.x

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.

Sharepoint 2010 - SPPersistedObject.Update() doesn't update properties across different applications without iisreset

Working with Sharepoint 2010, I have a class that inherits SPPersistedObject with various settings:
[Serializable] class Settings : SPPersistedObject
{
[Persisted] private string setting1; // getters and setters etc. exist for each field
...
}
These settings (properties) are supposed to be globally accessible from the application code. Every time the value of one or more of them changes, Update() method is called so that other parts of the code (i.e. other aspx pages) may read the correct, up-to-date value.
This works fine as long as I'm only accessing properties within the same application that updated them, e.g.: http://abc:5100/.../test.aspx updates Settings.Setting1, calls Update(); and other :5100 pages will now see the new value in their code.
However - and this is my problem - when I read Settings.Setting1 property from, say, http://abc:26233 /.../temp.aspx, the old value (pre-Update) is retrieved instead of the new one. This leads me to believe that the property is read from some kind of in-memory copy instead of from the updated store. The new value is retrieved only if I manually use 'iisreset /restart' beforehand, but that is not desirable.
I would greatly appreciate it if someone has any idea on how to update/read the properties so that the change is reflected across the entire farm, i.e. the value is read from a common permanent store.
Solution found by w128:
The solution is to use the SPPersistedObject.Clone() method on your class, e.g. (not the actual code, but illustrates the point):
Settings s = (Settings)SettingsObj.Clone();
return s.Setting1; // returns updated value

Categories

Resources