PCL Web Lib issue for WP8.1 RT and Windows 8.1 RT app - windows-runtime

I am coding a PCL Web Lib calling for Windows Phone 8.1 RT and Windows 8.1 app
While HttpWebRequest Class can NOT modify HOST, referer and so on headers running is Windows RT 8.1 app (WP8.1 RT runs OK, it is a bug in Microsoft)
So I want to use HttpClient Class. One UnResolve issue is how to modify request HOST? I can set different HOST without any exception. But actually, the request HOST is not applied. below is my code:
var client = new HttpClient();
var request = new HttpRequestMessage()
{
RequestUri = new Uri("http://www.bing.com"),
Method = HttpMethod.Get,
};
client.DefaultRequestHeaders.Host = new HostName("12.34.56.78");
//client.DefaultRequestHeaders.Add("Host", "12.34.56.78");
var respose = await client.SendRequestAsync(request);
var content = await respose.Content.ReadAsStringAsync();

According to Wikipedia the host HTTP header is used to identify the virtual host on the server. I think you should set the IP address on the RequestUri and set the host to the desired domain name, for example:
var client = new HttpClient();
var request = new HttpRequestMessage()
{
RequestUri = new Uri("http://12.34.56.78/path"),
Method = HttpMethod.Get,
};
client.DefaultRequestHeaders.Host = new HostName("www.bing.com");
var respose = await client.SendRequestAsync(request);
var content = await respose.Content.ReadAsStringAsync();

Related

how to get pdf file to the temp storage file, from Url in windows phone 8.1

var uri = new System.Uri("ms-appx:///Assets/FixesViaMail_17Dec.pdf", UriKind.Absolute);
StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
This code is working very well because i m using my system file path but whenever i am using this code
var uri = new System.Uri("http://www.visa.com/assets/upload/11458/Hotel/Voucher114581423144270.pdf", UriKind.Absolute);
StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
then i am getting error that is.....
Value does not fall within the expected range.
Please Help me
GetFileFromApplicationUriAsync is only used for loading a file from within your application. To read a file from the web you'll need to download it. You can do this with either the HttpClient (for small files) or BackgroundDownloader (for large files) classes.
var uri = new Uri("http://www.visa.com/assets/upload/11458/Hotel/Voucher114581423144270.pdf");
var httpClient = new HttpClient();
// Always catch network exceptions for async methods
try
{
var response = await httpClient.GetAsync(uri);
// save response out
}
catch
{
// Details in ex.Message and ex.HResult.
}
See Connecting to an HTTP server using Windows.Web.Http.HttpClient (XAML) for more details.
var uri = new Uri("http://www.visa.com/assets/upload/11458/Hotel/Voucher114581423144270.pdf");
BackgroundDownloader download = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(uri, destinationFile);
See Transferring data in the background for more details.

gsutil on a Google Compute Engine VM can't use service account authentication with a key file

