How to set the _CheckinComment with CSOM (SharePoint) - c#

I'm looking for a way to set the _CheckinComment. If i try It like this:
Microsoft.SharePoint.Client.File myUploadFile = myList.RootFolder.Files.Add(fileCreationInformation);
ListItem myItem = myUploadFile.ListItemAllFields;
myItem["Title"] = Path.GetFileName(sDocPath);
myItem["_CheckinComment"] = "This is the comment";
myClientContext.Load(myItem);
myClientContext.Load(myUploadFile);
myClientContext.ExecuteQuery();
I get Microsoft.SharePoint.Client.ServerException: Invalid data has been used to update the list item. The field you are trying to update may be read only.
I want to change the _CheckinComment (InternalName) and not this:
myUploadFile.CheckIn("This is the comment", CheckinType.OverwriteCheckIn)
Who can help?

Per Microsoft, "_CheckinComment" is a read-only server field. So, that explains your error.
Although you didn't specify what you are attempting to do, I think I know as I had my own problem related to this. I think you were annoyed that you couldn't put a check-in comment on upload...and when you use the checkin() method it creates a new version. So, your upload spans two versions (the first is the upload itself with no check-in comment and the second is the addition of the check-in comment)--kind of messy.
The key for me was to use the Publish(string) [https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.file.publish.aspx] and Unpublish(string) methods. This allows you to set the check-in comment for the current file while promoting/demoting the current version to a major of minor. Assuming your document library has major and minor versions, you can apply it as follows:
Upload -> Publish(strComment) to create a major version with comment
Upload -> Publish("") -> Unpublish(strComment) to create a minor version with a comment.

Related

Set a permanent value of a variable without using a database

I don't know how to describe it thoroughly in the title, but I need to set a permanent value of a variable/flag once a process has return true and maybe set some flag in the program itself the value rather than saving it to database. And once that variable/flag has already have that value then the program won't run the process again and just use the value. Is it possible? I'm using VB.Net. I can't use the database because database can be overridden and change values by using query. Thanks in advance!
You can simply use binary/XML serialization in a file to save the state of that variable through your program. Every time you restart your app you can access the value from that file to get its current state.
You can look at this example - http://www.centerspace.net/examples/nmath/csharp/core/binary-serialization-example.php
Basically, you will not save the value in the database but in a file. Anyways you need to persist the value somewhere.
Some ways below
You did not specify if you are afraid that your application or another one could change the value
How I would do it
My ideas below
1)You could use an xml file for example and zip a copy of it with a strong password. Every time you update the first xml you will update also the encrypted zipped xml.You can use a FileSystemWatcher and capture any file change, so if something/someone has changed the file you just get a new copy from the zip
2)You can store the value in the DB and add a trigger to prevent delete/update
for example
-- delete trigger
CREATE TRIGGER Function_Value_Deleted
ON [dbo].[FunctionsValueTb]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT [Flag] FROM deleted
)
BEGIN
ROLLBACK;
RAISERROR ('Record deletion is not allowed...', 16, 1);
END
END
*You can use also use THROW rather than RAISERROR
**Do the same for the insert and update actions
***You can also store the value into a log table or send an email
I found myself in a situation quite similar to yours a couple of days ago.
In the end, I decided to use the settings functionaly provided by .NET: it is easy to use and maintain, and so far it has given me good results.
Yo can see here what I am talking about:
Best practice to save application settings in a Windows Forms Application
That thread refers to C# but is easily applicable for VB.NET: I just had to follow the same steps in order to add the Settings file:
Right click on the project in Solution Explorer, choose Properties.
Select the Settings tab, click on the hyperlink if settings doesn't
exist. Use the Settings tab to create application settings. Visual
Studio creates the files Settings.settings and
Settings.Designer.settings that contain the singleton class Settings
inherited from ApplicationSettingsBase
And then, from my code, I use the settings like this:
Dim lastExecDate As Date = My.Settings.LastSuccessfulExecution
lastExecDate = lastExecDate.AddDays(1)
// Perform my next execution and do other stuff
My.Settings.LastSuccessfulExecution = lastExecDate
My.Settings.Save()
Next time you retrieve the parameter LastSuccessfulExecution, it will have the updated value.
One more remark, as stated in the post that I linked above:
Note that you need to set the scope property of your settings. If you
select Application scope then Settings.Default.< your property > will
be read-only
Finally, I see that you are using this to store the expiration date of a product, so you don't want the user messing around with it. According to this post, the actual values of the parameters are stored in an Application Data user folder. It is somehow obfuscated since it is not that easy to find and besides it contains a hash on its name... I don't know if that is well hidden enough for you.
If you want the value only to exist in memory when the application is running then you can use the main thread of the application and use:
int slotData = randomGenerator.Next(1, 200);
//to set the data
Thread.SetData(Thread.GetNamedDataSlot("SomeDataKey"), slotData);
//to get the data
int newSlotData = (int)Thread.GetData(Thread.GetNamedDataSlot("SomeDataKey"));
Or you can use the Windows Registry if your app only runs on Windows, if not then you would have to write the value/object to a file and read it from there.

