I am a new to ASP.NET MVC. I want to call an API on a payment gateway. The API only tries to resolve Users Identity. I have written the CURL in C# but I seem to be stuck on how to proceed to get the API called and also return a JSON using AJAX.
Below is the Curl converted to C#.
[HttpPost]
public JsonResult ResolveBVN()
{
//string str = BVN;
var secretKey = "secretkey";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {secretKey}");
var response = client.PostAsync("https://api.paystack.co/bvn/match", new StringContent("{ bvn: \"22146592120\",\n account_number: \"0689688306\",\n bank_code: \"044\",\n first_name: \"uthman\",\n last_name: \"jinadu\"\n }")).Result;
PaystackAPI paystackAPI = new PaystackAPI()
{
statuscode = response.IsSuccessStatusCode,
message = response.StatusCode
};
return Json(paystackAPI);
}
}
The AJAX call is below:
$("#btnGetBVN").click(function () {
if ($('#BVN').val() == '' || $('#BVN').val() == undefined) {
alert('Please Enter Customer BVN');
return false;
}
$('.spinner').css('display', 'block'); //if clicked ok spinner shown
$.ajax({
type: "POST",
url: "#Url.Action("ResolveBVN", "Transactions")",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response.status);
$('#Firstname').val(response.data.first_name);
$('#Surname').val(response.data.last_name);
// $('#Phone_Number').val(response.data.mobile);
$('.spinner').css('display', 'none');
},
failure: function (response) {
alert('BVN Does Not Exist Or Error Processing Request');
$('.spinner').css('display', 'none');
},
error: function (response) {
alert('BVN Does Not Exist Or Error Processing Request');
$('.spinner').css('display', 'none');
}
});
});
The alert message response is UNDEFINED
EDIT
I have added the Class to return the JSon to the AJAX call. I can only use the statuscode of the response.
How can I access the other part of the response? The response sample is below:
{
"status": true,
"message": "BVN lookup successful",
"data": {
"bvn": "000000000000",
"is_blacklisted": false,
"account_number": true,
"first_name": true,
"last_name": true
},
"meta": {
"calls_this_month": 1,
"free_calls_left": 9
}
}
How do I access the other parts in the class like account_Number, message and the likes.
Please use below :-
var secretKey = string.Empty;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {secretKey}");
var response = httpClient.PostAsync("https://api.paystack.co/bvn/match", new StringContent("{ bvn: \"12345678912\",\n account_number: \"0000000000\",\n bank_code: \"087\",\n first_name: \"bojack\",\n last_name: \"horseman\"\n }")).Result;
}
Please make sure to set the correct secret key.
you should be writing this code in the the method which is being called by the ajax.Response variable will contain the response returned by the paystack api
Related
I'm currently using JQuery Ajax to send some data to AccountController
Ajax
$.ajax({
type: "POST",
url: '/Account/Register',
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
console.log(response)
},
error: function (response) {
console.log(response)
}
});
Account Contrller
[HttpPost]
public async Task<JsonResult> Register(string data)
{
JObject json = JObject.Parse(data);
var user = new ApplicationUser { UserName = json["login"], Email = json["login"] };
var result = await UserManager.CreateAsync(user, json["password"]);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return Json(new { success = true, html = "", message = "111" }, JsonRequestBehavior.AllowGet);
}
return Json(new { success = false, html = "", message = "222" }); ;
}
And I get the following response object in ajax error section:
I think ajax request was sent to the back end. But I tried to set break points on Register function, the program doesn't trigger any break point. And I can't understand where the response object came from.
Does anyone know whats happening here?
------------------ Edit -----------------------------------------------------------
Great thanks to #freedomn-m, I found something interesting.
Here the response header gives 401 status, so I guess ajax fails because I miss some security token here. But does anyone know what token I missed?
I am trying to load a website in an I-frame. this is the first time I have to call the post method and pass a header and body.
This is my attempt with ajax.
$.ajax({
url: 'example.com',
type: 'post',
data: {
FirstName: "john doe"
},
headers: {
Token: "token"
},
dataType: 'json',
success: function (data) {
//console.info(data);
$("#output_iframe_id").attr('src', "/")
$("#output_iframe_id").contents().find('html').html(data);
}
});
I get a CORS error.
Access to XMLHttpRequest at 'https://localhost:44349/archive/statements' from origin 'https://localhost:44346' has been blocked by CORS policy: Request header field token is not allowed by Access-Control-Allow-Headers in preflight response.
Update:
I used HttpClient and was able to pass the needed header and body. the site loads in the i-frame. However, the site does not behave correctly. I loose session data on additional calls to the server.
string jsonString = GetJsonString(req);
string url = example.com;
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Token", "token");
var clientRequest = new HttpRequestMessage()
{
Method = HttpMethod.Post,
Content = new StringContent(jsonString, Encoding.UTF8, "application/json")
};
var Res = await client.PostAsync(url, clientRequest.Content);
ViewBag.Statements = await Res.Content.ReadAsStringAsync();
}
Usage:
<div>
<iframe srcdoc="#ViewBag.Statements"></iframe>
</div>
I was finally able to get the ajax call working. I ended up adding a test page within the application itself and below is the working ajax call.
$.ajax({
url: 'example.com',
type: 'post',
data: {
FirstName: "john doe"
},
headers: {
Token: "token"
},
dataType: 'html',
success: function (data) {
$("#output_iframe_id").contents().find('html').html(data);
}
});
AS for the HTTPClient call. I found a few articles stating that HTTPClient doesn't return all HTML so I ended up focusing on the ajax call.
I created an web application with submit button. When the user clicks on this button, there will be Ajax call invoked to communicate the BOT. I used following code for Ajax function
<script>
$(document).ready(function () {
$("#btnSend").click(function (e) {
$.ajax({
type: "POST",
url: "GroupChat.aspx/GetData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("success!");
},
error: function (response) {
alert(response.d);
}
});
return false;
});
});
</script>
And I used following code to communicate BOT from the web method
[WebMethod]
public static async Task GetData()
{
Task<TokenResponse> response = GetTokenAsync();
response.Wait();
string token = response.Result.access_token;
List<BOTConstants> lstConstants = new List<BOTConstants>();
lstConstants.Add(new BOTConstants
{
text = "test message",
channelId = "webApp",
serviceUrl = "https://smba.trafficmanager.net/in/",
textFormat = "plain",
type = "message"
});
string json = (new JavaScriptSerializer()).Serialize(lstConstants);
var data = new StringContent(json, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
//client.BaseAddress = new Uri("https://mybot.azurewebsites.net");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var result = await client.PostAsync("https://mybot.azurewebsites.net/api/messages", data).ConfigureAwait(false);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine(resultContent);
}
}
But, var result = await client.PostAsync("https://mybot.azurewebsites.net/api/messages", data).ConfigureAwait(false); is always returns Bad request.
Can anybody help me on this to resolve this issue, Please correct me if any mistakes in the above code.
You should use the direct line API instead of posting directly to your "api/messages" endpoint.
Based on Microsoft documentation, below should be the steps. For the same end-user, you should cache the token and conversation id, so your conversation can continue properly in a multi-turn dialog.
Start a conversation.
POST https://directline.botframework.com/v3/directline/conversations
Authorization: Bearer SECRET
//Response
{
"conversationId": "abc123",
"token": "RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn",
"expires_in": 1800,
"streamUrl": "https://directline.botframework.com/v3/directline/conversations/abc123/stream?t=RCurR_XV9ZA.cwA..."
}
After you get the conversation id e.g. "abc123", you can start posting your message to this conversation.
POST https://directline.botframework.com/v3/directline/conversations/abc123/activities
Authorization: Bearer RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0
Content-Type: application/json
[other headers]
//Request body
{
"locale": "en-EN",
"type": "message",
"from": {
"id": "user1"
},
"text": "hello"
}
I'm developing a web site associated to a SQL database and Azure web app. The app support authentication. For now, I'm able to login a user using Owin OAuthAuthorizationServerProvider class.
Here is the code I'm using to POST login data from my Angularjs file :
fac.login = function (user) {
var obj = {
'username': user.username, 'password': user.password,
'grant_type': 'password'
};
Object.toparams = function ObjectsToParams(obj)
{
var p = [];
for (var key in obj)
{
p.push(key + '=' + encodeURIComponent(obj[key]));
}
return p.join('&');
}
var defer = $q.defer();
$http({
method: 'post',
url: serviceBasePath + "/token",
data: Object.toparams(obj),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function (response) {
userService.SetCurrentUser(response.data);
defer.resolve(response.data);
}, function (error) {
defer.reject(error.data);
})
return defer.promise;
}
And I deal with the data and identity by overriding : Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context).
This works perfectly. I'm now trying to create a "Sign In" page based on the same structure.
I think I know how to post the data with AngularJS like this :
fac.suscribe = function (newUser) {
var obj = {
'username': newUser.username, 'surname': newUser.surname, 'firstname': newUser.firstname,
'password1': newUser.password1, 'password2': newUser.password2, 'email': newUser.email, 'guid': newUser.guid
};
Object.toparams = function ObjectsToParams(obj) {
var p = [];
for (var key in obj) {
p.push(key + '=' + encodeURIComponent(obj[key]));
}
return p.join('&');
}
var defer = $q.defer();
$http({
method: 'post',
url: serviceBasePath + "/register",
data: Object.toparams(obj),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function (response){
userService.SetCurrentUser(response.data);
defer.resolve(response.data);
}, function (error) {
defer.reject(error.data);
})
return defer.promise;
}
But I wonder how I can get the data to generate the post answer. Any idea on C#, preferably ?
First, You should have Model same with same property name on the server side. So that the property that you are sending in the object from angularjs will get binded to the Model Properties. Instead of having headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, change it to headers: { 'Content-Type': 'application/json' } for the Web API.
For your reference i am sharing this link
CRUD WITH ANGULARJS and ASP.NET WEB API
I have an ajax POST call to my wcf service. It was working fine when I was returning a string (json payload) but as soon as I switched to returning an 'HttpResponseMessage' object it started giving me the ERR_CONNECTION_RESET. Same payload returned with the exception of now I want to return proper responses like 200 and 404's.
Here is the ajax call:
function Login (cred) {
$.ajax({
type: "POST",
url: ServerConfig.Server + ServerConfig.Service + "/login/",
// The key needs to match your method's input parameter (case-sensitive).
data: JSON.stringify(cred),
contentType: "application/json",
dataType: "json",
crossDomain: true,
beforeSend: function(xhr) {
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
},
error: loginFailed,
success: loginSuccess
});
}
and here is the my wcf method:
public HttpResponseMessage Login(string username, string password)
{
repository = new DbRepository();
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
var res = string.Empty;
var user = repository.Login(username, password);
if (null != user)
{
res = JsonConvert.SerializeObject(user);
response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(res)
};
}
else
{
return response;
}
return response;
}
I have confirmed that by switching back to string works as expected. Can someone shed some light on what might be going on?
Thanks.
EDIT: Here is what my 'cred' object looks like and how it was created:
$('.signin').on("click", function () {
var user = $('.username').val();
var pass = $('.password').val();
var cred = { "username": user, "password": pass };
Login(cred);
});
The JSON.stringify(cred) looks like this:
{"username":"Test1234","password":"TestPassword!"}