Calling script from Blazor with parameters - javascript

I've been given a script function and would like to partially translate it to C# in a Blazor app
<script>
function pay() {
var token = document.getElementById('token').value;
var card = document.getElementById('card').value;
var exp = document.getElementById('exp').value;
var cvv = document.getElementById('cvv').value;
var paymentData = {
ssl_txn_auth_token: token,
ssl_card_number: card,
ssl_exp_date: exp ,
ssl_cvv2cvc2: cvv
};
ConvergeEmbeddedPayment.pay(paymentData);
return false;
}
</script>
I want to call the script (that is inside the script above)
ConvergeEmbeddedPayment.pay(paymentData);
Directly from c# . Like so
await JsRuntime.InvokeVoidAsync("ConvergeEmbeddedPayment.pay", paymentData);
There is some good information here:
https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-3.1
But it stops short of helping me.
What kind of variable should I pass in the paymentData parameter? And how should I pass it?
I've tried var , object and string and also tried JsonSerializer.Serialize( ); but no luck
Based on suggestion from #BurningKarl I tried Dictionary and object[] but
I get an error saying the content is missing or "Expected BEGIN_OBJECT but was STRING "

Looks like you have to create your own c# class that mimics the payment data object in your Javascript.
Something like this
public class PaymentData
{
public string ssl_txn_auth_token {get; set;}
public string ssl_card_number{get; set;}
public string ssl_exp_date{get; set;}
public string ssl_cvv2cvc2{get; set;}
}
Then you have to create an instance of this class and pass it to InvokeVoidAsync as an argument.
var data = new PaymentData ()
{
ssl_txn_auth_token = "authtokenvalue",// you have to get it from control
ssl_card_number = "card number",
ssl_exp_date: "date", // probably it should be daytime or similar
ssl_cvv2cvc2 = "111"
}
await JsRuntime.InvokeVoidAsync("ConvergeEmbeddedPayment.pay", data);

Related

How to get the value of a specific HTML element in a given HTML document or webpage (by URL)?

I want to pass the url of a webpage containing a <span id="spanID"> value </span> tag to a method like setTextBoxText(string url, string id) which is written in a wpf application codeBehind (MainWindow.xaml.cs) and set the Text of a specific TextBox Control to the span value, without loading the webpage. (for Ex. tracking price of a product in amazon)
I prefer to execute JavaScript code to get value of html elements and set the content of wpf controls to the result of the js code (function)
something like this:
public partial class MainWindow : Window
{
string url = "https://websiteaddress.com/rest";
setTextBoxText(url, "spanID");
static void setTextBoxText(string url, string id)
{
// code to get document by given url
txtPrice.Text = getHtmlElementValue(id);
}
string getHtmlElementValue(string id)
{
// what code should be written here?
// any combination of js and c#?
// var result = document.getElementById(id).textContent;
// return result;
}
}
You can use the HttpClient to load the HTML content of an URL and then process the DOM object in a JavaScript like syntax by wrapping the response into a mshtml.HTMLDocument - requires reference to Microsoft.mshtml.dll:
private mshtml.HTMLDocument HtmlDocument { get; set; }
private async Task SetTextBoxTextAsync(string url, string id)
{
await UpdateHtmlDocumentAsync(url);
var value = GetHtmlElementValueById(id);
txtPrice.Text = value;
}
public async Task UpdateHtmlDocumentAsync(string url)
{
using (HttpClient httpClient = new HttpClient())
{
byte[] response = await httpClient.GetByteArrayAsync(url);
string httpResponseText = Encoding.GetEncoding("utf-8").GetString(response, 0, response.Length - 1);
string htmlContent = WebUtility.HtmlDecode(httpResponseText);
this.HtmlDocument = new HTMLDocument();
(this.HtmlDocument as IHTMLDocument2).write(htmlContent);
}
}
public string GetHtmlElementValueById(string elementId)
=> this.HtmlDocument.getElementById(elementId).innerText;

How to use JSON result in selenium webdriver