How to generate and understand a list of field names in a UniData table

I'm new to both UniData and Uniobjects so if I ask something that obvious I apologize.
I'm trying to write a tool that will let me export contacts from our ERP (Manage2000) that runs on UniData (v. 6.1) and can then import them into AD/Exchange.
The primary issue I'm having is that I don't know which fields (columns?) in the table (file?) are for what. I know that that there is a dictionary that has this information in it but I'm not sure how to get what I want out of it.
I found that there is a command LIST.METADATA in the current UniData documentation from Rocket but it seems that either the version of UniData that we are using is so old that it doesn't have this command in it or it was removed from the VOC file for some unknown reason.
Does anyone know how or have any tips to pull out the structure of a table so that I can know which fields are for what data?
Thanks in advance!
At TCL:
LIST DICT contact.master
Please note that the database file name (EX: contact.master) is case sensitive. I don't have a UniData instance at the moment to provide an example output. However, it should be similar to Universe's output:
Field......... Type & Field........ Conversion.. Column......... Output Depth &
Name.......... Field. Definition... Code........ Heading........ Format Assoc..
Number
AMOUNT.WEBB A 1 MR22 Amt WEBB 10R M
PANDAS.COST A 3 MD2Z Pandass Cost 10R M
CREDIT.EXP.DT A 6 D4/ Cred Exp Date 10R M
For the example above, you can generally tell the "data type" of the field by looking at the conversion code. "D4/" is the conversion code for a date. "MD2Z" is a numeric conversion code, which we can guess is for monetary amounts. I'm glossing over the power of conversion codes, so please make sure to reference Rocket's documentation for these codes to truly understand what these fields would output. If you don't have the documentation in front of you, you can also reference this site:
http://www.koretech.com/kr_help/KU2/30/en/KMK_Prog_Conversions.htm
If you wanted to use UniObjects and C# to retrieve the field names in a file, you could use the following code:
UniCommand fieldSelectCommand = activeSession.CreateUniCommand();
fieldSelectCommand.Command = "SELECT DICT contact.master";
fieldSelectCommand.Execute();
UniSelectList resultList = activeSession.CreateUniSelectList(0);
String[] allFieldNames = resultList.ReadListAsStringArray();
Having answered your question, I would also like to make a recommendation that you check out Rocket's U2 Toolkit for .NET if you're mostly going to be selecting data from the database instead of reading and manipulating individual records:
http://www.rocketsoftware.com/products/rocket-u2-toolkit-net
Not only does it present an ADO.NET way of accessing the database, it also has a better performance version of the UniObjects library under the U2.Data.Client.UO namespace.
The Dictionary, in my opinion, is a recommendation of how the schema should behave. However, there are cases when it's not 100% accurate. You could run "LIST CONTACT.MASTER TOXML TO MYFILE.XML" which would create an xml file what you could parse.
See https://u2devzone.rocketsoftware.com/accelerate/articles/u2-xml/u2-xml#section-0 for more information.

Does IIS Metabase return sites in Id ascending order?

I'm not sure if my question on the face of it makes full sense, so let me try and elaborate. At the moment I try and check if a website already exists in IIS by creating a new DirectoryEntry:
DirectoryEntry IISWebsites = new DirectoryEntry(MetaBasePath);
MetaBasePath is defined earlier as:
private const string MetaBasePath = "IIS://Localhost/W3SVC";
I check IISWebsites children in a foreach loop and just wondered if this will run through the children in Id order? From what I've read this is actually stored in the DirectoryEntry 'Name' property.
The reason I ask is that if the website name entered by the user in my web setup project isn't found then I want to return the highest id so I can add 1 to it and create a new website with the name supplied by the user.
Having tested this with my IIS it does seem to return it in this order but I need to be sure.
EDIT
I've found the following on Microsoft support (http://support.microsoft.com/kb/240941):
Note that when the metabase is searched for configuration information,
it is enumerated from the bottom, or subkey, to top, or node.
This seems to imply that it does do what I think, but it's not 100% clear if it works on site Id as I'm not sure how this relates to the subkey.
The documentation does not specifically define the order as by site ID so it would not be safe to assume it will always be sorted that way (particularly as your current application eventually gets used with new versions of .NET/Windows/IIS in the future).
Most likely the number of websites is not going to be big enough that enumerating them to find the max would not be a bottleneck.
Even so, you can run a search for websites and specify the order using DirectorySearcher.Sort.
Note that in regards to your edit and how configuration information is enumerated, that does not related to sort order. The one sentence taken out of context is not as clear. Read it in context of the whole paragraph and it is clear that the enumeration behavior is related to metabase property inheritance.

Setting summary info in MST using WIX