I'm launching an instance from the google .net API and despite my best efforts I can't get it to copy anything to or from storage. Currently I'm authenticating with a developer console service account like this:-
string ServiceAccountEmail = "blahblah#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { ComputeService.Scope.Compute, ComputeService.Scope.DevstorageFullControl }
}.FromCertificate(certificate));
var cs = new ComputeService(new BaseClientService.Initializer
{
ApplicationName = "appname",
HttpClientInitializer = (Google.Apis.Http.IConfigurableHttpClientInitializer)credential,
});
Google.Apis.Compute.v1.Data.Instance newinst = new Google.Apis.Compute.v1.Data.Instance();
newinst.Name = "generatedinstance";
newinst.MachineType = "https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/machineTypes/n1-standard-1";
Google.Apis.Compute.v1.Data.AttachedDisk ad = new Google.Apis.Compute.v1.Data.AttachedDisk();
ad.AutoDelete = true;
ad.Boot = true;
ad.Type = "PERSISTENT";
ad.InitializeParams = new Google.Apis.Compute.v1.Data.AttachedDiskInitializeParams();
ad.InitializeParams.DiskName = "newdisk";
ad.InitializeParams.SourceImage = "https://www.googleapis.com/compute/v1/projects/projectid/global/images/customimage";
ad.InitializeParams.DiskType = "https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/diskTypes/pd-standard";
ad.Mode = "READ_WRITE";
newinst.Disks = new List<Google.Apis.Compute.v1.Data.AttachedDisk>();
newinst.Disks.Add(ad);
Google.Apis.Compute.v1.Data.NetworkInterface ni = new Google.Apis.Compute.v1.Data.NetworkInterface();
ni.Network = "https://www.googleapis.com/compute/v1/projects/projectid/global/networks/default";
ni.AccessConfigs = new List<Google.Apis.Compute.v1.Data.AccessConfig>();
ni.AccessConfigs.Add(new Google.Apis.Compute.v1.Data.AccessConfig
{
Type = "ONE_TO_ONE_NAT",
Name = "External NAT",
});
newinst.NetworkInterfaces = new List<Google.Apis.Compute.v1.Data.NetworkInterface>();
newinst.NetworkInterfaces.Add(ni);
var start = new Google.Apis.Compute.v1.Data.Metadata.ItemsData();
start.Key = "startup-script";
start.Value = "*startup script* includes gsutil cp which won't work without service account attached";
newinst.Metadata = new Google.Apis.Compute.v1.Data.Metadata();
newinst.Metadata.Kind = "compute#metadata";
newinst.Metadata.Items = new List<Google.Apis.Compute.v1.Data.Metadata.ItemsData>();
newinst.Metadata.Items.Add(start);
newinst.ServiceAccounts = new List<Google.Apis.Compute.v1.Data.ServiceAccount>();
//var sa = new Google.Apis.Compute.v1.Data.ServiceAccount();|with this section
//sa.Email = "blahblah#developer.gserviceaccount.com"; |the instance won't
//sa.Scopes = new[] { ComputeService.Scope.Compute, |start. (An equivalent
ComputeService.Scope.DevstorageFullControl }; |is found in instance
//newinst.ServiceAccounts.Add(sa); |start REST request)
var instinsert = new InstancesResource.InsertRequest(cs, newinst, "projectid", "zone");
var insertresponse = instinsert.Execute();
The message I get when I try to use gsutil cp is "You do not currently have an active account selected.". Can anyone tell me where I'm going wrong?
You need to run gcloud auth activate-service-account blahblah#developer.gserviceaccount.com --key-file path_to_key.p12 to tell the Cloud SDK (including gsutil) about your service account.
As per the code provided, I can see that the original example has
var certificate = new X509Certificate2(#"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
I notice you are missing the '#'in your code. I'm not very familiar with .Net. I have tested these examples in python and this one. When creating my instance I added the service account for GCS and the file is uploaded correctly.
OKAY! Problem solved. The part I was getting wrong was the bit commented out in the question-
var sa = new Google.Apis.Compute.v1.Data.ServiceAccount();
sa.Email = "blahblah#developer.gserviceaccount.com";
sa.Scopes = new[] { ComputeService.Scope.Compute,
ComputeService.Scope.DevstorageFullControl };
newinst.ServiceAccounts.Add(sa);
I needed the email for the main service account for the developer console in this section rather than the same service account I used to create the credentials but don't ask me why. Point is the instance launches and gsutil is now happily copying away.
Thanks for your time and help everyone!
Ross

How to access contacts API with Service Account

I am in the process of upgrading my Marketplace applications to support the new marketplace api and OAUTH 2.
I have managed to migrate most APIs but am stuck on the contacts api. With the the previous marketplace version we used 2LO and client key/client secret to authenticate across the Google Apps domain. My understanding is that the only way to do this in current version is with Service Accounts and OAuth 2.
Based on the V3 calendar API I'm assuming something like this (although the contacts API does not support it from what I can see) -
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { "https://www.google.com/m8/feeds" },
User = "admin#domain.co"
}.FromCertificate(certificate));
var service = new ContactsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Contact API Sample",
});
If anybody has done this, your advice will be appreciated!
I know this question has been answered, but adding an alternative that doesn't require the AssertionFlowClient or a specific version of DotNetOpenAuth. This allows you to use the same ServiceAccountCredential code from your original question (ie, using the same method to query a user's gmail)
Thank you for following up on your own post, it helped me find this solution!
private static ServiceAccountCredential GenerateCred(IEnumerable<string> scopes, string delegationUser)
{
var certificate = new X509Certificate2(certLocation, certPassword, X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes,
User = delegationUser
}.FromCertificate(certificate));
return credential;
}
var credential = GenerateCred(new[] { "https://www.googleapis.com/auth/contacts.readonly" }, userToDelegate);
//Get the token for this scope and user
await credential.RequestAccessTokenAsync(new CancellationToken());
//use the token to initalize the request
var rs = new RequestSettings(projectName)
{
OAuth2Parameters = new OAuth2Parameters()
{
AccessToken = credential.Token.AccessToken
}
};
var request = new ContactsRequest(rs);
Feed<Contact> f = request.GetContacts();
foreach (var c in f.Entries)
{
//process each contact
}
Well I got no response anywhere on this so I can only assume that the standard client libraries don't have support for this.
I have come up with a workaround based on the following post for email access.
http://www.limilabs.com/blog/oauth2-gmail-imap-service-account
You will need to follow his post and note the following:
this must use the DotNetOpenAuth version that he specifies. The latest version will not work.
You will only need his AssertionFlowClient classes which can be added to the below code I have provided here:
X509Certificate2 certificate = new X509Certificate2(
serviceAccountCertPath,
serviceAccountCertPassword,
X509KeyStorageFlags.Exportable);
AuthorizationServerDescription server = new AuthorizationServerDescription
{
AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"),
TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
ProtocolVersion = ProtocolVersion.V20,
};
AssertionFlowClient provider = new AssertionFlowClient(server, certificate)
{
ServiceAccountId = serviceAccountEmail,
Scope = string.Join(" ", new[] { "https://mail.google.com/", "https://www.google.com/m8/feeds/" }),
ServiceAccountUser = userEmail,
};
IAuthorizationState grantedAccess = AssertionFlowClient.GetState(provider);
RequestSettings rs = new RequestSettings("iLink");
rs.OAuth2Parameters = new OAuth2Parameters();
rs.OAuth2Parameters.AccessToken = grantedAccess.AccessToken;
rs.OAuth2Parameters.RefreshToken = null;
rs.OAuth2Parameters.ClientId = null;
rs.OAuth2Parameters.ClientSecret = null;
rs.OAuth2Parameters.RedirectUri = null;
ContactsRequest cr = new ContactsRequest(rs);
Feed<Contact> f = cr.GetContacts();
foreach (var c in f.Entries)
{
Response.Write(c.Name.FullName);
}