Im a beginner for automation testing.Here I want to get the data's from json to be used by selenium webdriver.I wrote one java class and hard coded something to get a result as a try.and getting an answer in console panel like
{
"name": "john",
"location": "jihu",
"job": [
{
"manager": [
{
"collegues": [
"ram",
"ranma",
],
}
}
}
(not exactly this).
Now i want to use this for one specific application using selenium webdriver. How can i move on with this.help me in detail.Thanks in advance.
From Selenium and Backend Comparison testing point of view i am answering the same .you need to parse json response using some Libraries like GSON , jackson etc into Java Pojo objects and then apply asserts on the fields you want to compare with json and UI. I guess you need to go through below topics first
1) Serialization -Deserialization API response
2) GSON or Jackson parsers
3) RestAssured ( Provides framework for API testing )
4) JAVA pojo classed and usage of them . you might need them to save your response in form of some Response class and compare objects .
You can use these online converters for converting a json object into Java Pojo Classes :
http://json2java.azurewebsites.net/ (I usually use this)
https://codebeautify.org/json-to-java-converter
and then place them in a package or in the same class as you wish :
You can better understand it by below example :
package com.demo.core;
import com.google.gson.Gson;
import io.restassured.RestAssured;
import io.restassured.response.Response;
public class Demo {
public static void main(String r[]) {
Response response1 = RestAssured.given().get("http://dummy.restapiexample.com/api/v1/employee/1"); // use your method to get the API response (I have used RestAssured here)
String json = response1.asString(); // you can use your json response here and convert it into a String
Gson gson = new Gson();
Employee emp = gson.fromJson(json, Employee.class); // The response is now captured in this Employee class
System.out.println(emp.getEmployeeAge());
System.out.println(emp.getEmployeeName());
System.out.println(emp.getEmployeeSalary());
}
}
class Employee {
private String id;
private String employee_name;
private String employee_salary;
private String employee_age;
private String profile_image;
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getEmployeeName() {
return this.employee_name;
}
public void setEmployeeName(String employee_name) {
this.employee_name = employee_name;
}
public String getEmployeeSalary() {
return this.employee_salary;
}
public void setEmployeeSalary(String employee_salary) {
this.employee_salary = employee_salary;
}
public String getEmployeeAge() {
return this.employee_age;
}
public void setEmployeeAge(String employee_age) {
this.employee_age = employee_age;
}
public String getProfileImage() {
return this.profile_image;
}
public void setProfileImage(String profile_image) {
this.profile_image = profile_image;
}
}
You can easily assert the values after the response is captured in Java classes using their getter methods like I have used in the code to get field values present in Employee class.
Please do let me know if you still got an issue.
If your result contains many fields than better to shift all converted java classes into a separate package for a clear code.

How to create a javascript model to send to an MVC controller?

I have a website served from a proprietary C++ server.
There is a standard javascript ajax function in the code but I don't want to start editing it.
The actual sending bit is as follows:
this.send=function(myawesomemodel)
{
/*Code redacted for brevity*/
obj.req.open('POST',myawesomeurl,true);
obj.req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
obj.req.send(JSON.stringify(myawesomemodel));
}
It used to send key value pairs as a query string but now it needs to send json.
I can send this function a controller/action address (myawesomeurl) for the appropriate end point and I can send it an awesome object which will be accepted by the action as a basic C# Model (myawesomemodel):
public ActionResult myawesomeaction(MyAwesomeClass myawesomeclass)
{
}
For the .Net model:
public class MyAwesomeClass
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
How do I build a javascript object the controller will recognise please?
Here's my latest failure:
function MyAwesomeModel()
{
this.A=1;
this.B=2;
this.C='Three';
}
Then:
var anawesomemodel=new MyAwesomeModel();
myawesomeajaxmodel.send(anawesomemodel);
I cannot construct the correct object in plain javascript so the mvc action registers it, what's the correct method please?
var myawesomemodel = {
A : 1,
B : 2,
C : 'Three'
}
For anyone else with the same problem who finds this page, Stephen Muecke nailed it
Change the ajax object to:
this.send=function(myawesomemodel)
{
/*Code redacted for brevity*/
obj.req.open('POST',myawesomeurl,true);
obj.req.setRequestHeader('Content-type','application/json;charset=utf-8');
obj.req.send(JSON.stringify(myawesomemodel));
}

