Could someone provide a C# example using itemsearch from Amazon Web Services - c#

I am trying to use Amazon Web Services to query Artist and title information and receive album art back. Using C# I cannot find any examples that come even close to this. All of the examples online are outdated and do not work with AWS' newer version.

There is an open Source project on CodePlex you might want to take a look at.... It's A .NET Library for Amazon's Web Services. S3, SQS, FPS, EC2, and DevPay
It could be as simple as this(as shown on codeplex):
S3Client s3 = new S3Client("myAWSKey", "MyAWSPassword");
bool success = s3.Connect();
S3Client s3 = new S3Client("key", "secret"):
var buckets = from b in s3.Buckets
where b.Name == "demo"
select b;
foreach(Bucket b in buckets)
{
Console.WriteLine(b.About());
}

Here you go for what it's worth. This is code within an Asp.Net control to display book information. You can probably adapt it for your purposes easily enough. Or at least give you a starting-point. If you really want, I'd be happy to bundle the control up and send it your way.
if (!(string.IsNullOrEmpty(ISBN) && string.IsNullOrEmpty(ASIN)))
{
AWSECommerceService service = new AWSECommerceService();
ItemLookup lookup = new ItemLookup();
ItemLookupRequest request = new ItemLookupRequest();
lookup.AssociateTag = ConfigurationManager.AppSettings["AssociatesTag"];
lookup.AWSAccessKeyId = ConfigurationManager.AppSettings["AWSAccessKey"];
if (string.IsNullOrEmpty(ASIN))
{
request.IdType = ItemLookupRequestIdType.ISBN;
request.ItemId = new string[] { ISBN.Replace("-", "") };
}
else
{
request.IdType = ItemLookupRequestIdType.ASIN;
request.ItemId = new string[] { ASIN };
}
request.ResponseGroup = ConfigurationManager.AppSettings["AWSResponseGroups"].Split(new char[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
lookup.Request = new ItemLookupRequest[] { request };
ItemLookupResponse response = service.ItemLookup(lookup);
if (response.Items.Length > 0 && response.Items[0].Item.Length > 0)
{
Item item = response.Items[0].Item[0];
if (item.MediumImage == null)
{
bookImageHyperlink.Visible = false;
}
else
{
bookImageHyperlink.ImageUrl = item.MediumImage.URL;
}
bookImageHyperlink.NavigateUrl = item.DetailPageURL;
bookTitleHyperlink.Text = item.ItemAttributes.Title;
bookTitleHyperlink.NavigateUrl = item.DetailPageURL;
if (item.OfferSummary.LowestNewPrice == null)
{
if (item.OfferSummary.LowestUsedPrice == null)
{
priceHyperlink.Visible = false;
}
else
{
priceHyperlink.Text = string.Format("Buy used {0}", item.OfferSummary.LowestUsedPrice.FormattedPrice);
priceHyperlink.NavigateUrl = item.DetailPageURL;
}
}
else
{
priceHyperlink.Text = string.Format("Buy new {0}", item.OfferSummary.LowestNewPrice.FormattedPrice);
priceHyperlink.NavigateUrl = item.DetailPageURL;
}
if (item.ItemAttributes.Author != null)
{
authorLabel.Text = string.Format("By {0}", string.Join(", ", item.ItemAttributes.Author));
}
else
{
authorLabel.Text = string.Format("By {0}", string.Join(", ", item.ItemAttributes.Creator.Select(c => c.Value).ToArray()));
}
ItemLink link = item.ItemLinks.Where(i => i.Description.Contains("Wishlist")).FirstOrDefault();
if (link == null)
{
wishListHyperlink.Visible = false;
}
else
{
wishListHyperlink.NavigateUrl = link.URL;
}
}
}

Related

C# Roslyn CompletionService where to get method overload information

I've got a method that returning back from CompletionService.GetDescriptionAsync(Document, CompletionItem) gives me the following description:
void SQL.GetSQLiteDB(string url) (+ 1 overload)
This is a method I made on a Xamarin project, here are both method signatures:
public static void GetSQLiteDB(string url);
public static string GetSQLiteDB(string url, string name);
What's the Roslyn way to get information on both?
Here's how I'm setting up completions:
async Task InitCodeCompletion()
{
host = MefHostServices.Create(MefHostServices.DefaultAssemblies);
workspace = new AdhocWorkspace(host);
Type[] types =
{
typeof(object),
typeof(System.Linq.Enumerable),
typeof(System.Collections.IEnumerable),
typeof(Console),
typeof(System.Reflection.Assembly),
typeof(List<>),
typeof(Type),
typeof(SQL)
};
imports = types.Select(x => x.Namespace).Distinct().ToImmutableArray();
assemblies = types.Select(x => x.Assembly).Distinct().ToImmutableArray();
references = assemblies.Select(t => MetadataReference.CreateFromFile(t.Location) as MetadataReference).ToImmutableArray();
compilationOptions = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
usings: imports);
projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Script", "Script", LanguageNames.CSharp, isSubmission: true)
.WithMetadataReferences(references).WithCompilationOptions(compilationOptions);
project = workspace.AddProject(projectInfo);
documentInfo = DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "Script", sourceCodeKind: SourceCodeKind.Script,
loader: TextLoader.From(TextAndVersion.Create(SourceText.From(""), VersionStamp.Create())));
document = workspace.AddDocument(documentInfo);
var services = workspace.Services;
completionService = CompletionService.GetService(document);
}
async Task<CodeCompletionResults> GetCompletions(string code)
{
string codeModified = "using SQL = XamTestNET5.Services.SQLiteGeneratorService; " + Environment.NewLine;
codeModified += "using HtmlSvc = XamTestNET5.Services.HtmlRetrievalService;" + Environment.NewLine;
// ^^^ The above two lines set up some simple namespace aliases in my project, if you know how to put this in a separate project document and use it in code completion please let me know in comments as otherwise doing so gives me an exception that you can't have multiple syntax trees
codeModified += code;
var source = SourceText.From(codeModified);
document = document.WithText(source);
// cursor position is at the end
var position = source.Length;
var completions = await completionService.GetCompletionsAsync(document, position);
return new CodeCompletionResults() { InputCode = code, ModifiedCode = codeModified, Completions = completions };
}
Here's how I'm getting them now and putting them in a browser control:
private async void CSharpShellEnvironment_EntryCodeCompletionEntry(object sender, CSharpShellEnvironment.EntryEventArgs e)
{
if (e.Value != "")
{
CodeCompletionResults results = await GetCompletions(e.Value);
CompletionList list = results.Completions;
if (list != null)
{
if (list.Items != null)
{
StringBuilder sb = new StringBuilder();
foreach (var item in list.Items)
{
string spanText = (item.Span.Start != item.Span.End) ? results.ModifiedCode.Substring(item.Span.Start, item.Span.Length) : "";
bool recommended = spanText == "" ? true : item.DisplayText.StartsWith(spanText);
if (recommended)
{
string fText = item.DisplayText.Substring(spanText.Length);
string props = "";
foreach(var p in item.Properties)
{
props += $"<span data-key=\"{p.Key}\" data-value=\"{p.Value}\"></span>";
}
string tags = "";
foreach(var t in item.Tags)
{
tags += $"<span data-tag=\"{t}\"></span>";
}
string descStr = "";
if (item.Tags != null)
{
if (item.Tags.Where(x => x.ToLower() == "method").FirstOrDefault() != null && item.Tags.Where(x => x.ToLower() == "public").FirstOrDefault() != null)
{
var desc = await completionService.GetDescriptionAsync(document, item);
descStr += $"<span data-desc=\"{desc.Text}\">";
foreach(var part in desc.TaggedParts)
{
descStr += $"<span data-desc-part-tag=\"{part.Tag}\" data-desc-part-text=\"{part.Text}\"></span>";
}
descStr += "</span>";
}
}
sb.AppendLine($"<div class=\"codecompleteentry\" data-display-text=\"{item.DisplayText}\" data-span-text=\"{spanText}\" data-final-text=\"{fText}\">{props}{tags}{descStr}{fText}</div>");
}
}
string scriptInputClick = "Array.prototype.forEach.call(document.getElementsByClassName('codecompleteentry'), function(el) { el.addEventListener('click', function(elem) { var text = { MessageType: 'CodeCompletion', Parameters: JSON.stringify({ DataDisplayText: el.getAttribute('data-display-text'), DataSpanText: el.getAttribute('data-span-text'), DataFinalText: el.getAttribute('data-final-text') }), Message: el.innerText }; window.chrome.webview.postMessage(text); } ); });";
sb.AppendLine($"<script type=\"text/javascript\">{scriptInputClick}</script>");
env.EnterCodeCompletionResponse(sb.ToString());
}
else
{
env.EnterCodeCompletionResponse(strNoSuggestions);
}
}
else
{
env.EnterCodeCompletionResponse(strNoSuggestions);
}
}
else
{
env.EnterCodeCompletionResponse(strNoSuggestions);
}
}
It seems on the surface that CompletionSurface has everything you need, but it doesn't, you need to reference the Document's SemanticModel in order to get all of the signature overloads of a method when the user types ( on a method during code completion.
It wasn't very obvious to me until I started looking through the RoslynPad source, which I recommend doing for a practical example: https://github.com/aelij/RoslynPad
List<IEnumerable<ReferencedSymbol>> allMethodRefs = new List<IEnumerable<ReferencedSymbol>>();
async Task<CodeCompletionResults> GetCompletions(string code)
{
string codeModified = "using SQL = XamTestNET5.Services.SQLiteGeneratorService; " + Environment.NewLine;
codeModified += "using HtmlSvc = XamTestNET5.Services.HtmlRetrievalService;" + Environment.NewLine;
// ^^^ I put my namespace aliases in the same SyntaxTree for now,
// I'd like a better solution though.
codeModified += code;
var source = SourceText.From(codeModified);
document = document.WithText(source);
// cursor position is at the end
var position = source.Length;
var completions = await completionService.GetCompletionsAsync(document, position);
syntaxRoot = await document.GetSyntaxRootAsync();
semanticModel = await document.GetSemanticModelAsync();
var methods = syntaxRoot.DescendantNodes().OfType<InvocationExpressionSyntax>();
allMethodRefs = new List<IEnumerable<ReferencedSymbol>>();
if (methods != null)
{
if (methods.Count() > 0)
{
foreach(var m in methods)
{
var info = semanticModel.GetSymbolInfo(m);
if (info.Symbol != null)
{
allMethodRefs.Add(await SymbolFinder.FindReferencesAsync(info.Symbol, solution));
}
else
{
foreach(var symbol in info.CandidateSymbols)
{
allMethodRefs.Add(await SymbolFinder.FindReferencesAsync(symbol, solution));
}
}
}
}
}
return new CodeCompletionResults() { InputCode = code, ModifiedCode = codeModified, Completions = completions };
}

Check if AWS Lambda function completed the job

I am currently sending a file to be transcoded to my AWS lambda function. After I send the file, I send a notification to the SQS for some external aplication to start downloading the transcoded files.
The problem is, sometimes, the download of the files happen before the Lambda function completed.
How can I only send the notification to SQS after the Lambda completed.
I tried getting the Job.Status as follow, but not sure how to query it again if Status is not Complete.
Here is my code:
using (var eClient = new AmazonElasticTranscoderClient())
{
var response = await this.S3Client.GetObjectMetadataAsync(s3Event.Bucket.Name, s3Event.Object.Key);
var videoPresets = new List<Preset>();
var presetRequest = new ListPresetsRequest();
ListPresetsResponse presetResponse;
do
{
presetResponse = await eClient.ListPresetsAsync(presetRequest);
videoPresets.AddRange(presetResponse.Presets);
presetRequest.PageToken = presetResponse.NextPageToken;
} while (presetResponse.NextPageToken != null);
var pipelines = new List<Pipeline>();
var pipelineRequest = new ListPipelinesRequest();
ListPipelinesResponse pipelineResponse;
do
{
pipelineResponse = await eClient.ListPipelinesAsync(pipelineRequest);
pipelines.AddRange(pipelineResponse.Pipelines);
pipelineRequest.PageToken = pipelineResponse.NextPageToken;
} while (pipelineResponse.NextPageToken != null);
var pipeLine = s3Event.Bucket.Name.ToLower().Contains("test") ? pipelines.First(p => p.Name.ToLower().Contains("test")) : pipelines.First(p => !p.Name.ToLower().Contains("test"));
//HLS Stuff for Apple
var usablePreset = videoPresets.Where(p => p.Name.Contains("HLS") && !p.Name.Contains("HLS Video")).ToList();
var hlsPresets = new List<Preset>();
foreach (var preset in usablePreset)
{
var resolution = preset.Name.Replace("System preset: HLS ", "");
switch (resolution)
{
case "2M":
case "1M":
case "400k":
hlsPresets.Add(preset);
break;
}
}
var jobReq = new CreateJobRequest
{
PipelineId = pipeLine.Id,
Input = new JobInput() { Key = fileName, },
OutputKeyPrefix = outPutPrefix
//OutputKeyPrefix = "LambdaTest/" + playlistName + "/"
};
var outputs = new List<CreateJobOutput>();
var playlistHLS = new CreateJobPlaylist() { Name = "HLS_" + playlistName, Format = "HLSv3" };
foreach (var preset in hlsPresets)
{
var resolution = preset.Name.Replace("System preset: HLS ", "").Replace(".", "");
var newName = resolution + "_" + playlistName;
var output = new CreateJobOutput() { Key = newName, PresetId = preset.Id, SegmentDuration = "10" };
outputs.Add(output);
playlistHLS.OutputKeys.Add(newName);
}
jobReq.Playlists.Add(playlistHLS);
jobReq.Outputs = outputs;
//var temp = JsonConvert.SerializeObject(jobReq);
var reply = eClient.CreateJobAsync(jobReq);
var transcodingCompleted = reply.Result.Job.Status == "Complete" ? true : false;
do {
//somehow need to query status again
} while (!transcodingCompleted);
if (transcodingCompleted)
await SendAsync(jobReq.OutputKeyPrefix, pipeLine.OutputBucket);
}
The part I am interested in:
var reply = eClient.CreateJobAsync(jobReq);
var transcodingCompleted = reply.Result.Job.Status == "Complete" ? true : false;
do {
//somehow need to query status again
} while (!transcodingCompleted);
if (transcodingCompleted)
await SendAsync(jobReq.OutputKeyPrefix, pipeLine.OutputBucket);

How to refund amount of paypal adaptive payment using PayPal.AdaptivePayments SDK?

I`m using PayPal.AdaptivePayments sdk for chained payment and refund process of chained payment.
Using following methods:
for payment : pay() method
for refund : refund() method as per sdk.
When try to refund with payKey then getting response with status: "NO_API_ACCESS_TO_RECEIVER"
Currently I`m sandbox account on development.
I have also followed paypal developer api/sdk docs but still getting same problem.
So please help me to refund process with status of "Refunded".
I have already review post related to this on stack-overflow but I didn`t proper solution in any post.
https://devtools-paypal.com/guide/ap_chained_payment?interactive=ON&env=sandbox
private void Refund(HttpContext contextHttp)
{
NameValueCollection parameters = contextHttp.Request.Params;
RefundRequest request = new RefundRequest(new RequestEnvelope("en_US"));
// Set optional parameters
if(parameters["receiverEmail"].Length > 0)
{
//(Required) Amount to be paid to the receiver
string[] amt = contextHttp.Request.Form.GetValues("receiverAmount");
// Maximum length: 127 characters
string[] receiverEmail = contextHttp.Request.Form.GetValues("receiverEmail");
//Telephone country code
string[] phoneCountry = contextHttp.Request.Form.GetValues("phoneCountry");
string[] phoneNumber = contextHttp.Request.Form.GetValues("phoneNumber");
//Telephone extension
string[] phoneExtn = contextHttp.Request.Form.GetValues("phoneExtn");
string[] primaryReceiver = contextHttp.Request.Form.GetValues("primaryReceiver");
string[] invoiceId = contextHttp.Request.Form.GetValues("invoiceId");
string[] paymentType = contextHttp.Request.Form.GetValues("paymentType");
//(Optional) The transaction subtype for the payment.
string[] paymentSubType = contextHttp.Request.Form.GetValues("paymentSubType");
List<Receiver> receivers = new List<Receiver>();
for(int i=0; i<amt.Length; i++) {
Receiver r = new Receiver(Convert.ToDecimal(amt[i]));
r.email = receiverEmail[i];
r.primary = Convert.ToBoolean(primaryReceiver[i]);
if(invoiceId[i] != string.Empty) {
r.invoiceId = invoiceId[i];
}
if(paymentType[i] != string.Empty) {
r.paymentType = paymentType[i];
}
if(paymentSubType[i] != string.Empty) {
r.paymentSubType = paymentSubType[i];
}
if(phoneCountry[i] != string.Empty && phoneNumber[i] != string.Empty) {
r.phone = new PhoneNumberType(phoneCountry[i], phoneNumber[i]);
if(phoneExtn[i] != string.Empty) {
r.phone.extension = phoneExtn[i];
}
}
receivers.Add(r);
}
request.receiverList = new ReceiverList(receivers);
}
if(parameters["currencyCode"] != string.Empty) {
request.currencyCode = parameters["currencyCode"];
}
if(parameters["payKey"] != string.Empty) {
request.payKey = parameters["payKey"];
}
if(parameters["transactionId"] != string.Empty) {
request.transactionId = parameters["transactionId"];
}
if(parameters["trackingId"] != string.Empty) {
request.trackingId = parameters["trackingId"];
}
AdaptivePaymentsService service = null;
RefundResponse response = null;
try
{
Dictionary<string, string> configurationMap = Configuration.GetAcctAndConfig();
service = new AdaptivePaymentsService(configurationMap);
response = service.Refund(request);
}
catch (System.Exception e)
{
contextHttp.Response.Write(e.Message);
return;
}
Dictionary<string, string> responseValues = new Dictionary<string, string>();
// string redirectUrl = null;
string redirectUrl = null;
if (!(response.responseEnvelope.ack == AckCode.FAILURE) &&
!(response.responseEnvelope.ack == AckCode.FAILUREWITHWARNING))
{
responseValues.Add("Currency code", response.currencyCode);
int idx = 1;
foreach (RefundInfo refund in response.refundInfoList.refundInfo)
{
//Receiver's email address.Maximum length: 127 characters
responseValues.Add("Refund receiver " + idx, refund.receiver.email);
// Amount to be refunded to the receiver.
responseValues.Add("Refund amount " + idx, refund.receiver.amount.ToString());
responseValues.Add("Refund status " + idx, refund.refundStatus);
responseValues.Add("Acknowledgement", response.responseEnvelope.ack.ToString());
}
}
Display(contextHttp, "Refund", responseValues, service.getLastRequest(), service.getLastResponse(), response.error, redirectUrl);
}

CefSharp 3 set proxy at Runtime

I downloaded CEF (chromuim embedded framework) binary distributation that comes with (cefclient & cefsimple) c++ examples, And Realized that cefclient can change proxy settings on run-time.
And the key to do that is to Grab the RequestContext and call the function SetPreference.
on CefClient all works just nice.
but on CefSharp calling SetPreference always returns false, and also HasPreference returns false for the preference name "proxy".
thanks to amaitland the proper way to actively inforce changing the request-context prefrences, is to run the code on CEF UIThread as following:
Cef.UIThreadTaskFactory.StartNew(delegate {
var rc = this.browser.GetBrowser().GetHost().RequestContext;
var v = new Dictionary<string, object>();
v["mode"] = "fixed_servers";
v["server"] = "scheme://host:port";
string error;
bool success = rc.SetPreference("proxy", v, out error);
//success=true,error=""
});
if anyone need any other soulition i found this solution.
Cef.UIThreadTaskFactory.StartNew(delegate
{
string ip = "ip or adress";
string port = "port";
var rc = this.browser.GetBrowser().GetHost().RequestContext;
var dict = new Dictionary<string, object>();
dict.Add("mode", "fixed_servers");
dict.Add("server", "" + ip + ":" + port + "");
string error;
bool success = rc.SetPreference("proxy", dict, out error);
});
I downloaded CefSharp.WinForms 65.0.0 and made class, that can help to start working with proxy:
public class ChromeTest
{
public static ChromiumWebBrowser Create(WebProxy proxy = null, Action<ChromiumWebBrowser> onInited = null)
{
var result = default(ChromiumWebBrowser);
var settings = new CefSettings();
result = new ChromiumWebBrowser("about:blank");
if (proxy != null)
result.RequestHandler = new _requestHandler(proxy?.Credentials as NetworkCredential);
result.IsBrowserInitializedChanged += (s, e) =>
{
if (!e.IsBrowserInitialized)
return;
var br = (ChromiumWebBrowser)s;
if (proxy != null)
{
var v = new Dictionary<string, object>
{
["mode"] = "fixed_servers",
["server"] = $"{proxy.Address.Scheme}://{proxy.Address.Host}:{proxy.Address.Port}"
};
if (!br.GetBrowser().GetHost().RequestContext.SetPreference("proxy", v, out string error))
MessageBox.Show(error);
}
onInited?.Invoke(br);
};
return result;
}
private class _requestHandler : DefaultRequestHandler
{
private NetworkCredential _credential;
public _requestHandler(NetworkCredential credential = null) : base()
{
_credential = credential;
}
public override bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
if (isProxy == true)
{
if (_credential == null)
throw new NullReferenceException("credential is null");
callback.Continue(_credential.UserName, _credential.Password);
return true;
}
return false;
}
}
}
Using:
var p = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
var p1 = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
var p2 = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
wb1 = ChromeTest.Create(p1, b => b.Load("http://speed-tester.info/check_ip.php"));
groupBox1.Controls.Add(wb1);
wb1.Dock = DockStyle.Fill;
wb2 = ChromeTest.Create(p2, b => b.Load("http://speed-tester.info/check_ip.php"));
groupBox2.Controls.Add(wb2);
wb2.Dock = DockStyle.Fill;
wb3 = ChromeTest.Create(p, b => b.Load("http://speed-tester.info/check_ip.php"));
groupBox3.Controls.Add(wb3);
wb3.Dock = DockStyle.Fill;
If you want dynamic proxy resolver (proxy hanlder), which allow you to use different proxy for different host - you should:
1) Prepare javascript
var proxy1Str = "PROXY 1.2.3.4:5678";
var proxy2Str = "PROXY 2.3.4.5:6789";
var ProxyPacScript =
$"var proxy1 = \"{(proxy1Str.IsNullOrEmpty() ? "DIRECT" : proxy1Str)}\";" +
$"var proxy2 = \"{(proxy2Str.IsNullOrEmpty() ? "DIRECT" : proxy2Str)}\";" +
#"function FindProxyForURL(url, host) {
if (shExpMatch(host, ""*example.com"")) {
return proxy1;
}
return proxy2;
}";
var bytes = Encoding.UTF8.GetBytes(ProxyPacScript);
var base64 = Convert.ToBase64String(bytes);
2) Set it correctly
var v = new Dictionary<string, object>();
v["mode"] = "pac_script";
v["pac_url"] = "data:application/x-ns-proxy-autoconfig;base64," + base64;
3) Call SetPreference as in accepted answer https://stackoverflow.com/a/36106994/9252162
As result all request to *example.com will flow throught proxy1, all others through proxy2.
To do it I spent all day but with help of source (https://cs.chromium.org/) I found solution. Hope it helps someone.
Main problems:
1) In new version (72 or 74 as I remember) there is no ability to use "file://..." as pac_url.
2) We can't use https://developer.chrome.com/extensions/proxy in cef.. or i can't find how to do it.
p.s. How to use another types of proxy (https, socks) - https://chromium.googlesource.com/chromium/src/+/master/net/docs/proxy.md#evaluating-proxy-lists-proxy-fallback
With the new version of CefSharp, it's quite simple to set proxy:
browser = new ChromiumWebBrowser();
panel1.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
await browser.LoadUrlAsync("about:blank");
await Cef.UIThreadTaskFactory.StartNew(() =>
{
browser.GetBrowser().GetHost().RequestContext.SetProxy("127.0.0.1", 1088, out string _);
});

EWS Search for Fields like Company or Street in Global Address List

I try to write a Webservice that can access to my exchange-server and search for names, companys and cities. At the moment i get the names like this:
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.UseDefaultCredentials = true;
// Create the ResolveNamesType and set
// the unresolved entry.
ResolveNamesType rnType = new ResolveNamesType();
rnType.ReturnFullContactData = true;
rnType.UnresolvedEntry = "searchname";
// Resolve names.
ResolveNamesResponseType resolveNamesResponse
= esb.ResolveNames(rnType);
ArrayOfResponseMessagesType responses
= resolveNamesResponse.ResponseMessages;
// Check the result.
if (responses.Items.Length > 0 && responses.Items[0].ResponseClass != ResponseClassType.Error)
{
ResolveNamesResponseMessageType responseMessage = responses.Items[0] as
ResolveNamesResponseMessageType;
// Display the resolution information.
ResolutionType[] resolutions = responseMessage.ResolutionSet.Resolution;
foreach (ResolutionType resolution in resolutions)
{
Console.WriteLine(
"Name: " +
resolution.Contact.DisplayName
);
Console.WriteLine(
"EmailAddress: " +
resolution.Mailbox.EmailAddress
);
if (resolution.Contact.PhoneNumbers != null)
{
foreach (
PhoneNumberDictionaryEntryType phone
in resolution.Contact.PhoneNumbers)
{
Console.WriteLine(
phone.Key.ToString() +
" : " +
phone.Value
);
}
}
Console.WriteLine(
"Office location:" +
resolution.Contact.OfficeLocation
);
Console.WriteLine("\n");
}
}
But anybody know how i can serach for Propertys like Company and Street?
EWS only has limited Directory operations if your using OnPrem Exchange then the easiest way to do this is just use LDAP and lookup Active Directory directly. The resolveName operation is meant to be used to resolve a partial number and doesn't work with any other properties. If you have Exchange 2013 then there is the FindPeople operation http://msdn.microsoft.com/en-us/library/office/jj191039(v=exchg.150).aspx which supports using a QueryString which should work if those properties are indexed. eg
EWSProxy.FindPeopleType fpType = new EWSProxy.FindPeopleType();
EWSProxy.IndexedPageViewType indexPageView = new EWSProxy.IndexedPageViewType();
indexPageView.BasePoint = EWSProxy.IndexBasePointType.Beginning;
indexPageView.Offset = 0;
indexPageView.MaxEntriesReturned = 100;
indexPageView.MaxEntriesReturnedSpecified = true;
fpType.IndexedPageItemView = indexPageView;
fpType.ParentFolderId = new EWSProxy.TargetFolderIdType();
EWSProxy.DistinguishedFolderIdType Gal = new EWSProxy.DistinguishedFolderIdType();
Gal.Id = EWSProxy.DistinguishedFolderIdNameType.directory;
fpType.QueryString = "Office";
fpType.ParentFolderId.Item = Gal;
EWSProxy.FindPeopleResponseMessageType fpm = null;
do
{
fpm = esb.FindPeople(fpType);
if (fpm.ResponseClass == EWSProxy.ResponseClassType.Success)
{
foreach (EWSProxy.PersonaType PsCnt in fpm.People)
{
Console.WriteLine(PsCnt.EmailAddress.EmailAddress);
}
indexPageView.Offset += fpm.People.Length;
}
else
{
throw new Exception("Error");
}
} while (fpm.TotalNumberOfPeopleInView > indexPageView.Offset);
Cheers
Glen

Categories