C# WMI ManagementException thrown on search.Get().Count - c#

Hello this is my first post on Stackoverflow.
Background:
I am building a Class to use the WindowsManagementInstrumentation library to query DNS Servers.
Problem:
When I search for a dns record that does not exist on the DNS Server I get the following error:
An exception of type 'System.Management.ManagementException' occurred in System.Management.dll but was not handled in user code
It is caused from this line:
if (search.Get().Count > 0)
In looking at this line I found the exception is on the Count.
I am not sure why this happens. If I search for a DNS Record that I know is on the DNS Server then Count returns the correct number and doesn't throw an error. I expect Count to return 0 if it can't find a DNS Record on the server. I could do a try catch and when it throws the exception handle it on my end so it but I feel this is not the right way to do it. Any ideas?
I get the following error info when I debug.
Count 'Count' threw an exception of type 'System.Management.ManagementException' int {System.Management.ManagementException}
base {"Generic failure "} System.SystemException {System.Management.ManagementException}
base {"Generic failure "} System.Exception {System.Management.ManagementException}
Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
HelpLink null string
HResult -2146233087 int
InnerException null System.Exception
Message "Generic failure " string
Source "System.Management" string
StackTrace " at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)\r\n at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()\r\n at System.Management.ManagementObjectCollection.get_Count()" string
ErrorCode Failed System.Management.ManagementStatus
Full Method:
public List<ManagementObject> GetRecords(string domain, string name, string type)
{
//Object to hold list of RRecords/DNS Records
List<ManagementObject> rrecords = new List<ManagementObject>();
//Init properites for the given type
Properties propertiesStruct = new Properties(type);
//Query
string query = "SELECT * FROM " + propertiesStruct.Table + " WHERE DomainName = '" + domain.ToLower() + "' AND OwnerName ='" + name.ToLower() + "." + domain.ToLower() + "'";
//Search for results
ManagementObjectSearcher search = new ManagementObjectSearcher(this.scope, new ObjectQuery(query));
//Make sure we have something and if we do loop through them to grab the data
if (search.Get().Count > 0)
{
foreach (ManagementObject results in search.Get())
{
rrecords.Add(results);
}
}
return rrecords;
}
Sorry if I missed anything and thanks for the help.

Just so anyone else who runs across this knows what I ended up doing. I ended up wrapping the count check in a try catch and if it throws an exception I ignore it and just return an empty rrecords object since the search didn't find anything.

Related

Check Null or Empty String For Two Values C# [duplicate]

