Windows 8 Httpclient basic authentcation - dotnet-httpclient

I am new to this forum.
I am trying to do Basic authentication using Httclient for my Windows app.
var handler2 = new HttpClientHandler
{
Credentials = new NetworkCredential(username, password)
};
var httpClient2 = new HttpClient(handler2);
httpClient2.DefaultRequestHeaders.Add("user-Agent", "authentication.cs");
var response2 = httpClient.GetAsync(uri);
I have 2 questions:
I need to add header content type and user-agent. Dont know how to add them. Could someone help me out.
In response i am getting null values. Any idea why?
Regards,
TM

You can add the user agent header by doing
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("authentication.cs"));
You can't add Content-Type to the default request headers because you can only set Content-Type when you are sending some Content using a PUT or a POST.
I'm guessing you want to set the Accept header like this:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
Update: Without my own account, this is as far as I can go.
public sealed partial class MainPage : Page
{
private readonly HttpClient _httpClient = new HttpClient();
public MainPage()
{
this.InitializeComponent();
InitHttpClient();
}
private void InitHttpClient() {
var username = "youremail#somewhere.com";
var password = "yourharvestpassword";
String authparam = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authparam);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MyHarvestClient", "1.0"));
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e) {
_httpClient.GetAsync("https://yoursubdomain.harvestapp.com/projects")
.ContinueWith(t => HandleResponse(t.Result));
}
private void HandleResponse(HttpResponseMessage response) {
response.EnsureSuccessStatusCode();
var contentString = response.Content.ReadAsStringAsync().Result;
var contentXML = XDocument.Parse(contentString);
}
}

Related

Woocommerce Create Order REST API and Xamarin Forms

