I'm messing about with the Bing Maps WPF control and SOAP services, trying to reverse geocode a point. I tried to implement some code from this project, specifically this block of code:
private string ReverseGeocodePoint(string locationString)
{
string results = "";
ReverseGeocodeRequest reverseGeocodeRequest = new ReverseGeocodeRequest();
// Set the credentials using a valid Bing Maps key
reverseGeocodeRequest.Credentials = new GeocodeService.Credentials();
reverseGeocodeRequest.Credentials.ApplicationId = key;
// Set the point to use to find a matching address
GeocodeService.Location point = new GeocodeService.Location();
string[] digits = locationString.Split(';');
point.Latitude = double.Parse(digits[0].Trim());
point.Longitude = double.Parse(digits[1].Trim());
reverseGeocodeRequest.Location = point;
// Make the reverse geocode request
GeocodeServiceClient geocodeService = new GeocodeServiceClient();
GeocodeResponse geocodeResponse = geocodeService.ReverseGeocode(reverseGeocodeRequest);
if (geocodeResponse.Results.Length > 0)
results = geocodeResponse.Results[0].DisplayName;
else
results = "No Results found";
return results;
}
However, when I try to implement it, I'm being told: Error: The type or namespace name 'Credentials' does not exist in the namespace 'GeocodeTest.GeocodeService' (are you missing an assembly reference?) This error occurs on the line:
reverseGeocodeRequest.Credentials = new GeocodeService.Credentials();
Curious, I decided to take a look at the service reference through the object browser. Apparently, my GeocodeService doesn't even have a Credentials member. So now the question is:
Should I add the member myself? If so, how would I do this?
If not, what alternatives to do have in terms of providing credentials?
The Credentials namespace/type doesn't exist for the service reference GeocodeText.GeocodeService. Instead, you have to use the Credentials from the Bing Maps WPF Control. The statement would look like so:
reverseGeocodeRequest.Credentials = new Microsoft.Maps.MapControl.WPF.Credentials();
Related
I have a need to manage Kerberos Resource Based Delegation in C# (I know it's easier in Powershell but that is not the requirement). The attribute on the user/computer/service accounts is msDS-AllowedToActOnBehalfOfOtherIdentity, but this seems to be some COM object which I can't seem to deal with in C#:
static void Main(string[] args)
{
string ou = #"OU=some,OU=ou,DC=corp,DC=com";
string cn = #"someaccount";
DirectoryEntry de = new DirectoryEntry();
de.Username = #"CORP\userwithOUrights";
de.Password = #"password";
de.AuthenticationType = AuthenticationTypes.Secure;
de.Path = $"LDAP://CN={cn},{ou}";
Object a = de.Properties["msDS-AllowedToActOnBehalfOfOtherIdentity"];
}
After this, a doesn't seem to be anything I can do much with, unlike other properties. It is some COM object and I need to get the accounts which are in there. Powershell reports that this property returns a System.DirectoryServices.ActiveDirectorySecurity object and I see useful methods in this class for decoding the binary format which is stored in AD etc. But this does not seem to be the return type from the property call in C#.
Update: All of this is now better documented in an article on my website: Handling NT Security Descriptor attributes
According to this the "attribute syntax" for that attribute is 2.5.5.15. According to this, that means it's a "String(NT-Sec-Desc)". According to this, that means it's a IADsSecurityDescriptor COM object.
You can add a COM reference in your project to "Active DS Type library" and cast it directly to IADsSecurityDescriptor, like this:
var act = (ActiveDs.IADsSecurityDescriptor)
de.Properties["msDS-AllowedToActOnBehalfOfOtherIdentity"].Value;
Console.WriteLine(act.Owner);
The Owner property gives you a DOMAIN\Username.
According to this random code I found, it seems you can also use the RawSecurityDescriptor class to interact with it. There is a constructor that takes a plain string, but you also can't seem to get the raw string from the attribute from DirectoryEntry.
But I did remember that sometimes DirectorySearcher will give you values in a different type than DirectoryEntry (doesn't make sense, but it's true). That appears to be true here. DirectorySearcher gives this attribute to you as a byte[], and RawSecurityDescriptor does have a constructor that takes a byte[].
So it seems you can do something like this:
string ou = #"OU=some,OU=ou,DC=corp,DC=com";
string cn = #"someaccount";
var search = new DirectorySearcher(new DirectoryEntry($"LDAP://{ou}"), $"(cn={cn})");
search.PropertiesToLoad.Add("msDS-AllowedToActOnBehalfOfOtherIdentity");
var result = search.FindOne();
var act = new RawSecurityDescriptor(
(byte[]) result.Properties["msDS-AllowedToActOnBehalfOfOtherIdentity"][0], 0);
Console.WriteLine(act.Owner);
//make changes to act.DiscretionaryAcl
byte[] descriptor_buffer = new byte[act.BinaryLength];
act.GetBinaryForm(descriptor_buffer, 0);
var de = result.GetDirectoryEntry();
de.Properties["msDS-AllowedToActOnBehalfOfOtherIdentity"].Value = descriptor_buffer;
de.CommitChanges();
In this, act.Owner is an account SID.
I have a small C# console application who's sole purpose is to receive records from a "Saved Search" in NetSuite(via SuiteTalk). I've been able to successfully connect and receive records from NetSuite for my Saved Search(the search runs fine through the web interface too), however when I attempt to access the results of the "Saved Search" through my application, I am unable to view them because the search object that is returned does not contain any data in the "recordList" property:
//Connect
var dataCenterAwareNetSuiteService = new DataCenterAwareNetSuiteService("XXXXXX");
dataCenterAwareNetSuiteService.Timeout = 1000 * 60 * 60 * 2;
//Adds Credentials etc...
dataCenterAwareNetSuiteService.tokenPassport = createTokenPassport();
//Setup Preferences
var prefs = new Preferences();
prefs.warningAsErrorSpecified = true;
prefs.warningAsError = false;
dataCenterAwareNetSuiteService.preferences = prefs;
var searchPrefs = new SearchPreferences();
dataCenterAwareNetSuiteService.searchPreferences = searchPrefs;
dataCenterAwareNetSuiteService.searchPreferences.pageSize = 5;
dataCenterAwareNetSuiteService.searchPreferences.pageSizeSpecified = true;
dataCenterAwareNetSuiteService.searchPreferences.bodyFieldsOnly = false;
dataCenterAwareNetSuiteService.searchPreferences.returnSearchColumns = false;
//Search
var tranSearchAdv = new TransactionSearchAdvanced();
var tranSearchRow = new TransactionSearchRow();
var tranSearchRowBasic = new TransactionSearchRowBasic();
tranSearchAdv.savedSearchId = "XXXX";
tranSearchRowBasic.internalId =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRowBasic.tranId =
new SearchColumnStringField[] { new SearchColumnStringField() };
tranSearchRowBasic.dateCreated =
new SearchColumnDateField[] { new SearchColumnDateField() };
tranSearchRowBasic.total =
new SearchColumnDoubleField[] { new SearchColumnDoubleField() };
tranSearchRowBasic.entity =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRow.basic = tranSearchRowBasic;
tranSearchAdv.columns = tranSearchRow;
//No errors,
//this works correctly and returns the "Saved Search" with the correct "totalRecords"
//but results.recordList == null while results.totalRecords = 10000000+
var results = dataCenterAwareNetSuiteService.search(tranSearchAdv);
I appears to me that the "recordList" object is the principal way data is retrieved from the results of a search(Related Java Example, Another Here). This is also the way the example API does it.
I have run this on multiple "Saved Search's" with the same results. I don't understand how you can have more than one record in "totalRecords" and yet the "recordList" remains null? Is there some configuration option that has to be set to allow me to access this property. Or maybe it's a security thing, the API user I have setup should have full access, is there anything else that need to be granted access?
NetSuite SuiteTalk is not well documented, and most of the examples online are not in C#, and not dealing with the issues that I'm experiencing. These factors make it very difficult to determine why the previously mentioned behavior is occurring, or even, to discover any alternative methods for retrieving the resulting data from the source "Saved Search".
Does anyone have any insight into this behavior? Is this the correct method of retrieving results from SuiteTalk? Is there any configuration from the API or Web Side that needs to be changed?
Update 1
I've also tried using the alternative way of getting result data by accessing the "searchRowList" object from the "SearchResult" object(suggested by #AdolfoGarza) However it returns mostly empty fields(null) similar to the "recordList" property I do not see a way to retrieve "Saved Search" data from this method.
Try getting the results with results.searchRowList.searchRow , thats how it works in php.
I was able to resolve the issue by removing this line in the code:
tranSearchRow.basic = tranSearchRowBasic;
Then like #AdolfoGarza reccomended, retrieving the results from "basic" field in "results.searchRowList"
For some reason the template API that I was using was setting up a "TransactionSearchAdvanced" referencing a blank "TransactionSearchBasic" record, not sure why but this was causing the results from "searchRowList" to be null. After removing it I now get non-null values in the proper fields.
As for "recordList", it's still null, not sure why, but as I have my data I don't think I'll continue to dig into this.
public ISearchResponse<object> GetById(string id) {
var uri = new Uri("<myendpoint>");
var settings = new ConnectionSettings(uri).DefaultIndex("useraction-*").PrettyJson().DisableDirectStreaming(); //or try _all
var client = new ElasticClient(settings);
var search = new SearchRequest<object>
{
Query = new TermQuery
{
Field = "field",
Value = "example"
}
};
var response = client.Search<object>(search);
return response;
}
I'm having trouble getting NEST to work. When I try to call the query defined above, I get the following error:
System.Exception: If you use a custom contract resolver be sure to subclass from ElasticResolver
at Nest.JsonExtensions.GetConnectionSettings(JsonSerializer serializer) in C:\Users\russ\source\elasticsearch-net-master\src\Nest\CommonAbstractions\Extensions\JsonExtensions.cs
I've searched the internet for mention of this and can't seem to find anything other than the source code. I've pretty much followed the documentation exactly so I don't know what to change.
Does anyone out there know what this error is trying to tell me? I feel like it's an error behind the scenes that I don't have control over.
I'm happy to answer additional questions if people need more info.
Thanks.
Also I don't know where that path is coming from in the exception because I have no user "russ"
Using Visual Studio, and AWS .NET V 3.0.
I'm trying to perform a real-time Predict operation, and to verify the basic setup works, I first perform a GetMLModel() which works and returns the endpoint (Somewhere in the documentation is was mentioned to use that result as the service endpoint, but it's the same that is listed in the console). Is has status "READY", so far so good.
The exception occurs below on the line below "Prediction P = RTP.Predict(Data)". Data contains a Dictionary with all the prediction values.
Error: Error making request with Error Code UnknownOperationException and Http Status Code BadRequest. No further error information was returned by the service.
public static APIResult GetRealTimePrediction(Dictionary<string, string> Data, string PayloadJSON = null) {
AmazonMachineLearningConfig MLConfig = new AmazonMachineLearningConfig();
MLConfig.RegionEndpoint = Amazon.RegionEndpoint.USEast1;
MLConfig.Validate();
AmazonMachineLearningClient MLClient = new AmazonMachineLearningClient("xxx", "xxx", MLConfig);
GetMLModelResponse MLMOdelResp = MLClient.GetMLModel("xxx"); // <-- WORKS
MLConfig.ServiceURL = MLMOdelResp.EndpointInfo.EndpointUrl;
Console.WriteLine(MLConfig.ServiceURL);
MLConfig.Validate();
Amazon.MachineLearning.Util.RealtimePredictor RTP = new Amazon.MachineLearning.Util.RealtimePredictor(MLClient, "xxx");
Prediction P = RTP.Predict(Data); // <----------------EXCEPTION HERE
}
(Obviously replace xxx with relevant values) :)
It turns out that this line:
MLConfig.ServiceURL = MLMOdelResp.EndpointInfo.EndpointUrl;
cases the MLConfig.RegionEndpoint to be reset. Even though the documentation indicates the RegionEndpoint can be determined from the ServiceURL (I'm pretty sure I read that), the RegionEndpoint needs to be set again before the RTP.Predict(Data) call.
Once I figured that out, I was able to reduce the code to just this, in case anyone else needs help. I guess adding too much information to the Configuration is NOT a good thing, as the AWS. NET library seems to figure all this out on its own.
public static APIResult GetRealTimePrediction(Dictionary<string, string> Data, string PayloadJSON = null) {
AmazonMachineLearningConfig MLConfig = new AmazonMachineLearningConfig();
MLConfig.RegionEndpoint = Amazon.RegionEndpoint.USEast1;
MLConfig.Validate(); // Just in case, not really needed
AmazonMachineLearningClient MLClient = new AmazonMachineLearningClient("xxx", "xxx", MLConfig);
Amazon.MachineLearning.Util.RealtimePredictor RTP = new Amazon.MachineLearning.Util.RealtimePredictor(MLClient, "xxx");
Prediction P = RTP.Predict(Data);
}
I am currently working on an MVC site that will hopefully consume an old .asmx Web Service. The documentation for the Web Service provides the following example:
// Construct a request object
TrimRequest request = new TrimRequest();
// Construct a RecordStringSearchClause, with type
// TitleWord, and argument "reef"
RecordStringSearchClause clause = new RecordStringSearchClause();
clause.Type = RecordStringSearchClauseType.TitleWord;
clause.Arg = "reef";
// Construct a record search, and put our search clause in it
WorkerPortalTest.TRIMWS.RecordSearch search = new WorkerPortalTest.TRIMWS.RecordSearch();
search.Items = new RecordClause[] { clause };
// If we had more than one clause, it would look like:
// search.Items = new RecordClause[] { clause1, clause2, clause3 }
// Put our search operation into our TrimRequest
request.Items = new Operation[] { search };
// Send it off. Whatever comes back will be in response
Engine engine = new Engine();
engine.Credentials = newSystem.Net.NetworkCredential(username, password);
TrimResponse response = engine.Execute(request);
As a fairly new C# programmer I understand all of it apart from the last three lines. I have never seen or used the Engine object and Visual Studio does not know of it either.. I looked through MSDN and found this page but it said it was deprecated.
I am just looking for some pointers in the right direction to call the Web Service and receive back the desired result.
Thanks.
Engine is an example of the webservice class. It calls a method in Engine class known as "Execute"..