This question already has answers here:
How can I fix the error : "Unreachable Code Detected"
(4 answers)
Closed 3 years ago.
I want to check for empty string or null values for Subject Code and Subject Name so that empty string of subject code and subject name will not be store in the database. I'm new to c#. There is an error to the code. It stated cannot convert from bool to string. I tried so many ways but the error is still there. After fixing the error for converting from bool to string, it returned me an Not Found error. How should I change the return NotFound() error?
public IHttpActionResult PostAddSubjectCode([FromBody] ConfigSubjectCode SubjectCodes)
{
string Subject_Code = SubjectCodes.Subject_Code;
string Subject_Name = SubjectCodes.Subject_Name;
if (String.IsNullOrEmpty(Subject_Code) && String.IsNullOrEmpty(Subject_Name))
{
return NotFound();
}
else
{
string sql = "INSERT INTO[dbo].[GEO_SUBJECT_CODES] ([Subject_Code],[Subject_Name_BY_CLASS]) VALUES " +
"('" + Subject_Code + "', '" + Subject_Name + "');";
DBConnection dbConnection = new DBConnection();
dBConnection.UpdateTable(sql);
return Ok();
}
}
The error states exactly what the problem is: You're passing a boolean (Subject_Code == "" && Subject_Name == "") to String.IsNullOrEmpty which expects a string
You're setting empty string to the variables you're checking, making the if check pointless
Your SQL is open to injection
Strongly suggested: Getting started with ASP.NET MVC 5, it will also have links to newer Core examples.
I'll keep this here since we had a thread going and to point out the issues listed.
// These will make the if statement useless, it will never hit else
// string Subject_Code = "";
// string Subject_Name = "";
//Assumptions: Subject_Codes contians these props
if(string.IsNullOrEmtpy(SubjectCodes.Subject_Code) && string.IsNullOrEmpty(SubjectCodes.Subject_Name)){
// whatever you want to do...
} else {
//sql here - I'll skip the comments on why your sql is bad - re: use parameters
// return after successful sql - look into a try/catch
}
Look into DataAnnotations [Required] in your model instead - you gain both server and client side validation. I strongly suggest you go over extensive tutorials instead of piecemeal stuff.
Based on the above code what you have tried to do is compare boolean value to a string value which would give you an error try the solution below.
if (String.IsNullOrEmpty(Subject_Code) && String.IsNullOrEmpty(Subject_Name)){
return NotFound();
} else{
try{
//SQL Code
} catch (Exception ex){
//Your Code
}
}
Note: This is a quick fix for OP's problem, not the best practice.
Since your if/else both return, it will never get to the actual update code. And you were assigned both variable to a fixed empty string, which would never cause the if/else to work in any case. You want something like this:
public IHttpActionResult PostAddSubjectCode([FromBody] ConfigSubjectCode SubjectCodes)
{
string Subject_Code = SubjectCodes.Subject_Code; // these can't be fixed ""
string Subject_Name = SubjectCodes.Subject_Name; // these can't be fixed ""
if (String.IsNullOrEmpty(Subject_Code) && String.IsNullOrEmpty(Subject_Name))
{
return NotFound();
}
else
{
string sql = "INSERT INTO[dbo].[GEO_SUBJECT_CODES] ([Subject_Code],[Subject_Name_BY_CLASS]) VALUES " +
"('" + Subject_Code + "', '" + Subject_Name + "');";
DBConnection dBConnection = new DBConnection();
dBConnection.UpdateTable(sql);
return Ok();
}
}

Throws exception and breaks the flow but the data is available in the sequence

The below code throws sequence does not contain the matching element.
var inavailableous = userOuIds.Any(n => ("," + item.AvailableOUs + ",").Contains(n));
Where userOuIds is List<string> has value as ,1, and the item.AvailableOUs is string has values 1,2,3,4,5,6.
Please help me what is going wrong with the code?

Why does my method not build a proper XML query from user input?

I'm currently trying to take user input from a text box and build an XML query with it.
The query should search within the document for an element with a given attribute 'dataItemId' and return the innerText value.
The two lines of code which are commented out within the try{} statement work as expected, returning the correct value, yet when I try to use the two lines above these and type 'Xabs' into my input box I am getting:
Your resultant Query XPath: //*[dataItemId = 'Xabs']
No Items Found."
It must be something to do with how the string is parsed but I'm stumped as to what.
public void MazakButton_Click(object sender, EventArgs e)
{
string userInput = searchInput.Text;
ResultBox.Items.Clear();
string query = "No Query Found";
string searchResult = "No Items Found";
if (userInput.Length > 3)// If query paramater is long enough
{
//string Query = "\"//*[dataItemId = '" + userInput + "']\""; // Build Attribite Query
query = "//*[dataItemId = '" + userInput + "']"; // Build Attribite Query
XmlDocument MTData = MTFunctions.ScrapeXMLData(MazakSourceURL, false);
try
{
XmlNode target = MTData.SelectSingleNode(query);
searchResult = userInput + ": " + target.InnerText;
//XmlNode target = MTData.SelectSingleNode("//*[#dataItemId = 'Xabs']");
//searchResult = target.InnerText;
}
catch
{
Console.WriteLine("!!!!!!!!!!!!!!! - XML SEARCH FAILED - !!!!!!!!!!!!!!!");
}
}
else{searchResult = "Invalid request (Too short)";}
searchInput.Focus();
ResultBox.Items.Add("Your Resultant Query XPath: " + query);
ResultBox.Items.Add(searchResult);
searchInput.Text = string.Empty; // Clear searchInput
}
First point: you should never build a query by string concatenation incorporating user input. Google "SQL injection attacks" to find out why (most of the literature is in SQL terms, but XPath has exactly the same vulnerabilities).
If you use an expression with a variable, like //*[dataItemId = $userInput] then (a) you are protected against injection attacks, (b) you don't need to worry about escaping special characters in the input (like apostrophes), and (c) it's much more efficient because you only need to compile the XPath expression once.
The only difficulty is that you need to work out how to supply a parameter to the query (that is, a value for $userInput) before executing it. That depends on the API to your XPath processor and I'm not familiar with the XPath processor that you are using, so you'll need to research this yourself.

