I am trying to save a setting in Kentico and I get this error:
The settings key with code name 'AvalaraOrderStatus' already exists.
I already created the setting and I have saved a value to it. The code worked fine in Kentico 8, but I was asked for no SiteInfiIdentifer.
Here is the code I created to make the setting:
//if the setting does not exist, then create it
if (SettingsKeyInfoProvider.GetSettingsKeyInfo(siteName + ".AvalaraOrderStatus", siteID) == null)
{
// Create and set up new SettingsKey
SettingsKeyInfo si = new SettingsKeyInfo();
si.KeyName = "AvalaraOrderStatus";
si.KeyDisplayName = "Avalara Order Status";
si.KeyDescription = "Avalara order status for this site";
si.KeyType = "string";
si.KeyValue = string.Empty;
si.KeyCategoryID = category.CategoryID;
SettingsKeyInfoProvider.SetSettingsKeyInfo(si);
}
The code throws the error on the last line. Here is my code:
int currentSiteID = CMS.SiteProvider.SiteContext.CurrentSiteID;
SiteInfoIdentifier siteId = new SiteInfoIdentifier(currentSiteID);
//update settings in system
SettingsKeyInfoProvider.SetValue(siteName + ".AvalaraOrderStatus", siteId, orderStatus.Trim());
A few things to note:
The first parameter of the SettingsKeyInfoProvider.GetSettingsKeyInfo method does not need to be prefixed with the site name. This is why a site identifier is provided (in your case, the SiteID). Otherwise, you might be getting a null value every time the if statement evaluates, which is why the setting key is being recreated even if it exists. So that should be:
SettingsKeyInfoProvider.GetSettingsKeyInfo("AvalaraOrderStatus", siteID)
The same applies for the SettingsKeyInfoProvider.SetValue method - no need to prefix the site name:
SettingsKeyInfoProvider.SetValue("AvalaraOrderStatus", siteId, orderStatus.Trim())
The CurrentSiteID integer is a valid SiteIdentifier, so there is no need to explicitly instantiate a SiteInfoIdentifier object:
SettingsKeyInfoProvider.SetValue("AlavaraOrderStatus", CMS.SiteProvider.SiteContext.CurrentSiteID, orderStatus.Trim())
Related
So here's the case: I am trying to create a Task WorkItem. I have to get the data from a dataGridView, which I think I managed to. But the fun part comes when I try to save, or validate the WorkItem. No matter what value State has, the validator always comes with InvalidListValue on execution of wiTask.Validate();. I have tried even hard-coding the State's value, but nothing happens. There is one thing that bothers me a bit - in the Validation array the error comes within the Status property, where the actual control has only State available. Here are some code and a snippet of the error bit:
WorkItem wiTask = new WorkItem(workItemType)
{
Title = form1.dg_taskView.Rows[rows].Cells["titleDataGridViewTextBoxColumn"].Value.ToString() + " " + form1.tb_details.Text,
Description = form1.dg_taskView.Rows[rows].Cells["descriptionDataGridViewTextBoxColumn"].Value.ToString(),
AreaId = int.Parse(form1.dg_taskView.Rows[rows].Cells["areaIDDataGridViewTextBoxColumn"].Value.ToString()),
AreaPath = form1.dg_taskView.Rows[rows].Cells["areaPathDataGridViewTextBoxColumn"].Value.ToString(),
IterationId = int.Parse(form1.dg_taskView.Rows[rows].Cells["iterationIDDataGridViewTextBoxColumn"].Value.ToString()),
IterationPath = form1.dg_taskView.Rows[rows].Cells["iterationPathDataGridViewTextBoxColumn"].Value.ToString(),
State = form1.dg_taskView.Rows[rows].Cells["stateDataGridViewTextBoxColumn"].Value.ToString()
};
ArrayList result = wiTask.Validate();
wiTask.Save();
var hierarchicalLink = _workItemStore.WorkItemLinkTypes["System.LinkTypes.Hierarchy"];
userStory.WorkItemLinks.Add(new WorkItemLink(hierarchicalLink.ForwardEnd, wiTask.Id));
userStory.Save();
As it turns - the validation returns to the array the column that has issues. After further examination the issue is resolved by specifying to Assigned to name, which is part of the project contributors' list.
I am posting this because it might help someone using the VersionOne API SDK Client. I wanted to change the status of a test programmatically, to one of the following categories: Ready, InTesting, Passed, or Failed. I originally tried to change the attribute 'Status.Name' however I would get an error that the attribute is a Read-Only attribute. Another suggestion was to create a new attribute with the same name and that the new attribute would override the previous read-only attribute with the same name. However, it appears that I was looking at it backwards.
internal void TestStatusPassed(string str_TestID)
{
var testId = Oid.FromToken(str_TestID, _context.MetaModel);
var query = new Query(testId);
var testType = _context.MetaModel.GetAssetType("Test");
var sourceAttribute = testType.GetAttributeDefinition("Status.Name");
query.Selection.Add(sourceAttribute);
var result = _context.Services.Retrieve(query);
var test = result.Assets[0];
var oldSource = GetValue(test.GetAttribute(sourceAttribute).Value);
test.SetAttributeValue(sourceAttribute, "Passed");
_context.Services.Save(test);
}
This code will throw an exception "Cannot change a read-only attribute"...
I pulled the XML data for one test from the VersionOne Rest API and noticed a relation named "TestStatus" and then it had a number '9123' assigned to it. So I moved that test manually to 'In Testing' and the "TestStatus" changed to '9121'. Then I moved it to failed and the "TestStatus" changed to '155'. I repeated this with several tests from different testsets and noticed that the numbers for each status were consistent and then changed the code slightly and then I was able to programmatically change the status of each test. I changed "Status.Name" to "Status" and "Passed" to "TestStatus:9123" and now it moves the test into the passed category programmatically.
internal void TestStatusPassed(string str_TestID)
{
var testId = Oid.FromToken(str_TestID, _context.MetaModel);
var query = new Query(testId);
var testType = _context.MetaModel.GetAssetType("Test");
var sourceAttribute = testType.GetAttributeDefinition("Status");
query.Selection.Add(sourceAttribute);
var result = _context.Services.Retrieve(query);
var test = result.Assets[0];
var oldSource = GetValue(test.GetAttribute(sourceAttribute).Value);
test.SetAttributeValue(sourceAttribute, "TestStatus:9123");
_context.Services.Save(test);
}
I am trying to update the "ModifiedBy" field in a Sharepoint discussion board using the Client Object Model. By changing the "Editor" and "Author" fields, I can change the "ModifiedBy" that appears on the list view. However, once you click on a discussion post, the "ModifiedBy" field that appears there (the one with the picture above it) does not reflect the changes. After experimenting, I discovered that the field I need to change to correct this is called "MyEditor". Unfortunately, this field is read-only.
In the code below, I try to change the read-only settings of the field to false. When I look at the MyEditor field in Visual Studio's debugger after the ExecuteQuery() line at the bottom of the first block, it shows that the ReadOnlyField value has in fact been set to false.
sharepointContext.Load(discussionList);
sharepointContext.ExecuteQuery();
var fields = discussionList.Fields;
sharepointContext.Load(fields);
sharepointContext.ExecuteQuery();
var field = fields.GetByInternalNameOrTitle("MyEditor");
field.ReadOnlyField = false;
field.Update();
sharepointContext.Load(field);
sharepointContext.ExecuteQuery();
The code above executes with no problems. The problem comes with this next block:
//...Code to initialize discussionItem...
discussionItem["MyEditor"] = 0;
discussionItem["Editor"] = 0;
discussionItem["Author"] = 0;
discussionItem["Body"] = "Testing";
discussionItem["Title"] = "Hello Worlds";
discussionItem.Update();
sharepointContext.Load(discussionItem);
sharepointContext.ExecuteQuery();
When the code reaches the ExecuteQuery() at the bottom of the second block, it throws a ServerException with the following message:
Invalid data has been used to update the list item.
The field you are trying to update may be read only.
To make sure that the MyEditor field was the one causing the exception to be thrown, I commented out the line where I set it and ran the code again. Everything worked fine. I don't understand what is wrong, can someone help me?
In case someone needs to find the user by name, it goes like this:
private static FieldUserValue GetUser(ClientContext clientContext, string userName)
{
var userValue = new FieldUserValue();
var newUser = clientContext.Web.EnsureUser(userName);
clientContext.Load(newUser);
clientContext.ExecuteQuery();
userValue.LookupId = newUser.Id;
return userValue;
}
The returned value can be set via item["Author"]
ModifiedBy and CreadtedBy calculated automatically from Author and Editor you need to change only Author and Editor fields like this:
using (var clientContext = new ClientContext(#"http://server"))
{
var web = clientContext.Web;
var lst = web.Lists.GetByTitle("Discus");
var item = lst.GetItemById(2);
item["Author"] = 3;
item["Editor"] = 2;
item.Update();
clientContext.ExecuteQuery();
Console.WriteLine("done");
}
I'm attempting to fill in data to my NCCMembershipUser with the following code:
string name = User.Identity.Name;
NCCMembershipUser currentUser = (NCCMembershipUser)NCCMembershipProvider.GetUser(name, true);
currentUser.Salutation = GenderSelect.SelectedValue;
currentUser.FirstName = TextBoxFirstName.Text;
currentUser.LastName = TextBoxLastName.Text;
currentUser.Position = TextBoxPosition.Text;
...
try
{
NCCMembershipProvider u = (NCCMembershipProvider)Membership.Provider;
u.UpdateUser(currentUser);
}
I am getting an error "An object reference is required for the non-static field, method, or property 'System.Web.Security.MembershipProvider.GetUser(string, bool)'"
If I instead use Membership.GetUser() (without the name string) to access the current user, it gives me a casting error, and GetUser() appears it cannot be overridden.
Edit:
The casting error I get is "[A]NCC.App_Code.NCCMembershipProvider cannot be cast to [B]NCC.App_Code.NCCMembershipProvider."
The error tells you that the GetUser method isn't static, so it cannot be invoked without an instance of the NCCMembershipProvider class.
You have to grab your provider earlier in your method:
string name = User.Identity.Name;
NCCMembershipProvider u = (NCCMembershipProvider)Membership.Provider;
NCCMembershipUser currentUser = (NCCMembershipUser)u.GetUser(name, true);
currentUser.Salutation = GenderSelect.SelectedValue;
currentUser.FirstName = TextBoxFirstName.Text;
currentUser.LastName = TextBoxLastName.Text;
currentUser.Position = TextBoxPosition.Text;
// ...
try
{
u.UpdateUser(currentUser);
}
The casting error I get is "[A]NCC.App_Code.NCCMembershipProvider
cannot be cast to [B]NCC.App_Code.NCCMembershipProvider."
For this error, verify that you don't have that class in your App_Code folder, if so, move it to another place like a new folder called Membership
That will take care of the casting issue as the app is compiling 2 different DLLs into 2 different places in the temporary asp.net folders.
My project requires me to programmatically access TFS servers we don't administer and to get real time information about the fields in the WorkItemTypes. I can get the field names and most of the information I need by looking at the FieldDefinition in the WorkItemType's FieldDefinitions collection.
public WitType(WorkItemType type)
{
this.Fields = new List<string>();
foreach (FieldDefinition f in type.FieldDefinitions)
{
Fields.Add(f.Name);
}
}
One thing missing is the IsRequired property. I need to be able to tell if a field is required.
I have tried running a work item story query
WorkItemCollection workItemCollection = workItemStore.Query
foreach (WorkItem workItem in workItemCollection)
foreach (Field field in workItem.Fields)
{
textBox1.Text += field.Name + " is required? " + field.IsRequired.ToString();
}
and then checking the IsRequired property of the Field item in the WorkItem's Fields collection.
Only problem is that for a given work item type one work item says Title is required, then the next work item will have the IsRequired property = false.
Is there a way to determine if a WorkItem field is required without resorting to the WIT xml file? If not, is there a way to programmatically access the WIT xml file?
I needed to perform a similar task, and the following was the only way I could figure out how to accomplish it.
As mentioned by others, WorkItem validation is defined in the WorkItemType's template. Fields can have different validation requirements based on the WorkItem's current state and even the current user's permissions.
Therefore, you need to create/retrieve a WorkItem instance using the user's credentials. If your application is impersonating the current user (i.e. in an ASP.NET application using Windows Authentication and impersonation), then you can simply use Option 1, where you use the TFS API to get the WorkItem, without impersonating.
If you're application is not impersonating the user, when you can use Option 2, where you use the TFS impersonation feature, to make calls on-behave of a user. This requires granting the "Make Requests on behave of others" permission in TFS to the application's identity (i.e. in ASP.NET the application pool's identity). See the following link for more information:
http://blogs.microsoft.co.il/blogs/shair/archive/2010/08/23/tfs-api-part-29-tfs-impersonation.aspx
The following code is an example on how to do Option 1 and Option 2.
// Set the following variables accordingly
string workItemTypeName = "Bug";
string teamProjectName = "My Project";
string usernameToImpersonate = "joesmith";
string tfsTeamProjectCollectionUrl = "http://mydomain.com:8080/tfs/ProjectCollectionName";
// OPTION 1: no impersonation.
// Get an instance to TFS using the current thread's identity.
// NOTE: The current thread's identity needs to have the "" permision or else you will receive
// a runtime SOAP exception: "Access Denied: [username] needs the following permission(s) to perform this action: Make requests on behalf of others"
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection( new Uri( tfsTeamProjectCollectionUrl ) );
IIdentityManagementService identityManagementService = tfs.GetService<IIdentityManagementService>();
// OPTION 2: impersonation. Remove the following two lines of code if you don't need to impersonate.
// Get an instance to TFS impersonating the specified user.
// NOTE: This is not needed if the current thread's identity is that of the user
// needed to impersonate. Simple use the ablve TfsTeamProjectCollection instance
TeamFoundationIdentity identity = identityManagementService.ReadIdentity( IdentitySearchFactor.AccountName, usernameToImpersonate, MembershipQuery.None, ReadIdentityOptions.None );
tfs = new TfsTeamProjectCollection( tfs.Uri, identity.Descriptor );
WorkItem workItem = null;
WorkItemStore store = tfs.GetService<WorkItemStore>();
// Determine if we are creating a new WorkItem or loading an existing WorkItem.
if( workItemId.HasValue ) {
workItem = store.GetWorkItem( workItemId.Value );
}
else {
Project project = store.Projects[ teamProjectName ];
WorkItemType workItemType = project.WorkItemTypes[ workItemTypeName ];
workItem = new WorkItem( workItemType );
}
if( workItem != null ) {
foreach( Field field in workItem.Fields ) {
if( field.IsRequired ) {
// TODO
}
}
}