Web API post array of objects?

I have an object as follows which is then stored in an array of them.
I would like to send the array of them to Web API, usually you would use JSON.stringify on an object, but would this work also being in an array?
I then need to work out what type of object they would be received as the other end as I need to iterate through them. I was hoping to use a typeof class.
var fieldarray = [];
$("div[class*=container_]").each(function (index) {
var firstElement = $(this).first();
var object = $(this).find('.object');
fielddata = {
id: firstElement.attr('class').match(/\d+/)[0],
attributes: [{
'label_text': firstElement.text(),
'label_width': firstElement.width(),
'label_height': firstElement.height(),
'label_color': firstElement.css('color'),
'Field_Width': object.width(),
'Field_Height': object.height,
'Field_Type': object.attr('Field_Type'),
'PositionX': firstElement.offset().left,
'PositionY': firstElement.offset().top,
'Field': firstElement.attr('class').match(/\d+/)[0],
'Label_Font': firstElement.css('font-family')
}]
}
array.push(fielddata);
});
Can I send this using JSON.stringify, and if so, what type would I receive this as in the Web API server side?
I usually use a public class type but the above code has an object inside an object - that is my problem.
I have sorted this now, basically I used:
[HttpPut]
public int Put(int id, [FromBody] FormData HTMLFORM)
{
....
}
and stored it in my type class as a string:
public class FormData
{
public int id { get; set; }
public string HTML { get; set; }
public string fieldData { get; set; }
}
I then used
IList<AttributeData> findingList = JsonConvert.DeserializeObject<IList<AttributeData>>(HTMLFORM.fieldData);
And it was stored in the list which I can iterate through using my type class of AttributeData!
Thanks

Web API post parameter

I currently have an issue with a webapi call. I want to download and open a logfile with my ApiController.
I use a javascript function to post a filename to my controller.
Here is a helper function to post the parameter (answer from dystroy):
How to replace window.open(...) with a POST
Now when I use a simple string as parameter in my controller I can’t get the parameter, it is always null.
public HttpResponseMessage PostDownloadLogFile([FromBody]string psFileName)
{
//psFileName is always null
But if I use HttpReqeustMessage as parameter and read the form data from my request it is no problem and it works.
public HttpResponseMessage PostDownloadLogFile(HttpRequestMessage poRequest)
{
var loFormData = poRequest.Content.ReadAsFormDataAsync().Result;
string psFileName = loFormData["psFileName"]; //psFileName is set correct
Is there a solution to get the parameter with a simple parameter in my controller?
Update
This is my javascript helper function:
var loOpenWindow = function (psMethode, psUrl, poData, psTarget) {
var loForm = document.createElement("form");
loForm.action = psUrl;
loForm.method = psMethode;
loForm.target = psTarget || "_self";
if (poData) {
for (var lsKey in poData) {
var loInput = document.createElement("textarea");
loInput.name = lsKey;
loInput.value = typeof poData[lsKey] === "object" ? JSON.stringify(poData[lsKey]) : poData[lsKey];
loForm.appendChild(loInput);
}
}
loForm.style.display = "none";
document.body.appendChild(loForm);
loForm.submit();
};
Call it:
helper.openWindow("POST", apiRoutes.URLS.ApiPostDownloadLogFile, { "psFilename": $scope.data.showLogEntry.FullName });
There should be no problem from the client side code, because the controller methode with HttpReqeustMessage works without problems.
Here is the browser request:
Probably the problem is in your client code sending the data.
[FromBody] parameters must be encoded as =value
then, this does not work:
// Value will be null.
$.post('api/values', value);
// Value will be null.
$.post('api/values', { key: value });
But this work:
$.post('api/values', "=" + value);
Try to change your client code to send just =/path/to/your/file in the body.
Reference: http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
Ok I found a solution.
If I use a class as parameter and a property with the given name, it seems to work.
public class Param
{
public string psFileName { get; set; }
}
And
public HttpResponseMessage PostDownloadLogFile(Param poParam)
{
string psFileName = poParam.psFileName; //psFileName is set correct
This is not really a simple parameter but I can live with this solution.

Categories