On the WMI query below if the proptery is blank then my code errors. How can i make the code return "" when the property does not exist ? For example queryObj["Help Telephone"] is null so my code is erroring out but i want it to continue.
ManagementObjectSearcher searcherSoftware = new ManagementObjectSearcher("root\\CIMV2", "Select * from Win32_Product");
foreach (ManagementObject queryObj in searcherSoftware.Get())
{
ItemsUnderControlObject TemporarySoftware = new ItemsUnderControlObject();
TemporarySoftware.sType = "Software";
TemporarySoftware.sAssignmentType = queryObj["AssignmentType"].ToString().Split(new[] { "Name=" }, StringSplitOptions.None).Last().Trim('"'); //http://stackoverflow.com/questions/22583873/get-names-from-string-values/22583919?noredirect=1#22583919
TemporarySoftware.sCaption = queryObj["Caption"].ToString().Split(new[] { "Name=" }, StringSplitOptions.None).Last().Trim('"');
TemporarySoftware.sDescription = queryObj["Description"].ToString().Split(new[] { "Name=" }, StringSplitOptions.None).Last().Trim('"');
TemporarySoftware.sHelpLink = queryObj["HelpLink"].ToString().Split(new[] { "Name=" }, StringSplitOptions.None).Last().Trim('"');
TemporarySoftware.sHelpTelephone = queryObj["Help Telephone"].ToString().Split(new[] { "Name=" }, StringSplitOptions.None).Last().Trim('"');
}
You could create a helper method:
private static string GetNameContents(ManagementObject queryObj, string propertyName)
{
object propertyValue = queryObj[propertyName];
if (propertyValue == null)
return String.Empty;
string propertyString = propertyValue.ToString();
return propertyString.Length == 0
? String.Empty
: propertyString.Split(new[] { "Name=" }, StringSplitOptions.None).Last().Trim('"');
}
And use it as follows:
TemporarySoftware.sAssignmentType = GetNameContents(queryObj, "AssignmentType");
TemporarySoftware.sCaption = GetNameContents(queryObj, "Caption");
Related
Have a salesorder opject and I want to search by using a tranid field.
how can I do that?
I know how to search by using internalid or extrenalid, but no clue about tranid
Here is an example of how to do this in C#.
SearchResult result = service.search(new TransactionSearch()
{
basic = new TransactionSearchBasic()
{
type = new SearchEnumMultiSelectField() {
#operator = SearchEnumMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = new string[] { "_salesOrder" }
},
tranId = new SearchStringField()
{
#operator = SearchStringFieldOperator.#is,
operatorSpecified = true,
searchValue = "SO364886"
}
}
}
);
if(result.status.isSuccess && result.totalRecords == 1)
{
SalesOrder salesOrder = (SalesOrder)result.recordList[0];
System.Console.WriteLine("Internal ID = " + salesOrder.internalId);
} else
{
System.Console.WriteLine("Couldn't find sales order!");
}
I'm trying to convert a nested json to simple json by recursively traversing.
(Structure of input json is unknown)
for example, I want json like this
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType": {
"RID": 2,
"Title": "Full Time"
},
"CTC": "3.5",
"Exp": "1",
"ComplexObj": {
"RID": 3,
"Title": {
"Test": "RID",
"TWO": {
"Test": 12
}
}
}
}
to be converted something like this
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType__RID": 2,
"EmpType__Title": "Full Time",
"CTC": "3.5",
"Exp": "1",
"ComplexObj__RID": 3,
"ComplexObj__Title__Test": "RID",
"ComplexObj__Title__TWO__Test": 12
}
each fields in nested object will be changed to key which represents its actual path.
this is what I have done so far.
public static void ConvertNestedJsonToSimpleJson(JObject jobject, ref JObject jobjectRef, string currentNodeName = "", string rootPath = "")
{
string propName = "";
if (currentNodeName.Equals(rootPath))
{
propName = currentNodeName;
}
else
{
propName = (rootPath == "" && currentNodeName == "") ? rootPath + "" + currentNodeName : rootPath + "__" + currentNodeName;
}
foreach (JProperty jprop in jobject.Properties())
{
if (jprop.Children<JObject>().Count() == 0)
{
jobjectRef.Add(propName == "" ? jprop.Name : propName + "__" + jprop.Name, jprop.Value);
}
else
{
currentNodeName = jprop.Name;
rootPath = rootPath == "" ? jprop.Name : rootPath;
ConvertNestedJsonToSimpleJson(JObject.Parse(jprop.Value.ToString()), ref jobjectRef, currentNodeName, rootPath);
}
}
}
and getting wrong result
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType__RID": 2,
"EmpType__Title": "Full Time",
"CTC": "3.5",
"Exp": "1",
"EmpType__ComplexObj__RID": 3,
"EmpType__Title__Test": "RID",
"EmpType__two__Test": 12
}
will appreciate any help on correcting my code, or any other approach to archive this.
You don't need to convert the value of the property to string and then parse it again every time - just cast it to JObject
You don't need the complicated conditional logic to generate the name of the property - just use this: prefix + jprop.Name + "__"
The code:
public static void FlattenJson(JObject node, JObject result, string prefix = "")
{
foreach (var jprop in node.Properties())
{
if (jprop.Children<JObject>().Count() == 0)
{
result.Add(prefix + jprop.Name, jprop.Value);
}
else
{
FlattenJson((JObject)jprop.Value, $"{prefix}{jprop.Name}__", result);
}
}
}
You can call it like this:
var node = JObject.Parse(/* the input string */);
var result = new JObject();
FlattenJson(node, result);
Your problem is in the line rootPath = rootPath == "" ? jprop.Name : rootPath;. You are changing the rootPath when you first come across EmpType which means when you process ComplexObj your rootPath is wrong. What I believe you intended is just to change what you were passing into the recursive function.
As it is though it is unnecessary to keep track of root and currentnode as two separate items. Better would be to just track the current prefix for a given node in code that looks more like this:
public static void ConvertNestedJsonToSimpleJson(JObject input, JObject output, string prefix = "")
{
foreach (JProperty jprop in input.Properties())
{
var name = prefix==""?jprop.Name:String.Format("{0}__{1}", prefix,jprop.Name);
if (jprop.Children<JObject>().Count() == 0)
{
output.Add(name, jprop.Value);
}
else
{
ConvertNestedJsonToSimpleJson((JObject)jprop.Value, output, name);
}
}
}
This now gives me the output:
{
"FirstName": "Rahul",
"LastName": "B",
"EmpType__RID": 2,
"EmpType__Title": "Full Time",
"CTC": "3.5",
"Exp": "1",
"ComplexObj__RID": 3,
"ComplexObj__Title__Test": "RID",
"ComplexObj__Title__TWO__Test": 12
}
which looks correct.
Could you do something like this using linq
var jsonObj = jobject.select(x => new CustomJson {
FirstName = x.FirstName,
LastName = x.LastName,
EmpTypeId = x.EmpType.Id,
Title = x.EmpType.Title
etc etc
});
I am using CRM 4 and the SDK to grab cases like so:
public List<Case> GetCases()
{
List<Case> cases = new List<Case>();
#region Retrieve Resolved Cases
try
{
InitSession();
RetrieveMultipleRequest req = new RetrieveMultipleRequest();
req.ReturnDynamicEntities = true;
//QueryExpression says what entity to retrieve from, what columns we want back and what criteria we use for selection
QueryExpression qe = new QueryExpression();
qe.EntityName = EntityName.incident.ToString();
List<string> attributes = new string[] {
"incidentid","title" ,"description", "ticketnumber", "statuscode",
"kez_allocatedhours",
"customerid",
"casetypecode"
}.ToList();
//columns to retireve
ColumnSet AvailabilityColumnSet = new ColumnSet();
AvailabilityColumnSet.Attributes = attributes.ToArray();
qe.ColumnSet = AvailabilityColumnSet;
//filter
FilterExpression fe = new FilterExpression();
fe.FilterOperator = LogicalOperator.And;
//condtion for filter
ConditionExpression isResolved = new ConditionExpression();
isResolved.AttributeName = "statuscode";
isResolved.Operator = ConditionOperator.NotEqual;
isResolved.Values = new string[] { "5" };
fe.Conditions = new ConditionExpression[] { isResolved }; //Add the conditions to the filter
qe.Criteria = fe; //Tell the query what our filters are
req.Query = qe; //Tell the request the query we want to use
//retrieve entities
RetrieveMultipleResponse resp = svc.Execute(req) as RetrieveMultipleResponse;
if (resp != null)
{
BusinessEntity[] rawResults = resp.BusinessEntityCollection.BusinessEntities;
List<DynamicEntity> castedResults = rawResults.Select(r => r as DynamicEntity).ToList();
foreach (DynamicEntity result in castedResults)
{
string id = GetProperty(result, "incidentid");
string title = GetProperty(result, "title");
string description = GetProperty(result, "description");
string ticket = GetProperty(result, "ticketnumber");
string customer = GetProperty(result, "customerid");
int statuscode = -1;
string statusname = "";
double estHours = 0.0;
string casetype = "";
int casetypecode = -1;
Property prop = result.Properties.Where(p => p.Name == "statuscode").FirstOrDefault();
if (prop != null)
{
StatusProperty status = prop as StatusProperty;
if (status != null)
{
statuscode = status.Value.Value;
statusname = status.Value.name;
}
}
prop = result.Properties.Where(p => p.Name == "kez_allocatedhours").FirstOrDefault();
if (prop != null)
{
CrmFloatProperty fl = prop as CrmFloatProperty;
if (fl != null)
{
estHours = fl.Value.Value;
}
}
prop = result.Properties.Where(p => p.Name == "casetypecode").FirstOrDefault();
if (prop != null)
{
PicklistProperty fl = prop as PicklistProperty;
if (fl != null)
{
casetype = fl.Value.name;
casetypecode = fl.Value.Value;
}
}
Case c = new Case();
c.ID = id;
c.Title = title;
c.Description = description;
c.StatusCode = statuscode;
c.StatusName = statusname;
c.TicketNumber = ticket;
c.CustomerName = customer;
c.EstimatedHours = estHours;
c.Type = casetype;
c.TypeCode = casetypecode;
bool allowedThroughStat = true;
bool allowedThroughType = true;
var userStatuses = SettingsManager.Get("CRMUserStatusReasons").Split(';').ToList().Where(p => p.Length > 0).ToList();
var userTypes = SettingsManager.Get("CRMUserCaseTypes").Split(';').ToList().Where(p => p.Length > 0).ToList();
if(userStatuses.Count > 0 && !userStatuses.Contains(c.StatusCode.ToString()))
{
allowedThroughStat = false;
}
if (userTypes.Count > 0 && !userTypes.Contains(c.TypeCode.ToString()))
{
allowedThroughType = false;
}
if(allowedThroughStat && allowedThroughType)
cases.Add(c);
}
}
}// end try
catch (Exception)
{
return null;
// The variable 'e' can access the exception's information.
// return "Error Message: " + e.Message.ToString() + " | Stack Trace: " + e.StackTrace.ToString();
}
return cases;
#endregion
}
However, now I need to be able to change the status and title of a case from C# given its incidentid.
Ive looked at the SDK docs and cannot find an example of this.
Anyone work with this before?
Thanks
Simply put, above is code to read an incident. Could I get an example of writing an incident field, Just one. Ex: How could I change the title of an incident.
You can call the Update method on the CrmService. Here is the SDK article.
Case c = new Case();
c.ID = id;
c.Title = title;
svc.Update(c);
To change the state of an entity you use the setstaterequest. If you want to do it to a dynamic entity there's a description in this blog
I'm trying to query a DynamoDB that i have created using code from the Amazon docs with a few simple modifications. I'm trying to take the data i get and write it to a log file as strings. But all i can seem to get is this:
2013-02-22 20:21:37.9268|Trace|[System.Collections.Generic.Dictionary2+KeyCollection[System.String,Amazon.DynamoDB.Model.AttributeValue] System.Collections.Generic.Dictionary2+ValueCollection[System.String,Amazon.DynamoDB.Model.AttributeValue]]|
I've tried a few different things but all return either the same thing, or something very similar.
The code i'm using:
private static void GetCallsForRange()
{
AmazonDynamoDBConfig config = new AmazonDynamoDBConfig();
config.ServiceURL = "http://dynamodb.us-west-2.amazonaws.com";
AmazonDynamoDBClient client = new AmazonDynamoDBClient(config);
DateTime startDate = DateTime.Today.AddDays(-21);
string start = startDate.ToString("G", DateTimeFormatInfo.InvariantInfo);
DateTime endDate = DateTime.Today;
string end = endDate.ToString("G", DateTimeFormatInfo.InvariantInfo);
QueryRequest request = new QueryRequest
{
TableName = "Inquiry",
HashKeyValue = new AttributeValue { S = "+15555555555" },
RangeKeyCondition = new Condition
{
ComparisonOperator = "BETWEEN",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = start },
new AttributeValue { S = end }
}
}
};
QueryResponse response = client.Query(request);
QueryResult result = response.QueryResult;
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
string logMsg = String.Format("[{0} {1}]", item.Keys, item.Values);
Logging.LogTrace(logMsg);
}
}
You will need to iterate over each item in the response.QueryResult.Items. You could rewrite your loop like this (taken from the Amazon DynamoDB documentation):
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
LogItem(item);
}
private void LogItem(Dictionary<string, AttributeValue> attributeList)
{
foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
{
string attributeName = kvp.Key;
AttributeValue value = kvp.Value;
string logValue =
(value.S == null ? "" : value.S) +
(value.N == null ? "" : value.N.ToString()) +
(value.B == null ? "" : value.B.ToString()) +
(value.SS == null ? "" : string.Join(",", value.SS.ToArray())) +
(value.NS == null ? "" : string.Join(",", value.NS.ToArray())) +
(value.BS == null ? "" : string.Join(",", value.BS.ToArray()));
string logMsg = string.Format("[{0} {1}]", attributeName, logValue);
Logging.LogTrace(logMsg);
}
}
Essentially, you need to discover the "type" of the AttributeValue(String, Number, Binary, StringSet, NumberSet, BinarySet) and then output that to your log.
I hope that helps!
I have collection of patient in a lists named lst_Patient.
And this is method where i get the info from user:
public Patient[] GetPatientsBySearchParams(DataPair[] dataPair)
{
//return the array patients that match any of the criteria
//Right Now I ma doing this didn't get any success :
List<Patient> P = new List<Patient>();
P = lst_Patient.FindAll(p => { p.FirstName = dataPair[0].OutputValue.ToString();
p.LastName = dataPair[1].OutputValue.ToString();
return true;
return P.ToArray();
}
On a button click i take the info entered in the textbox by the user:
private DataPair[] dpair;
private void Button_Click(object sender, RoutedEventArgs e)
{
InvalidSearch.Visibility = Visibility.Collapsed;
SearchResults.Visibility = Visibility.Visible;
dpair = new DataPair[]{
new DataPair { Name = "FirstName", OutputValue = fst_Name.Text },
new DataPair { Name = "LastName", OutputValue = lst_Name.Text },
new DataPair { Name = "DateOfBirth", OutputValue = dob.Text },
new DataPair { Name = "SSN", OutputValue = ssn.Text },
new DataPair { Name = "PracticeNumber", OutputValue = pract_nbr.Text },
new DataPair { Name = "ReferenceNumber", OutputValue = ref_nbr.Text },
new DataPair { Name = "PlaceOfService", OutputValue = pos.Text },
new DataPair { Name = "DateOfService", OutputValue = dos.Text},
new DataPair { Name = "RenderingProvider", OutputValue = rndrng_prov.Text },
new DataPair { Name = "AdmissionDate", OutputValue = admsn_date.Text }
};
this.FetchData();
}
private void FetchData()
{
Patient[] p = client.GetPatientsBySearchParams(dpair);
}
public Patient[] GetPatientsBySearchParams(DataPair[] dataPair)
{
P = lst_Patient.FindAll(
delegate(Patient tmp){
if(tmp.FirstName = dataPair[0].OutputValue || tmp.LastName = dataPair[1].OutputValue)
return true;
else
return false;
}
);
return P.ToArray();
}
You should use reflection to call the property whose name gets passed.
p.GetType().GetProperty(dataPair[i].Name).GetValue(p) == dataPair[i].OutputValue;