I'm building a checkout page written in Xamarin Forms that creates an order in Woocommerce.
I've looked up documentation online but can't seem to find any examples or code that shows you how to do this.
My question is : is there an example code on how to create a simple order using Xamarin Forms and Woocommerce REST API?
I was able to use the REST API to pull the products from Woocommerce but can't seem to find any code examples of how to actually create an order using the REST API in Xamarin Forms.
Hope you can help.
Cheers
Here's my code woocommerceapi.cs class.
class WoocommerceAPI
{
private static string website_url = "xxxxx";
private static string consumer_key = "xxxxx";
private static string consumer_secret = "xxxxx";
private static string GetAllProductsApiUrl = string.Format("{0}/wc-api/v3/products?consumer_key={1}&consumer_secret={2}", website_url, consumer_key, consumer_secret);
private static string GetAllProductsInACategoryApiUrl = "xxxxx/wc-api/v3/products?category=379&consumer_key=xxxxx&consumer_secret=xxxxx";
public async Task<Products> GetAllProducts()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(GetAllProductsApiUrl);
HttpContent content = response.Content;
var json = await content.ReadAsStringAsync();
var products = JsonConvert.DeserializeObject<Products>(json);
return products;
}
public async Task<Products> GetAllProductsInACategory()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(GetAllProductsInACategoryApiUrl);
HttpContent content = response.Content;
var json = await content.ReadAsStringAsync();
var products = JsonConvert.DeserializeObject<Products>(json);
return products;
}
}
I managed to build a solution and it's now working!
Here's the code if you come across this problem and need a fix.
async void OrderBtnClicked(object sender, EventArgs e)
{
Console.WriteLine("Starting REST API");
var clientapi = new HttpClient();
clientapi = new Uri("xxxx?consumer_key=xxxx&consumer_secret=xxxx");
Console.WriteLine("Starting REST API");
var clientapi = new HttpClient();
clientapi.BaseAddress = new Uri("xxxx?consumer_key=xxxx&consumer_secret=xxxx");
// json data for adding customer
string jsonData = #"{
""first_name"" : ""John1"",
""last_name"" : ""Doe1"",
""email"" : ""john.doe1#example.com"",
""username"" : ""john.doe1"",
""password"" : ""mypassword"",
""billing"": {
""first_name"": ""John"",
""last_name"": ""Doe"",
""company"": ""john doe company"",
""address_1"": ""969 Market"",
""address_2"": """",
""city"": ""San Francisco"",
""state"": ""CA"",
""postcode"": ""94103"",
""country"": ""US"",
""email"": ""john.doe#example.com"",
""phone"": ""(555) 555-5555""
},
""shipping"": {
""first_name"": ""John"",
""last_name"": ""Doe"",
""company"": """",
""address_1"": ""969 Market"",
""address_2"": """",
""city"": ""San Francisco"",
""state"": ""CA"",
""postcode"": ""94103"",
""country"": ""US""
}
}";
Console.WriteLine("Here's the json string data");
Console.WriteLine(jsonData);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage apiresponse = await clientapi.PostAsync("xxxxx?consumer_key=xxxxx&consumer_secret=xxxx", content);
var apiresult = await apiresponse.Content.ReadAsStringAsync();
Console.WriteLine("Here's the result:");
Console.WriteLine(apiresult);
Console.WriteLine("REST API Post Completed.");
await DisplayAlert("Checkout", "Completed", "ok");
}
Obviously you can setup public variables to store the json data and you're more than welcome to do so, i'm not your dad.

MVC app stops after SendAsync to an API - The same code runs fine in Console App though

I built a simple Console Application to test the connection to an API. Calling the connection method from Console App Main works fine. I get a response with an access-token.
I though that I just could implement the same method/code to an MVC-project and add the method within the HomeController, then call the method from any ActionResult, getting the access-token and then put it in a ViewBag to display it in a view (just for testing). But it doesn't work in the MVC-project.
If I run the debugger, it seems like the app hangs when SendAsync is executed in the method. The console gives this output:
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-04-08T09:26:32.4945663Z","tags":{"ai.internal.sdkVersion":"rddf:2.2.0-738","ai.internal.nodeName":"XXXXXX","ai.cloud.roleInstance":"XXXXXXXX"},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":2,"name":"/token","id":"XXXXXXXXX=","data":"https://api.vasttrafik.se/token","duration":"00:00:00.2810000","resultCode":"200","success":true,"type":"Http","target":"api.vasttrafik.se","properties":{"DeveloperMode":"true"}}}}
The thread 0x1f68 has exited with code 0 (0x0).
What can I do to make the API-call / response work in the MVC-application?
My knowledge in the area is ridiculously low. But I really want to understand whats going on here.
Thanks!
Best
J
MVC project
public class HomeController : Controller
{
public ActionResult Index()
{
string token = PostRequest().Result;
ViewBag.Token = token;
return View();
}
async static Task<string> PostRequest()
{
var client = new HttpClient();
client.BaseAddress = new Uri("https://api.vasttrafik.se");
var request = new HttpRequestMessage(HttpMethod.Post, "/token");
// Key // Secret
string credentials = "xxxxxxxxxoVS5xDrcO6qZsAp0a" + ":" + "xxxxxxxxhn0STj1w4asDwixdMa";
var plainTextBytes = Encoding.UTF8.GetBytes(credentials);
//Key and secret encoded
string encodedCrentedials = Convert.ToBase64String(plainTextBytes);
//Console.WriteLine(encodedCrentedials);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedCrentedials);
var formData = new List<KeyValuePair<string, string>>();
formData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
formData.Add(new KeyValuePair<string, string>("scope", "xxxxxxxxw0oVS5xDrcO6qZsAp0a"));
request.Content = new FormUrlEncodedContent(formData);
// This is where the app hangs....
var response = await client.SendAsync(request);
var mycontentres = await response.Content.ReadAsByteArrayAsync();
var responseBody = Encoding.Default.GetString(mycontentres);
//Console.WriteLine(responseBody);
JavaScriptSerializer seri = new JavaScriptSerializer();
dynamic data = JObject.Parse(responseBody);
string tok = data.access_token;
return tok;
}
}
Don't block on async code:
public async Task<ActionResult> Index()
{
string token = await PostRequest();
ViewBag.Token = token;
return View();
}

Using Postal and Hangfire in Subsite

I have been trying to use Postal on my MVC5 site. When I host my webpage a subsite ie, http://localhost/Subsite I am receiving the error
The virtual path '/' maps to another application, which is not allowed
I have debugged it down to when the ControllerContext is being created the HttpContext isn't getting set correctly. Since I'm running Postal from Hangfire the HttpContext.Current is always null. Postal creates the ContollerContext using the code below.
ControllerContext CreateControllerContext()
{
// A dummy HttpContextBase that is enough to allow the view to be rendered.
var httpContext = new HttpContextWrapper(
new HttpContext(
new HttpRequest("", UrlRoot(), ""),
new HttpResponse(TextWriter.Null)
)
);
var routeData = new RouteData();
routeData.Values["controller"] = EmailViewDirectoryName;
var requestContext = new RequestContext(httpContext, routeData);
var stubController = new StubController();
var controllerContext = new ControllerContext(requestContext, stubController);
stubController.ControllerContext = controllerContext;
return controllerContext;
}
string UrlRoot()
{
var httpContext = HttpContext.Current;
if (httpContext == null)
{
return "http://localhost";
}
return httpContext.Request.Url.GetLeftPart(UriPartial.Authority) +
httpContext.Request.ApplicationPath;
}
How can I specify the UrlRoot so that instead of pulling the default of localhost to pull it based on my subsite?
I followed the directions here http://docs.hangfire.io/en/latest/tutorials/send-email.html to send my email. The method in the tutorial is below
public static void NotifyNewComment(int commentId)
{
// Prepare Postal classes to work outside of ASP.NET request
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));
var emailService = new EmailService(engines);
// Get comment and send a notification.
using (var db = new MailerDbContext())
{
var comment = db.Comments.Find(commentId);
var email = new NewCommentEmail
{
To = "yourmail#example.com",
UserName = comment.UserName,
Comment = comment.Text
};
emailService.Send(email);
}
}
I found the issue was that the FileSystemRazorViewEngine was not being used bty postal. To get the this to work I had to make sure that the FileSystemRazorViewEngine was the first engine in the available. I then removed it because I did not want it to be the default engine. Below is my updated method.
public static void NotifyNewComment(int commentId)
{
// Prepare Postal classes to work outside of ASP.NET request
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var eng = new FileSystemRazorViewEngine(viewsPath));
ViewEngines.Engines.Insert(0, eng);
var emailService = new EmailService(engines);
// Get comment and send a notification.
using (var db = new MailerDbContext())
{
var comment = db.Comments.Find(commentId);
var email = new NewCommentEmail
{
To = "yourmail#example.com",
UserName = comment.UserName,
Comment = comment.Text
};
emailService.Send(email);
ViewEngines.Engines.RemoveAt(0)
}
}
Below is another possible solution that I think is more elegant than above. It also resolves an issue that appears when accessing the MVC application while the background process is being executed.
public static void SendTypedEmailBackground()
{
try
{
var engines = new ViewEngineCollection();
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var eng = new FileSystemRazorViewEngine(viewsPath);
engines.Add(eng);
var email = new WebApplication1.Controllers.EmailController.TypedEmail();
email.Date = DateTime.UtcNow.ToString();
IEmailService service = new Postal.EmailService(engines);
service.Send(email);
}
catch(Exception ex)
{
throw ex;
}
}

Docusign Embedded Signing(MVC website) - tags not showing up and the document is coming as free form signing

I am trying to integrate my website with Docusign via embedded signing. I have been pretty successful - thanks to the documentation and pointers from SO).
My issue is that I have a website and on initial sign up I need the users to e-sign a document before they proceed to shop at my site. So I have set up a docusign embedded signing experience once they login - which will take them seamlessly(without login to docusign server etc) to Docusign - where in the document for signing shows up - this document is coming thru fine - but the tags are not showing up and it is showing as free form signing. There are "FIELDS" to the left of my document and I need to drag and drop these on the form ( I have populated these fields with values).
The real issue is docusign lets me "FINISH" without signing since the document is showing up as free form - Please find my code below - I am using the DocuSign REST API to created an embedded signing for a predefined document template using the /envelopes/{envelopeID}/views/recipient call. I am using RESTSHARP to connect to docusign. Thanks much for your help!
protected const string IntegratorKey = "XX";
protected const string Environment = "https://demo.docusign.net";
protected const string templateRole = "Applicant";
protected const string templateId = "XX";
private static Logger logger = LogManager.GetCurrentClassLogger();
protected const string AccountEmail = "XX#XX.com";
protected const string AccountPassword = "***";
private RestSharp.RestClient client = new RestClient();
private RestSharp.RestRequest request;
bool docuSignCallresult = false;
//
// GET: /Docusign/
public ActionResult launchDocusign(int id)
{
RestSettings.Instance.IntegratorKey = IntegratorKey;
RestSettings.Instance.DocuSignAddress = Environment;
RestSettings.Instance.WebServiceUrl = Environment + "/restapi/v2";
Domain.Account currentAccount = null;
using (var accountRepo = new AccountRepository())
{
currentAccount = accountRepo.AccountGet(id);
}
string RecipientEmail = currentAccount.Email;
string RecipientName = currentAccount.FullName;
Account docuSignAcct = GetDocusignAcctDetails();
Envelope docuSignEnvelope = GetDocusignEnvelopeDetails(docuSignAcct,RecipientEmail,RecipientName);
RecipientView rv = GetRecipientView(RecipientEmail, RecipientName);
client = new RestSharp.RestClient(Environment);
request = new RestRequest("/restapi/{apiVersion}/accounts/{accountId}/envelopes/{envelopeId}/views/recipient");
request.AddUrlSegment("apiVersion", "v2");
request.AddUrlSegment("accountId", docuSignAcct.AccountId);
request.AddUrlSegment("envelopeId", docuSignEnvelope.EnvelopeId);
Mysite.Web.Models.DocuSignData.AuthenticationHeader header = new Mysite.Web.Models.DocuSignData.AuthenticationHeader();
var jsonHeader = JsonConvert.SerializeObject(header);
request.AddHeader("X-DocuSign-Authentication", jsonHeader);
request.Method = Method.POST;
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(rv);
var response = client.Execute(request);
char[] charstoTrim = { '\r', '\n', ' ', '\'' };
var json = response.Content.Trim(charstoTrim);
var jo = JObject.Parse(json);
var recipientUrl = jo["url"].ToString();
return Redirect(recipientUrl);
}
/// <summary>
/// Get the recipient view to launch the docusign(Embedded signing experience)
/// </summary>
/// <param name="RecipientEmail"></param>
/// <param name="RecipientName"></param>
/// <returns></returns>
private RecipientView GetRecipientView(string RecipientEmail, string RecipientName)
{
RecipientView rv = new RecipientView();
rv.authenticationMethod = "email";
rv.returnUrl = Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host + "/MySiteController/MySiteActionMethod";
rv.email = RecipientEmail;
rv.userName = RecipientName;
rv.clientUserId = "1";
return rv;
}
/// <summary>
/// Create an Envelope using the template on docusign
/// </summary>
/// <param name="acct"></param>
/// <param name="recipientEmail"></param>
/// <param name="recipientName"></param>
/// <returns></returns>
private Envelope GetDocusignEnvelopeDetails(Account acct,string recipientEmail,string recipientName)
{
Envelope envelope = new Envelope();
envelope.Login = acct;
envelope.Status = "sent";
envelope.EmailSubject = "Testing";
envelope.TemplateId = templateId;
envelope.TemplateRoles = new TemplateRole[]
{
new TemplateRole()
{
email = recipientEmail,
name = recipientName,
roleName = templateRole,
clientUserId = "1"
}
};
try
{
docuSignCallresult = envelope.Create();
}
catch (Exception ex)
{
logger.Error("Login to docusign failed due to {0} and the exception generated is {2}", envelope.RestError.message, ex.Message);
}
return envelope;
}
/// <summary>
/// Access Docusign Account information
/// </summary>
/// <returns></returns>
private Account GetDocusignAcctDetails()
{
Account docuSignAcct = new Account();
docuSignAcct.Email = AccountEmail;
docuSignAcct.Password = AccountPassword;
try
{
docuSignCallresult = docuSignAcct.Login();
}
catch (Exception ex)
{
logger.Error("Login to docusign failed due to {0} and the exception generated is {2}", docuSignAcct.RestError.message, ex.Message);
}
return docuSignAcct;
}
}
}
As Jeff has mentioned in the comments this is most likely caused by you not matching your recipient correctly to a template (placeholder) role on your template. From your code it looks like you are sending the value Applicant as the template role name - this means that you need to have a role called Applicant in your Template in the Web Console.
For instance, in the below screenshot the role name is Signer1:
To fix either login to the Console and name the role on your template "Applicant" or whatever name it currently has copy that into the code and send that in the API request.

Where do I specify the user I want to follow in twitter hbc

Hey I would like to have the latest tweets from certain users that I will follow to be displayed on a page of my web app. So I followed the tutorial on the git of horsebird client but I don't know where I have to specify the users I want the messages from.
public class TwitterLatestTweets implements Runnable {
private final static String BUNDLE_BASENAME = "configuration.twitter";
private final static String CONSUMER_KEY = ResourceBundle.getBundle(
BUNDLE_BASENAME).getString("consumerKey");
private final static String CONSUMER_SECRET = ResourceBundle.getBundle(
BUNDLE_BASENAME).getString("consumerSecret");
private final static String TOKEN = ResourceBundle.getBundle(
BUNDLE_BASENAME).getString("token");
private final static String SECRET = ResourceBundle.getBundle(
BUNDLE_BASENAME).getString("secret");
private List<String> msgList = new ArrayList<String>();
#Override
public void run() {
/**
* Set up your blocking queues: Be sure to size these properly based on
* expected TPS of your stream
*/
BlockingQueue<String> msgQueue = new LinkedBlockingQueue<String>(100000);
BlockingQueue<Event> eventQueue = new LinkedBlockingQueue<Event>(1000);
/**
* Declare the host you want to connect to, the endpoint, and
* authentication (basic auth or oauth)
*/
Hosts hosebirdHosts = new HttpHosts(Constants.STREAM_HOST);
StatusesFilterEndpoint hosebirdEndpoint = new StatusesFilterEndpoint();
Authentication hosebirdAuth = new OAuth1(CONSUMER_KEY, CONSUMER_SECRET,
TOKEN, SECRET);
ClientBuilder builder = new ClientBuilder().hosts(hosebirdHosts)
.authentication(hosebirdAuth).endpoint(hosebirdEndpoint)
.processor(new StringDelimitedProcessor(msgQueue))
.eventMessageQueue(eventQueue);
Client hosebirdClient = builder.build();
hosebirdClient.connect();
while (!hosebirdClient.isDone()) {
try {
String msg = msgQueue.take();
msgList.add(msg);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
hosebirdClient.stop();
for (String s : msgList) {
System.out.println(s);
}
}
}
}
Is it Constants.STREAM_HOST ? Could you give me an example with the white house twitter (https://twitter.com/whitehouse) ?
You need to add a list of userIds to your endpoint, like this:
hosebirdEndpoint.followings(userIds);
You've got several examples here, in the same github project you've provided in your question. This one uses the same endpoint as in your post.
In here you can find Twitter's documentation on the endpoint, and the full list of the parameters you can use.

Resources