The MST created using wix does not have updated summary information stream values.
//The temp msi (copy of original msi) has updated summary info values
Database d2 = new Database(tempmsiPath, DatabaseOpenMode.Direct);
//origDatabase is a Database object of original msi;
d2.GenerateTransform(origDatabase, mstPath);
//this code is used to create the mst.
d2.CreateTransformSummaryInfo(origDatabase, mstPath,
TransformErrors.None,TransformValidations.None);
Please let me know how i can implement the writing updated summary values to MST using C#.
If I open an MSI in ORCA, create a new transform and then go to Summary Information all of the fields are greyed out.
If I then go to (in ORCA) Transform | Transform Properties I get a screen titled "Transform SummaryInfo". It has a series of checkboxes for suppress errors and validation. This maps to the arguments available in CreateTransformSummaryInfo. Reading the DTF help topic on the same method says:
Creates and populates the summary information stream of an existing
transform file, and fills in the properties with the base and
reference ProductCode and ProductVersion.
There is also a TranformInfo class in ....WindowsInstaller.Package assembly but it only supports reading transform information. Rob might be able to tell you more but it seems pretty much by design to not give unrestricted access. Probably because the transform has to be compatible with the base MSI.
Maybe if I understood exactly what/why you are updating I could give a better answer.

How to select library items that belong to a taxonomy in Ektron

I'm using Ektron CMS version 8.5 SP2.
I have some items in a taxonomy. Some are actual pages, some are library items (documents like Word files and PDFs).
Let's say there are 3 pages and 2 library items for a total of 5 items in my taxonomy.
I use the following code...
ContentManager cManager = new Ektron.Cms.Framework.Content.ContentManager();
Ektron.Cms.Content.ContentTaxonomyCriteria ctCriteria = new Ektron.Cms.Content.ContentTaxonomyCriteria();
ctCriteria.AddFilter(1707, true); // hard coded taxonomy ID
List<ContentData> list = cManager.GetList(ctCriteria);
Label1.Text = list.Count.ToString();
When this code runs, the count of items in the list is 3. If I output the actual list, I can see it's only the pages in the taxonomy, not the 2 library items.
It seems that the ContentManager.getList() function does not get library items, even when those items have been added to the taxonomy. I can confirm that in the admin workarea, the library items are visible in the taxonomy.
For clarification, this is a problem with retrieving items that have already been added to the taxonomy.
Does anyone know how I can retirieve a list of all items in a taxonomy, including any library items in there.
Note: If I add the files to the Document Managment System instead of the library, it works perfectly. But in the live system, I have hundreds of items in the library and I'm hoping theres' a way to view them via a taxonomy without having to move them all into the DMS.
I have posted this question on the Ektron developers forum as well, but I've had no reply. I'm hoping somebody here can help.
Cheers.
A follow up to my comment from the other day on #nedlud's answer, I felt like this deserved its own answer though.
According to the Framework API docs:
If intent is to retrieve CMS items that have been categorized in Taxonomies, use TaxonomyItemManager.
But as already noted in the comments, the TaxonomyItemData objects returned by this API have a number of empty properties such as QuickLink and Html. I've found that using the TaxonomyManager, one can successfully query for items assigned to particular taxonomy categories.
Here's a brief snippet using the Framework API (version >= 8.5); this feels reminiscent of working with the older (version <= 8.0) taxonomy API wherein one would create a TaxonomyRequest and get an object structure back that encapsulated not only the taxonomy iteself, but the items categorized into that taxonomy:
//e.g. for a single-level taxonomy
long taxRoot = 1707; //from OP's question
TaxonomyManager taxManager = new TaxonomyManager();
//GetTree overload supplying includeItems parameter
TaxonomyData taxTree = taxManager.GetTree(taxRoot, includeItems: true);
foreach(TaxonomyItemData taxItem in taxTree.TaxonomyItems)
{
//these should print true
Response.Write(!String.IsNullOrEmpty(taxItem.QuickLink));
Response.Write(!String.IsNullOrEmpty(taxItem.Html));
}
I'm currently refactoring some version 8.0 code into version 8.6 and converting to the Framework API. Until Ektron fixes the (bug?) of TaxonomyItemManager returning TaxonomyItemData with null properties, I'll be using the above method + LINQ for the sorting/filtering/etc.
I would look at the TaxonomyItemManager rather than the ContentManager.
Thanks to #maddoxej suggestion of using the TaxonomyItemManager, I have working solution code...
TaxonomyItemCriteria criteria = new TaxonomyItemCriteria();
criteria.AddFilter(TaxonomyItemProperty.TaxonomyId, CriteriaFilterOperator.EqualTo, 1707);
TaxonomyItemManager taxonomyItemManager = new TaxonomyItemManager();
List<TaxonomyItemData> taxonomyItemList = taxonomyItemManager.GetList(criteria);
Label1.Text = taxonomyItemList.Count.ToString();
This code now shows the expected count of "5", and I can display all the itmes :)
So many "manager" classes in Ektron.

Categories

Resources