Im trying to convert a C# example thats posting to a API into .vb.
My programming skills are limited so I cant seem to get it to work.
One problem is that I cant use httpclient cause the project is in Framework 3.5 and thats something I cant change. Anyone?
Here is the c# code:
public class TriggerData
{
//if true, the contact will be updated with sent property data (affects performance).
public bool saveProps { get; set; }
public string originalId { get; set; }
public Dictionary<string, string> properties { get; set; }
public TriggerData()
{
properties = new Dictionary<string, string>();
}
}
public class CarmaTriggerClient
{
static void Main(string[] args)
{
//use your settings here
var host = "https://www.adress.com";
var customerId = 0;
var triggerId = 0;
var user = "";
var pass = "";
var data = new TriggerData();
//unique identifier in the list
data.originalId = "th#post.se";
///property keys are emailAddress, mobileNumber, firstName, lastName, city, zip, country, middleName, title, dateOfBirth, sex, or the id of one of your custom properties
data.properties["emailAddress"] = "th#post.se";
data.properties["4321"] = "some data";
//REST resource for trigger
var path = string.Format("/rest/{0}/triggers/{1}/messages", customerId, triggerId);
TriggerAsync(host, path, user, pass, data).Wait();
}
static async Task TriggerAsync(string host, string path, string user, string pass, TriggerData data)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(host);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var credentials = string.Format("{0}:{1}", user, pass);
//http://www.ietf.org/rfc/rfc2617.txt
var authorization = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(credentials));
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authorization);
// HTTP POST
var response = await client.PostAsJsonAsync(path, data);
if (!response.IsSuccessStatusCode)
{
System.Diagnostics.Debug.WriteLine(response.Content);
}
}
}
}
}
Search for csharp vbnet online converter and you will find, for example, http://www.carlosag.net/tools/codetranslator/
I checked your code. It does translate.
Framework versions are the same regarding vbnet and csharp; which is another question.
HTH
Related
I need to connect to an API. All examples that I could find use Tokens which I can send to each transaction I desire.
Accordingly to the supplier documentation, I couldn't find anything related to tokens.
The problem is when I connect, using curl or wp_remote_post() I don't have an 'connected' object to keep doing the transactions that I need.
Bellow is how it is done in C#. I need some directions in what objects I have to use and create the same functionality in php. Thanks
Connection Class:
public class RestService: IDisposable {
private readonly HttpClient _httpClient;
private readonly string _acumaticaBaseUrl;
public RestService(
string acumaticaBaseUrl, string userName, string password, string company, string branch, string locale) {
_acumaticaBaseUrl = acumaticaBaseUrl;
_httpClient = new HttpClient(
new HttpClientHandler {
UseCookies = true,
CookieContainer = new CookieContainer()
}) {
BaseAddress = new Uri(acumaticaBaseUrl + "/entity/Default/6.00.001/"),
DefaultRequestHeaders = {
Accept = {
MediaTypeWithQualityHeaderValue.Parse("text/json")
}
}
};
//Log in to MYOB Advanced
_httpClient.PostAsJsonAsync(
acumaticaBaseUrl + "/entity/auth/login", new {
name = userName,
password = password,
company = company,
branch = branch,
locale = locale
}).Result.EnsureSuccessStatusCode();
}
void IDisposable.Dispose() {
_httpClient.PostAsync(_acumaticaBaseUrl + "/entity/auth/logout", new ByteArrayContent(new byte[0])).Wait();
_httpClient.Dispose();
}
}
////////////////
//Data submission
public string Put(string entityName, string parameters, string entity) {
var res = _httpClient.PutAsync(_acumaticaBaseUrl + "/entity/Default/6.00.001/" + entityName + "?" + parameters, new StringContent(entity, Encoding.UTF8, "application/json")).Result.EnsureSuccessStatusCode();
return res.Content.ReadAsStringAsync().Result;
}
}
I am learning as I create, that being said, I have spent quite a few hours on JUST the login/register pages in the app I am trying to make.
I have finally got to the point where I am able to make the API call to get the response back with the information I need.
I just don't know how to save the token once it comes back.
I am using SQLite for local storage, and I have a "Token" nclass to save it to, but I can't figure out how to actually save it and continue forward.
(I could be completely wrong and it doesn't work at all, but that's all part of learning, I guess.)
anyways, here is my Token class
public class Token
{
[PrimaryKey]
public int Id { get; set; }
public string accessToken { get; set; }
public string errorDescription { get; set; }
public DateTime expireDate { get; set; }
public int expireIn { get; set; }
public Token() { }
}
and here is my APIServices class (some stuff is commented because I am working with my buddy to get everything sorted on the API side)
public class ApiServices
{
public string JsonResult { get; private set; }
public async Task<bool> RegisterUserAsync(string email, string name, /*string first_name, string last_name,*/ string password)
{
var client = new HttpClient();
var model = new RegisterBindingModel
{
Email = email,
//FirstName = first_name,
//LastName = last_name,
Name = name,
Password = password,
};
var json = JsonConvert.SerializeObject(model);
HttpContent httpContent = new StringContent(json);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync("https://myurl/v1/auth/register", httpContent);
if (response.IsSuccessStatusCode)
{
var result = JsonConvert.DeserializeObject(JsonResult);
return true;
}
return false;
}
public async Task<string> LoginAsync(string email, string password)
{
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("email", email),
new KeyValuePair<string, string>("password", password),
new KeyValuePair<string, string>("grant_type", "password")
};
var request = new HttpRequestMessage(HttpMethod.Post, "https://myurl/auth/login" + "Token");
request.Content = new FormUrlEncodedContent(keyValues);
var client = new HttpClient();
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(content);
var accessTokenExpiration = jwtDynamic.Value<DateTime>(".expires");
var accessToken = jwtDynamic.Value<string>("access_token");
//Settings.AccessTokenExpirationDate = accessTokenExpiration;
Debug.WriteLine(accessTokenExpiration);
Debug.WriteLine(content);
return accessToken;
}
}
Lets explain it step by step:
1.Install the sqlite-net-pcl package(Nuget URL). This package will help you to work with database in an easy way.
2.After installing it successfully, You need to add the using statement of SQLite to your class:
using SQLite;
3.In order to make a request to database, you will need to first make a connection to database. to do so, you need to declare a variable for aforementioned goal:
var db = new SQLiteConnection (dbPath);
4.Once you have the database connection object, you are ready to make requests to database. for example to save an object of type Token class, just do this:
var tokenInfo= new Token();
tokenInfo.accessToken="...";//set value to other properties like this
db.Insert(tokenInfo);
These are all you need to do an Insert request to database!
You might want to read more about aforementioned package in these urls:
https://github.com/praeclarum/sqlite-net
https://learn.microsoft.com/en-us/xamarin/android/data-cloud/data-access/using-sqlite-orm
I have a little program which should communicate with "Slack". In an older Version I used "Dictionary<string, string>" and then put them into UrlEncodedContent - which worked fine.
Now I am trying to create a Json-object, using Newtonsoft's Nuget-package and (in my opinion) formatting my object the way they say on their website.
Problem is, when I try to make a simple request, my program just runs to one specific line in the code(var response = await _httpClient.SendAsync(request);) and then it just ends. It doesn't throw an exception or display any kind of message, it simply ends on this line. I went through my code step by step while debugging, that's how I know it ends on exactly this line. And I just don't know why!
Now my code:
First, my object...
namespace BPS.Slack
{
public class JsonObject
{
//generally needed parameters
[JsonProperty("ok")]
public bool ok { get; set; }
[JsonProperty("error")]
public string error { get; set; }
[JsonProperty("channel")]
public string channel { get; set; }
[JsonProperty("token")]
private string token = "xoxp-MyToken";
[JsonProperty("as_user")]
public bool as_user = false;
[JsonProperty("username")]
public string username { get;set; }
//--------------------------------
//only needed for textmessages
[JsonProperty("text")]
public string text { get; set; }
//--------------------------------
//for posting messages with data attached
[JsonProperty("initial_comment")]
public string initial_comment { get; set; }
[JsonProperty("file")]
public string file { get; set; }
[JsonProperty("channels")]
public string channels { get; set; }
//--------------------------------
//for getting the latest message from a channel
[JsonProperty("count")]
public string count = "1";
[JsonProperty("unreads")]
public bool unreads = true;
}
}
now the client:
namespace BPS.Slack
{
public class BpsHttpClient
{
private readonly HttpClient _httpClient = new HttpClient { };
public Uri UriMethod { get; set; }
public BpsHttpClient(string webhookUrl)
{
UriMethod = new Uri(webhookUrl);
}
public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UriMethod);
request.Content = requestContent;
var response = await _httpClient.SendAsync(request);
return response;
}
}
}
and the main
namespace TestArea
{
class MainArea
{
public static void Main( string[] args)
{
try
{
Task.WhenAll(SendMessage());
}
catch(Exception ass)
{
Console.WriteLine(ass);
Console.ReadKey();
}
}
private static async Task SendMessage()
{
var client = new BpsHttpClient("https://slack.com/api/im.history");
JsonObject JO = new JsonObject();
JO.channel = "DCW21NBHD";
var Json = JsonConvert.SerializeObject(JO);
var StringJson = new StringContent(Json, Encoding.UTF8);
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(StringJson);
var Response = await client.UploadFileAsync(content);
string AnswerContent = await Response.Content.ReadAsStringAsync();
Console.WriteLine(AnswerContent);
Console.ReadKey();
}
}
}
I had the same problem in my older version, BUT only as I wanted to DEserialize an answer I got from Slack. It had to do with my object I tried do deserialize the answer into. But this time I can not figure out what's wrong. But, as I said, I do not have any experience with using serialized objects as Json-property to send requests... anyone has an idea what is wrong with my code?
EDIT: This problem is kinda solved. But there is a follow up problem.
Okay, I found out that the reason for the abprubt termination was the
Task.WhenAll(SendMessage());
it should be
Task.WaitAll(SendMessage()); Why??? Somebody said I should use WhenAll, but obviously it doesn't work properly in this case...
Now I get a response from Slack, but now a different problem has arisen. When I use this method:
public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UriMethod);
request.Content = requestContent;
var response = await _httpClient.SendAsync(request);
return response;
}
I allways get the answer:
{"ok":false,"error":"invalid_form_data"}
so I tried to explicitly tell it the 'mediaType', I tried "application/json" and others, but with all of them I get the same error. Here is the full method that calls the upper mehtod:
private static async Task SendMessage()
{
var client = new BpsHttpClient("https://slack.com/api/chat.postMessage");
JsonObject JO = new JsonObject();
JO.channel = "DCW21NBHD";
JO.text = "This is so much fun :D !";
var Json = JsonConvert.SerializeObject(JO, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringJson = new StringContent(Json, Encoding.UTF8, "application/json");
var requestContent = new MultipartFormDataContent();
requestContent.Add(StringJson);
var Response = await client.UploadFileAsync(requestContent);
string AnswerContent = await Response.Content.ReadAsStringAsync();
}
When I use this method:
public async Task<HttpResponseMessage> SendMessageAsync(FormUrlEncodedContent content)
{
var response = await _httpClient.PostAsync(UriMethod, content);
return response;
}
so bascially I am passing "FormUrlEncodedContent" instead of "MultipartFormDataContent" in this, and then I get the response I want and can work wiht it. BUT this i of little use to me since I have to use "MultipartFormDataContent" to be able to send files with my requests.
Anyone have an idea what is failing here? Why does it not like the one content-type but the other one? I'd be gratefull for tipps and ideas!
You are serializing your object to Json and then adding it to a Multipart body, that's quite strange. Unless you're uploading binary data (eg Files), there is no need to use MultipartFormDataContent.
You are can directly post your JsonObject serialized as JSON:
public async Task<HttpResponseMessage> PostJsonAsync(StringContent content)
{
var response = await client.PostAsync(url, content);
return response;
}
var client = new BpsHttpClient("https://slack.com/api/im.history");
JsonObject JO = new JsonObject();
JO.channel = "DCW21NBHD";
var Json = JsonConvert.SerializeObject(JO);
var StringJson = new StringContent(Json, Encoding.UTF8);
var Response = await client.PostJsonAsync(content);
Also this is should be POST on the UploadFileAsync function.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UriMethod);
so I figured out that in the Main() the problem was this:
Task.WhenAll(SendMessage());
I should instead use:
Task.WaitAll(SendMessage());
Anyone who has more knowledge on this, please elaborate why!
I am trying to send chars like : / . in asp.net mvc 5 to an API controller endpoint, but it fails as soon as I try something containing certain chars. For example, I can't send message:hi, I have to change it to message_hi to get it working.
I am trying to send an email using Exchange and the body (containing an URL and other info) won't go through.
My API Controller:
[Route("send/{adress}/{subject}/{body}")]
public void SendEmail(string adress, string subject, string body)
{
Office365MailSender ms = new Office365MailSender();
EmailDto email = new EmailDto(adress, subject, body);
ms.Send(email);
}
Calling the above endpoint from my application:
public static async Task<string> SendMail(IPhoneCall phoneCall)
{
var email = new EmailEntity(phoneCall);
using (var client = new HttpClient())
{
var uri = new Uri("http://url/email/send/" + email.Recipient + "/" + email.Title + "/" + email.body);
var msg = await client.GetAsync(uri);
}
return "Email Sent";
}
An example of a value of the uri variable would be:
http://url/email/send/myemail#outlook.com/Hello There/Hi,\nThis is a url you can use for stuff: https://thisisit.com. \n Thanks bye.
I've tried HttpUtility.UrlEncode on the body before I send it, but that does nothing. Does anyone know how to send strings containing these type of chars?
I would recommend you using the POST verb in order to send the body of the message. So you could start by writing a view model:
public class MailMessageViewModel
{
public string Address { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
that your Web API action will take as parameter:
[Route("send")]
[HttpPost]
public IHttpActionResult SendEmail(MyViewModel model)
{
Office365MailSender ms = new Office365MailSender();
EmailDto email = new EmailDto(model.Address, model.Subject, model.Body);
ms.Send(email);
return this.Ok();
}
and then you could invoke like this:
var email = new EmailEntity(phoneCall);
using (var client = new HttpClient())
{
var uri = new Uri("http://url/email/send");
var content = new StringContent(
JsonConvert.SerializeObject(new
{
Address = email.Recipient,
Subject = email.Title,
Body = email.body,
}),
UnicodeEncoding.UTF8,
"application/json");
var msg = await client.PostAsync(uri, content);
}
Okay I have limited understanding of working with API's
Im trying to get to grips with Adobe Sign API and hit a dead end, on there test page i have enterd this and it works
But i have no idea on how then do that in C#
I have tried the following, but know its missing the OAuth stuff and I'm just not sure what to try next.
by the way foo.GetAgreementCreationInfo() just gets the string that is in the screen shot, I just moved it out cus it was big and ugly
var foo = new Models();
var client = new RestClient("https://api.na1.echosign.com/api/rest/v5");
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest("agreements/{AgreementCreationInfo}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("AgreementCreationInfo", foo.GetAgreementCreationInfo()); // replaces matching token in request.Resource
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
You are misinterpreting the API documentation. The Access-Token parameter needed in your API is clearly an HTTP header, while the AgreementCreationInfo is simply the request body in JSON format. There is no URI segment, so rewrite your code as follows:
var foo = new Models();
//populate foo
var client = new RestClient("https://api.na1.echosign.com/api/rest/v5");
var request = new RestRequest("agreements", Method.POST);
request.AddHeader("Access-Token", "access_token_here!");
// request.AddHeader("x-api-user", "userid:jondoe"); //if you want to add the second header
request.AddParameter("application/json", foo.GetAgreementCreationInfo(), ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var content = response.Content;
Please also be aware that in RESTSharp you do not need to manually serialize your body into JSON at all. If you create a strongly typed object (or just an anonymous object could be enough) that has the same structure of your final JSON, RESTSharp will serialize it for you.
For a better approach I strongly suggest you to replace this line:
request.AddParameter("application/json", foo.GetAgreementCreationInfo(), ParameterType.RequestBody);
With those:
request.RequestFormat = DataFormat.Json;
request.AddBody(foo);
Assuming your foo object is of type Models and has the following structure along with its properties:
public class Models
{
public DocumentCreationInfo documentCreationInfo { get; set; }
}
public class DocumentCreationInfo
{
public List<FileInfo> fileInfos { get; set; }
public string name { get; set; }
public List<RecipientSetInfo> recipientSetInfos { get; set; }
public string signatureType { get; set; }
public string signatureFlow { get; set; }
}
public class FileInfo
{
public string transientDocumentId { get; set; }
}
public class RecipientSetInfo
{
public List<RecipientSetMemberInfo> recipientSetMemberInfos { get; set; }
public string recipientSetRole { get; set; }
}
public class RecipientSetMemberInfo
{
public string email { get; set; }
public string fax { get; set; }
}
Link to AdobeSign Repository:
ADOBE SIGN SDK C# SHARP API Ver. 6
Adobe Sign API integrators - this is kind of hidden away in AdobeSigns GIT repositories. The link to all the generated SWAGGER classes (models/methods) for C# and REST client integrated C# project in a GIT project you can compile and use right inside your project as a project reference or compiled DLL. This project has been updated to use version 6 of the API. This was a huge time saver for me. I have provided a quick example below on how to use it. I hope this helps others save time as well.
Note you might have to switch out BasePath in the configuration.cs so you can retrieve the initial Adobe URI "BaseURI" call if you get 404 error.
Change BasePath = "http://localhost/api/rest/v6";
To:
BasePath = "https://api.echosign.com/api/rest/v6";
//include namespaces:
using IO.Swagger.Api;
using IO.Swagger.model.agreements;
using IO.Swagger.model.baseUris;
using IO.Swagger.model.transientDocuments;
using System.IO;
Then this quick minimal demonstrates BaseUri, Upload PDF a.k.a. Transient Document, then Create Agreement (Example 1 Basic Signer Minimal Options)
string transientDocumentId = "";
string adobesignDocKey = "";
string baseURI = "";
var apiInstanceBase = new BaseUrisApi();
var authorization = "Bearer " + apiKey; //Example as Integration Key, see adobesign docs For OAuth.
try
{
//___________________GET BASEURI ADOBE SIGN_________________________
BaseUriInfo resultBase = apiInstanceBase.GetBaseUris(authorization);
baseURI = resultBase.ApiAccessPoint; //return base uri
//___________________UPLOAD YOUR PDF THEN REF ADOBE SIGN_________________________
var apiInstanceFileUpload = new TransientDocumentsApi(baseURI + "api/rest/v6/");
TransientDocumentResponse resultTransientID = apiInstanceFileUpload.CreateTransientDocument(authorization, File.OpenRead([ENTER YOUR LOCAL FILE PATH]), null, null, _filename, null);
if (!String.IsNullOrEmpty(resultTransientID.TransientDocumentId))
{
transientDocumentId = resultTransientID.TransientDocumentId; //returns the transient doc id to use below as reference
}
var apiInstance = new AgreementsApi(baseURI + "api/rest/v6/");
//___________________CREATE ADOBE SIGN_________________________
var agreementId = ""; // string | The agreement identifier, as returned by the agreement creation API or retrieved from the API to fetch agreements.
var agreementInfo = new AgreementCreationInfo();
//transientDocument, libraryDocument or a URL (note the full namespace/conflicts with System.IO
List<IO.Swagger.model.agreements.FileInfo> useFile = new List<IO.Swagger.model.agreements.FileInfo>();
useFile.Add(new IO.Swagger.model.agreements.FileInfo { TransientDocumentId = transientDocumentId });
agreementInfo.FileInfos = useFile;
//Add Email To Send To:
List<ParticipantSetMemberInfo> partSigners = new List<ParticipantSetMemberInfo>();
partSigners.Add( new ParticipantSetMemberInfo { Email = "[ENTER VALID EMAIL SIGNER]", SecurityOption=null });
//Add Signer To Participant
List<ParticipantSetInfo> partSetInfo = new List<ParticipantSetInfo>();
partSetInfo.Add(new ParticipantSetInfo { Name = "signer1", MemberInfos = partSigners, Role = ParticipantSetInfo.RoleEnum.SIGNER, Order=1, Label="" });
agreementInfo.ParticipantSetsInfo = partSetInfo;
agreementInfo.SignatureType = AgreementCreationInfo.SignatureTypeEnum.ESIGN;
agreementInfo.Name = "Example Esign For API";
agreementInfo.Message = "Some sample Message To Use Signing";
agreementInfo.State = AgreementCreationInfo.StateEnum.INPROCESS;
AgreementCreationResponse result = apiInstance.CreateAgreement(authorization, agreementInfo, null, null);
adobesignDocKey = result.Id; //returns the document Id to reference later to get status/info on GET
}
catch (Exception ex)
{
//Capture and write errors to debug or display to user
System.Diagnostics.Debug.Write(ex.Message.ToString());
}