so in our Jira, we have a custom field "X" that is empty by default. To my surprise, it is not returned at all when listing through CustomFields of a newly created issue, and therefore I cannot simply use:
issue.CustomFields["X"].Values == ...
because such a field would not be found.
It only becomes available in the RestAPI when a user enters some data via Jira UI. However, I would need to be able programmatically to initialize this field in certain cases but I cannot figure out how.
EDIT:
I test if the field is there:
if (x.CustomFields.Where(CustomField => CustomField.Name=="X").Count()==0)
{
//NOT FOUND - I need to initialize it (cannot just set its value for the reasons stated above}
}
Thanks a lot
Related
I created a mapping for my Kofax Export Connector. This connector interacts with an external application using webservices.
I want to connect the indexfield values to field IDs of the external application. Currently I have a dictionary containing the ID of the external application and the index field ID.
Dictionary<double, double?> // external fieldID <-> indexfieldID
The key is nullable because a field might not be assigned. Instead of passing the indexfieldID to the external application I want to pass in the value of this indexfield.
Currently I have this
releaseSetupData.CustomProperties.Add("MetaFieldID", "IndexFieldID");
and the desired result would be
releaseSetupData.CustomProperties.Add("MetaFieldID", "IndexFieldValue");
How do I get the value of the index field? The indexfield itself has no "value" property and the Kofax user is able to setup a custom field with a custom dataType. So how would a value look like?
I don't get it from the Kofax Capture Export Type Library API Reference Guide
Generally speaking, Kofax organizes any kind of mapped data as so-called Links. However, it does not take care of mapping anything on its own, that is our job (for some reason). You will find two different objects at your disposal:
Your setup script will contain a reference to a ReleaseSetupData object, usually named SetupData.
Your release script has another reference to a ReleaseData object, namely DocumentData.
Now, all links established during setup time will become available during release time. Said links can contain different kinds of data, for example index fields, batch fields, Kofax values, or custom properties. Now, let's say you have the index field "FirstName" on your document class, and you do want to access its value during release time - here's what you need to do.
Setup Script
setupData.Links.Add(
setupData.IndexFields["FirstName"].Name,
KfxLinkSourceType.KFX_REL_INDEXFIELD,
setupData.IndexFields["FirstName"].Name);
setupData.Apply();
Please keep in mind that those links are similar to dictionary entries, so you can't link the same item twice. I usually like removing all links when my setup script loads, and add them again when it unloads again (and note that you can safely loop over the setupData.Indefields collection to add all fields instead of just a single one).
Release (Run) Time
During release, all links are then made available in the DocumentData.Values collection. To access your index field and its value, here's what you need to do. The following assumes you already set up a Dictionary<string, string> named IndexFields, and it further shows you how to access all other kinds of links (batch fields, custom properties, et cetera):
foreach (Value v in DocumentData.Values)
{
switch (v.SourceType)
{
case KfxLinkSourceType.KFX_REL_BATCHFIELD:
BatchFields.Add(v.SourceName, v.Value);
break;
case KfxLinkSourceType.KFX_REL_DOCUMENTID:
break;
case KfxLinkSourceType.KFX_REL_INDEXFIELD:
// index fields may also contain table fields
if (v.TableName == "")
{
// this is a regular index field
IndexFields.Add(v.SourceName, v.Value);
}
else
{
// this is a table field!
}
break;
case KfxLinkSourceType.KFX_REL_TEXTCONSTANT:
TextConstants.Add(v.SourceName, v.Value);
break;
case KfxLinkSourceType.KFX_REL_UNDEFINED_LINK:
break;
case KfxLinkSourceType.KFX_REL_VARIABLE:
break;
}
}
If you wanted to map Kofax Index Fields to some external ID, you could safely do so using Custom Properties. Example: you can assign the id 42 to FirstName during setup (just create a property grid with a custom class), add the Custom Property during setup time, and then access its value during release. That way you could maintain ids via the setup form without the need to ever rebuild your solution.
I am using the Microsoft.Graph library which I got off of Nuget. I have a problem regarding change tracking using deltas. Suppose
I am getting changes to users using something like the code below:
var usersDeltaRequest = client
.Users
.Delta()
.Request(usersDeltaLink == null ? new Option[0] : new []
{
new QueryOption("$deltatoken", usersDeltaLink)
});
var users = await usersDeltaRequest.GetAsync();
foreach (var user in users)
{
//code that updates the user goes here
}
My problem is that in this case, what gets returned is a User object. However since this is a delta, not all the fields in the object get populated. Only the ones that have been changed are guaranteed to be populated.
Now were I to parse the JSON returned manually, it would be easy to see which fields have actually been included in the response, since only those will be included in the JSON.
However, the library returns a User object and leaves the fields which haven't been returned as null. In this case, it does not seem possible to disambiguate between a field which simply hasn't been returned in the delta vs a field that actually does contain a null value.
Is there something I'm missing in how the library should be used? Because as it stands, it appears as if the library does lose some critical information, because I can't rely on the returned User object to reliably update my database, because a changed field containing a null value and a field that hasn't changed both result in a null value in the returned .Net object.
This obviously also applies to other types of resources, I just chose Users for the example.
As I read the API docs at https://developer.microsoft.com/en-us/graph/docs/concepts/delta_query_users it sez:
The optional $select query parameter is included in the request to
demonstrate how query parameters are automatically included in future
requests.
I haven't tried this. Did you include the properties you want to track changes for on your original request? Or perhaps try $select=* to return everything? The API sez:
By default, only a limited set of properties are returned
(businessPhones, displayName, givenName, id, jobTitle, mail,
mobilePhone, officeLocation, preferredLanguage, surname,
userPrincipalName).
I wanted to know the difference between these 3 Settings.Default.<PropertyName> , Settings.Default.Properties and Settings.Default.PropertyValues .
I have a wpf window that would dynamically generate controls based on these Settings and then one can update the Settings values
I first used Settings.Default.Properties Collection , but I believe it does not update the values in either config or the physical settings file in the user folder.
So I used reflection to update , But I still couldn't figure how to obtain
values by Reflection . (May still need to research on this)
Settings.Default.GetType().GetProperty(propertyName,
typeof(string)).SetValue(source, fileDialog.FileName, null);
Settings.Default.Save();
Settings.Default.Reload();
Then I saw Settings.Default.PropertyValues has the latest updated values and tested that in debug mode,
string properyValue =
Convert.ToString(Settings.Default.PropertyValues[propertyName].PropertyValue);
strangely they don't seem to be working when I created the installer and exe . Still to figure what exactly wrong.
Can someone point me out if I am complicating things and missing something?
Update 1
After nflash's comment , I checked when the file was created. The file was not created when the application starts for all 3 , I even called Settings.Default.Save right at the start but it doesn't create the file Settings.Default.<PropertyName> , Settings.Default.Properties are instantiated but Settings.Default.PropertyValues not.
Only once I make a change in the Settings and Save , the file is created.
Update2
Right now the solution that I came with is
source.GetType().GetProperty(setting.Name, typeof(string))
.SetValue(source, "NewValue", null);
As mentioned by nflash , it would be type safe (Although Reflection has it's demirits) . But the Settings.Default.<PropertyName> is synchronized and instantiated correctly hence.
Just want to add that you can only change settings with "User" scope. When you save the new value of the setting the value is not saved in the config in the application path but instead it is saved in the user.config inside the %localappdata% folder (%localappdata%\CompanyName\ApplicationName_someGUID\AppVersion)
Update:
About your last update, the user.config file is only created when you save a setting with a value different from the default value of the setting.
I'm not sure if you still have questions about this, so I'm trying to add more info:
Settings.Default.<PropertyName> as wonko79 pointed out is just a property accessor to the corresponding value. If you look at the code behind the settings (or just Go To Definition of the property) you will see something like this:
public string PropertyName {
get {
return ((string)(this["PropertyName"]));
}
set {
this["PropertyName"] = value;
}
}
The array operator is accessing the underlying structure that holds the values that in fact is the PropertyValues.
The difference between the Properties and PropertyValues is a little bit trickier. These are really two different structures (one is a SettingsPropertyCollection and the other is a SettingsPropertyValueCollection). The Properties property is defined in the ApplicationSettingsBase class and the PropertyValues is defined in the SettingsBase class.
The SettingsProperty class (elements of the SettingsPropertyCollection) contains information about the setting itself (metadata?) and its default value.
The SettingsPropertyValue class (elements of the SettingsPropertyValueCollection) contains the actual value of the setting and some additional control information, like if the value is dirty, if it is using default value, etc.
In the end of the day this is all how .NET internally manages the Settings and all that we need to know is how to get and set these settings.
I always like to work with the properties that the setting designer generates as it is strongly typed and already makes the cast to the corresponding type. Also using the Properties or PropertyValues requires a string as a parameter and in case of a typo I will only get an error in runtime as opposed to the compile error that I get if misspell the name of the property.
To save the settings after changing them you have to call
Settings.Default.Save();
Settings.Default.<PropertyName> is a property accessor to the corresponding settings value.
Settings.Default.Properties is a collection of all settings in your settings file.
Settings.Default.PropertyValues is a collection of all values of the settings in your settings file.
Maybe Using Settings in C# is a good starting point to read.
The article mentioned by user1064248 is good info, but does not address the PropertyValues issue. I cannot add anything to the good advice from Rameez and nflash except for this pragmatic advice: If you wish to force PropertyValues to populate, you need only to force a value to change. In my settings I have a DateTime property called "Timestamp" and if you put this in the form Load event, you will find that nn1 is zero, and nn2 contains the count all of the properties:
int nn1 = Properties.Settings.Default.PropertyValues.Count;
Properties.Settings.Default.Timestamp = DateTime.UtcNow; // Forces PropertyValues to load
int nn2 = Properties.Settings.Default.PropertyValues.Count;
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
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.