how to use HttpClient in WindowsPhone 8

Hey everyone i have a big problem with this thing. i'm trying to use HttpClient method in my new project. i try this code:
var httpClient = new HttpClient();
var request = await httpClient.GetAsync(new Uri("http://www.google.com/", UriKind.RelativeOrAbsolute));
var txt = request.Content.ReadAsStringAsync();
MessageBox.Show(txt.Result);
i think it is true code because i wrote it in Console app and it works fine. Then i opened a new WindowsPhone 8 project and write this code.And code doesn't work, it returns Null. Sometimes it works but generally not. i thought my Visual Studio wasnt work good and i deleted it and re-install it, and nothing had been changed. what do you think?
try this.
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(new Uri("http://www.google.com/", UriKind.RelativeOrAbsolute));
response.EnsureSuccessStatusCode();
var txt = response.Content.ReadAsStringAsync();
MessageBox.Show(txt.Result);
make the breakpoint in the line response.EnsureSuccessStatusCode(); to make sure response httpcode is 200 every time.
You shouldn't be calling Result. Try this instead:
var httpClient = new HttpClient();
var request = await httpClient.GetAsync(new Uri("http://www.google.com/", UriKind.RelativeOrAbsolute));
var txt = await request.Content.ReadAsStringAsync();
MessageBox.Show(txt);

Exchange web service returns 401 unauthorized when run from web page

I am using EWS for sending email from web page. When I run this code in console application It's successfuly executed:
var sender = "sample#mail.com";
var fromPassword = "pass";
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.Credentials = new WebCredentials(sender, fromPassword);
service.Url = new Uri("https://testserver.com/EWS/Exchange.asmx");
ServicePointManager.ServerCertificateValidationCallback = delegate(object s,
X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
return true;
};
EmailMessage message = new EmailMessage(service);
message.Subject = "test";
message.Body = "test";
message.ToRecipients.Add("sample#gmail.com");
message.SendAndSaveCopy();
When I run the same code from web page in my sharepoint application I get error "401 unauthorized" when SendAndSaveCopy method executing.
What I am doing wrong?
Thanks.