Please, can you help me create/update items from custom fields that have space within their name?
We have a project with a custom field Contact phone. This field can be used correctly from the browser. https://github.com/Workfront/workfront-api-examples-csharp didn't help. I was able to add the data within the details of the issue. I would like to add it within the specific custom field (create/update).
var client = new AtTaskRestClient(_url); // from the example
...
var description = $"Contact phone: {item.ContactPhone}";
client.Create(ObjCode.ISSUE, new { name = item.Name,
description = description,
projectID = _projectID });
client.Create has an object as final parameter. We use an anonymous type that can't contain "DE:Contact phone" = item.ContactPhone within the constructor. How can we write this field?
Reading DE:Contact phone works correctly if we insert the value from the browser:
JToken issues = client.Search(ObjCode.ISSUE, new { projectID = _projectID });
foreach (var issue in issues["data"].Children()) {
var name = issue.Value<string>("name"); // correct
var id = issue.Value<string>("ID"); // correct
var fields = client.Get(ObjCode.ISSUE, id, new[] { "description", "DE:Contact phone"}); // correct
https://github.com/Workfront/workfront-api-examples-csharp/blob/master/AtTaskRestExample/AtTaskRestClient.cs
public JToken Create(ObjCode objcode, object parameters) {
VerifySignedIn();
string[] p = parameterObjectToStringArray(parameters, "sessionID=" + SessionID);
JToken json = client.DoPost(string.Format("/{0}", objcode), p);
return json;
}
I wrote a new function CreateEx, that receives a string array
public JToken Create(ObjCode objcode, string[] parameters) {
VerifySignedIn();
JToken json = client.DoPost(string.Format("/{0}", objcode), parameters);
return json;
}
It is accessed as follows:
var client = new AtTaskRestClient(_url); // from the example
...
string[] parameteres =
{
$"name={issueName}",
$"description={description}",
$"projectID={_projectID}",
$"sessionID={client.SessionID}",
$"DE:Contact phone={contactPhone}"
};
client.CreateEx(ObjCode.ISSUE, parameteres);
Related
So the problem I have is that I want to be able to filter on a particular criteria.
I originally tried to filter based on the datatype of the field, I am struggling to do this with arrays though. This did work at one point with single fields, but now not having much joy.
Then as part of the update I want to set specific fields inside the array from string datatype to say integer.
So to summarise I want to do the following:
Filter where the fields in the array are string datatype as I want to update them.
Update only the datatype and retain the value(essentially converting from string to integer)
Get results with modified count to ensure it was successful.
Thanks in advance.
var mongoDb = mongoClient.GetDatabase(config.DatabaseName); // , new MongoDatabaseSettings() { WriteConcern = WriteConcern.Unacknowledged }
var objectId = new ObjectId("63d38c71ef08fde3fbf1b9da");
var filter = Builders<BsonDocument>.Filter.Eq("_id", objectId);
var updateQuery = new BsonDocument { { "$set", new BsonDocument { { "CheckFinalization.Check.ItemDetail.$[].ItemNumber", new BsonDocument { { "$toInt", "$CheckFinalization.Check.ItemDetail.$[].ItemNumber" } } } } } };
var updatePipeline = Builders<BsonDocument>.Update.Pipeline(PipelineDefinition<BsonDocument, BsonDocument>.Create(updateQuery));
var dataCollection = mongoDb.GetCollection<BsonDocument>(config.CollectionName);
var recordResult = dataCollection.Find(filter).Limit(100).ToList();
// check we have records to update.
if (recordResult.Any())
{
var result = dataCollection.UpdateMany(filter, updatePipeline);
if (result.ModifiedCount > 0)
{
// Success
}
else
{
// Failed
}
}`
I can't find an example of this here or in the Acumatica sample code. Sending single attribute values works fine, but I can't find a way to send multi-select ones. They are returned as a comma-separated list in a string value, but sending them that way doesn't work. Also, sending them as multiple instances of single values doesn't work.
Here's what I've tried. (In the actual code I'm sending some other single attributes in the list, as well, but those work fine.)
// this results in nothing being set for the attribute
string interestedIn = "Brochure, Contact, Collecting small stones";
List<Acumatica.AttributeDetail> attributes = new List<Acumatica.AttributeDetail>();
attributes.Add(
new Acumatica.AttributeDetail {
Attribute = new Acumatica.StringValue { Value = "Interested in" },
Value = new Acumatica.StringValue { Value = interestIn }
}
);
custAdd.Attributes = attributes.ToArray();
// this results in the last item in the list being set for the attribute
string interestedIn = "Brochure, Contact, Collecting small stones";
List<Acumatica.AttributeDetail> attributes = new List<Acumatica.AttributeDetail>();
string[] interests = Convert.ToString(interestedIn).Split(',');
foreach (string interest in interests) {
attributes.Add(
new Acumatica.AttributeDetail {
Attribute = new Acumatica.StringValue { Value = "Interested in" },
Value = new Acumatica.StringValue { Value = interest.Trim() }
}
);
};
custAdd.Attributes = attributes.ToArray();
From the source
MappedCustomer obj = bucket.Customer;
Core.API.Customer impl = obj.Local;
impl.Attributes = impl.Attributes ?? new List<AttributeValue>();
AttributeValue attribute = new AttributeValue();
attribute.AttributeID = new StringValue() { Value = attributeID };
attribute.ValueDescription = new StringValue() { Value = attributeValue?.ToString() };
impl.Attributes.Add(attribute);
Some subtle differences here. Also, I wonder if the .ToArray() call is necessary.
Okay so I have a small section of code which creates a list of objects based on the data model. I don't want to have to create a class for this. It is used on n ASP.net MVC application for populating a user notifications list.
I know there are plenty of other ways to do this such as actually setting up a class for it(probably the easiest method), but I would like to know if there is a way to do what is displayed below.
List<object> notificationList = new List<object>();
object userNotification = new { Text = "Here is some text!", Url = "http://www.google.com/#q=notifications" };
notificationList.Add(userNotification);
foreach(object notification in notificationList)
{
string value = notification.Text;
}
So I haven't populated the list much but for the purposes here you get the idea. After debug I notice that the Text and Url properties exist, however cannot code to get the values???
You need to use dynamic as variable type in the foreach:
foreach(dynamic notification in notificationList)
{
string value = notification.Text;
}
Edit Oops ... you do need "dynamic", either as the List's generic type, or in the foreach.
var notificationList = new List<dynamic>();
var userNotification = new { Text = "Here is some text!", Url = "http://www.google.com/#q=notifications" };
notificationList.Add(userNotification);
foreach (var notification in notificationList)
{
string value = notification.Text;
}
End edit
Anonymous types should be declared using the var keyword:
var userNotification = new { Text = "Here is some text!", Url = "http://www.google.com/#q=notifications" };
You could also use "dynamic" instead of "var", but that deprives you of compile-time checks, and it appears unnecessary in this case (because the type is fully defined at compile time, within the same method scope). A case where you would need to use "dynamic" is where you want to pass the anonymous-typed object as a parameter to another function, eg:
void Func1()
{
var userNotification = new { Text = "Here is some text!", Url = "http://www.google.com/#q=notifications" };
Func2(userNotification);
}
void Func2(dynamic userNotification)
{
string value = notification.Text;
}
Well you could declare the list as an list of dynimac objects:
List<dynamic> notificationList = new List<object>();
var userNotification = new { Text = "Here is some text!", Url = "http://www.google.com/#q=notifications" };
notificationList.Add(userNotification);
foreach(dynamic notification in notificationList)
{
string value = notification.Text;
}
or use var to let the compiler choose the type:
var notificationList = new []
{
new { Text = "Here is some text!", Url = "http://www.google.com/#q=notifications" }
}.ToList();
foreach(var notification in notificationList)
{
string value = notification.Text;
}
I'm trying to complete fields with JoeBlogs WordPress Wrapper.
My code is:
private void postToWordpress(string title, string postContent,string tags, string aioTitle)
{
string link = this.maskedTextBox1.Text;
string username = this.maskedTextBox2.Text;
string password = this.maskedTextBox3.Text;
var wp = new WordPressWrapper(link + "/xmlrpc.php", username, password);
var post = new Post();
post.Title = title;
post.Body = postContent;
post.Tags = tags.Split(',');
string[] cf = new CustomField(); //{ ID = "name", Key = "aiosp_title", Value = "All in One SEO Title" };
cf.ID = "name";
cf.Key = "aiosp_title";
cf.Value = "All in One SEO Title";
post.CustomFields[0] = cf;
wp.NewPost(post, false);
}
The error is at this line:
post.CustomFields[0] = cf;
And it is:
An unhandled exception of type 'System.NullReferenceException'
occurred in JoeBlogsWordpressWrapperTests.exe
Additional information: Object reference not set to an instance of an
object.
So, how to use/add correctly custom fields on WordPress from C# Application using JoeBlogs WordPress Wrapper?
The following code fixes your NullReferenceException and also successfully saves the custom fields into the Post in Wordpress.
private void postToWordpress(string title, string postContent,string tags, string aioTitle)
{
string link = this.maskedTextBox1.Text;
string username = this.maskedTextBox2.Text;
string password = this.maskedTextBox3.Text;
var wp = new WordPressWrapper(link + "/xmlrpc.php", username, password);
var post = new Post();
post.Title = title;
post.Body = postContent;
post.Tags = tags.Split(',');
var cfs = new CustomField[]
{
new CustomField()
{
// Don't pass in ID. It's auto assigned for new custom fields.
// ID = "name",
Key = "aiosp_title",
Value = "All in One SEO Title"
}
};
post.CustomFields = cfs;
wp.NewPost(post, false);
}
You were getting the NullReferenceException error because you were creating a string array and trying to assign it the CustomFields property of the Post object, which is an array of CustomField i.e. CustomField[].
Also, in order to save the CustomFields to the Post in the database, you should pass in only the Key and Value fields of the CustomField struct and skip the ID field all together. Reason being Wordpress auto-generates the ID fields (also it's an integer / numeric field in the database). I think that was what was causing the XmlRpc call to fail, but we did not get any errors as to why.
Try the above code and it should work (I have it working on my localhost WAMP Wordpress installation).
One final note. Although the CustomField's name property is called Key, it doesn't have to be unique, and uniqueness is not enforced. So for instance, if you are populating a custom dropdown box with a list of cities for a Post, you could have the list of cities as a set of custom fields as follows.
var cfs = new CustomField[]
{
new CustomField()
{
Key = "aiosp_title",
Value = "All in One SEO Title"
} ,
new CustomField()
{
Key = "this is another custom field with HTML",
Value = "All in One SEO Title <br/> Keyword 1 <br/><p>This is some more text and html</p>"
} ,
new CustomField()
{
Key = "list_of_cities",
Value = "San Francisco"
} ,
new CustomField()
{
Key = "list_of_cities",
Value = "New York"
}
};
This will also get saved to the post, with 2 custom fields with the same Key value and different text in the Value field's value.
And last but not least, you can store HTML also in the custom fields (as shown above).
I have my list as below,
var serie_line = new { name = series_name , data =new List<float?>() };
In the above code data in another list which contains float value, I want data to contains two different datatype value that is string and float value, when I am trying to add two different datatype values as follow,
var serie_line = new { name = series_name , data =new List<string, float?>() };
It gives me an error as
Using the generic type'System.Collections.Generic.List<T>' requires 1 argument.
I cannot try for data=new List<Tupple<string,float>>();..since I am using .NET 3.5...any idea..hw cn I deal with this problem..thank you,
----------Updated question---------
Output that I requires is as follows,
{
"legend":{"enabled":"true"},
"title":{"text":"Financial"},
"chart":{"type":"pie"},
"series":
[
{"name":"Actual-","data":[["Market Share",20.00],["Sales Growth",30.00],["Operating Profit",40.00],["Actual-Gross Margin %",10.00]]}
]
},
this data list should contains one string value and one float value...I want to draw pie chart in highcharts but output I am getting is as follows,
{
"legend":{"enabled":"true"},
"title":{"text":"Financial"},
"chart":{"type":"column"},
"series":[{"name":"Actual","data":[{"Str":"Market Share","Flo":20.00}]},
{"name":"Actual","data":[{"Str":"Sales Growth","Flo":30.00}]},
{"name":"Actual","data":[{"Str":"Operating Profit","Flo":40.00}]},
{"name":"Actual","data":[{"Str":"Gross Margin %","Flo":10.00}]}
]
}
Any Idea...???
----------Use of Dictionary----------
var data = new Dictionary<string, float?>();
var serie_line = new { name = series_name, data };
serie_line.data.Add(child_object_name, period_final_value);
but this doesnot give required output...
it only gives values inside data as for eg,
"data":["market share":20.00].. since I am serializing serie_line into JSON...but I don't want this way..what I want is "data":["market share",20.00]
I hope u get this...
just use
new Dictionary<string, float?>() //if your string value cannot be duplicated
//or
new List<KeyValuePair<string,float?> >
create a type to be use with your list:
public class MyDataType
{
public string Str {get; set;}
public float? Flo {get;set;}
}
you use it like this:
var serie_line = new { name = series_name , data =new List<MyDataType>() };
serie_line.data.Add(new MyDataType{Flo = 45.4});
or like:
var serie_line = new { name = series_name , data =new List<MyDataType>() };
serie_line.data.Add(new MyDataType{Flo = 45.4, Str = "my string"});
If you are trying to add items to a list so that both are available you need to use List<object>(), as its the only shared type between both. That or use ArrayList.
As you pull the objects out you will need to test if they are objects of type string or float? in order to cast them back. You may be able to wrap them.
Use ArrayList, the non-generic version of List.
How about something more structured:
public struct MyData
{
public float? FloatData;
public string StringData;
}
var serie_line = new
{
name = series_name,
data = new MyData()
{
FloatData = theFloatData,
StringData = theStringData,
}
};