address1_latitude and address1_longitude is not getting from RetrieveMultiple

Hi i have tried to get address1_latitude and address1_longitude from CRM using CRM SDK here is mu code
var querybyattribute11 = new QueryByAttribute("account");
querybyattribute11.ColumnSet = new ColumnSet("name", "address1_city", "statuscode", "address1_postalcode", "address1_latitude", "address1_longitude");
querybyattribute11.Attributes.AddRange("name");
querybyattribute11.Values.AddRange("ASSOCIATED COMBUSTION INC");
EntityCollection entities = service.RetrieveMultiple(querybyattribute11);
foreach (Entity item in entities.Entities)
{
// Console.WriteLine("Name: {0}. Id: {1}", role.Name, role.Id);
list += item.Attributes["name"].ToString() + " " + item.Attributes["address1_longitude"] .ToString() + "\n";
}
But I am not geting it item.Attributes["address1_longitude"]
error message is
'The given key was not present in the dictionary.'
It might be because it's null.
Try either one of these 2 options:
item["address1_longitude"] (shouldn't raise exception, it would return null if blank, otherwise the address longitude)
To check if the column exists:
item.Attributes.ContainsKey("address1_longitude")

Rewriting foreach using IObservable and Reactive Framework

I'm in VS2008 with Entity Framework. I'm accessing objects from the database using esql for WHERE IN functionality. I'm passing a ton of IDs to the select statement so I chunk it up into sets of 800. Then I merge the results together from each chunk. My goal is to obtain results for each chunk in parallel, rather than waiting synchronously. I installed Reactive Framework and am pretty sure I need to make use of ForkJoin. However, I can't figure out how to convert this function to use it. Here's my existing code:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var retList = new List<TElement>();
foreach (var idChunk in chunkedIds)
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
retList.AddRange(query);
}
return retList;
}
Thanks!
EDIT >>>
I modified the code to use Poor Man's as below:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var chunkLists = new List<IEnumerable<TElement>>();
Parallel.ForEach(chunkedIds, idChunk =>
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
var retList = new List<TElement>();
foreach (var chunkList in chunkLists)
{
retList.AddRange(chunkList);
}
return retList;
}
It worked great the first time. But the second time I ran it, I got this error:
The connection was not closed. The connection's current state is connecting.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The connection was not closed. The connection's current state is connecting.
Source Error:
Line 49: foreach (var iAsyncResult in resultList)
Line 50: {
Line 51: del.EndInvoke(iAsyncResult);
Line 52: iAsyncResult.AsyncWaitHandle.Close();
Line 53: }
It's interesting, b/c Emre (the author of the library) has an edit to his original post talking about how he added those lines of code for added safety. Am i using it right? Or was his v1 safer after all?
VS2010 does have that with PLINQ. Using the extensions AsParallel().WithDegreeOfParallelism(nbProcessors) would do what you need.
With VS2008, I've used Poor Man's Parallel.ForEach Iterator by Emre Aydinceren in the past when I was trying to work around a performance bottleneck, try to give it a shot.
EDIT: In reaction to the error you added, it might be a random shot in the dark, but seperate contexts for each thread ? Like so:
Parallel.ForEach(chunkedIds, idChunk =>
{
ObjectContext context = new MyContext(connStr);//depending what's your config
// like, with or w/o conn string
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
You might have to tweak around some things (like take the connextion string from the Context extended to instantiate new Contexts).

Categories