Shopify app with proxy extension PUT requests not working - shopify

I have managed to created an app proxy using this guide:
https://shopify.dev/tutorials/display-data-on-an-online-store-with-an-application-proxy-app-extension#handling-proxy-requests
I wanted to update the customer record using a form. On submission of form the below func would be invoked.
jQuery(function($) {
$('#enrollFormID').submit(function() {
var fname = $(FirstName).val();
var lname = $(LastName).val();
var emailID = $(email).val();
var pass = $(password).val();
event.preventDefault();
var data = jQuery(this).serialize();
console.log(data);
data = "form_type="+data;
$.ajax({
url: '/apps/subpath',
type: 'PUT',
data: data,
dataType: 'json',
success: function (data) {
console.info(data);
}
});
return true;
});
});
In the backend app, the below url is getting hit when the form gets submitted, but am not able to retrieve the form data values.
router.put('/test', async (ctx) => {
.....
}
Get request works fine, but with Put request am not able to retrieve the form data from the ajax call.
Can someone help me on this?

Related

How to use Nuxt 3 server as a passthrough API with FormData to hide external endpoints

I'm trying to get my head around the Nuxt /server API and can't seem to figure out how to send a POST request with form-data (ie files) to Nuxt server to forward on to an external service:
In my pages.vue file I have this method:
async function onSubmit() {
const formData = new FormData();
for (let file of form.files) {
await formData.append("image", file);
}
await $fetch("/api/send", {
method: "POST",
body: formData
});
}
and then in /server/api/send.js I have:
export default defineEventHandler(async (event) => {
const { method } = event.node.req;
// I THINK THE ISSUE IS HERE
const body =
method !== "GET" && method !== "HEAD"
? await readMultipartFormData(event)
: undefined;
const response = await $fetch.raw(https://*******, {
method,
baseURL: *********,
headers: {
},
body: body
});
return response._data;
}
I'm effectively creating a passthrough API using Nuxt so that the external endpoint isn't exposed to the end user. Just can't figure out how to access the formData in the correct format to pass through on the server side. I don't think I am supposed to use readMultipartFormData() because that seems to be parsing the data somehow whereas I just want to pass the formData straight through to the external API. Any tips?
I've tried using both readMultipartFormData() and readBody() and neither seem to work. I don't actually need to read the body but rather get it and pass it through without any formatting...
If you want to pass the data with formdata to the endpoint try this library:
https://www.npmjs.com/package/object-to-formdata
code:
import { serialize } from 'object-to-formdata';
const formData = serialize(body);
const response = await $fetch.raw(https://*******, {
method,
baseURL: *********,
headers: {
},
body: formData
});
I managed to make it work with ugly solution, first you have to update nuxt to version 3.2.0 min then here my front side
let jobApplicationDTO = {
firstName: values.firstName,
lastName: values.lastName,
email: values.email,
phoneNumber: values.phoneNumber,
company: values.company,
shortDescription: values.shortDescription
};
const formData = new FormData();
formData.append("application", new Blob([JSON.stringify(jobApplicationDTO)], {type: "application/json"}));
formData.append("file", values.file) ;
//formData.append("file", values.file );
await useFetch("/api/application", {
method: "POST",
body: formData,
onResponse({request, response, options}) {
// Process the response data
if (response.status === 200) {
errorMessage.value = "";
successMessage.value = "Your application wa sent successfully, you will be contacted soon !";
}
},
onResponseError({request, response, options}) {
console.debug(response);
if (response.status === 400) {
successMessage.value = "";
errorMessage.value = "There may be an issue with our server. Please try again later, or send an email to support#mantiq.com";
} else {
successMessage.value = "";
errorMessage.value = "Sorry we couldn’t send the message, there may be an issue with our server. Please try again later, or send an email to support#mantiq.com";
}
},
});
}
and server side
import {FormData} from "node-fetch-native";
export default defineEventHandler(async (event) => {
const {BACKEND_REST_API, ENQUIRY_TOKEN} = useRuntimeConfig();
//retrieve frontend post formData
const form = await readMultipartFormData(event);
const applicationUrl = BACKEND_REST_API + '/job/apply'
console.log("url used for enquiry rest call :" + applicationUrl);
console.log("Job application token :" + ENQUIRY_TOKEN);
const formData = new FormData();
console.log(form);
if (form) {
formData.append(form[0].name, new Blob([JSON.stringify(JSON.parse(form[0].data))], {type: form[0].type}));
formData.append(form[1].name, new Blob([form[1].data], {type: form[1].type}), form[1].filename);
}
console.log(formData.values);
return await $fetch(applicationUrl, {
method: "POST",
body: formData,
headers: {
Authorization: ENQUIRY_TOKEN,
},
});
})
What is funny is on frontend you have to create a formData , then to get content and to recreate a formData from your previous formData converted in MultiFormPart[], i created a ticket on nuxt to see how to do it properly

send another Data field to action when i want upload file

i have this controller for uploading file
[HttpPost]
public JsonResult Upload( HttpPostedFileBase uploadedFile)
{
//uploadedFile parameter geting seccusfully but i can not get other field such as news about file
}
this is my java script for sending file to action
function UploadFile() {
var form = $('#FormUpload')[0];
var dataString = new FormData(form);
$.ajax({
url: '/Home/Upload',
type: 'POST',
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
//myXhr.upload.onprogress = progressHandlingFunction
myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
success: successHandler,
error: errorHandler,
complete:completeHandler,
// Form data
data: dataString,
//**********
//i want send another filed with datastring but i can not
//**********
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
}
this is my view code
enter image description here
i want send textarea content with uploaded file to action
tanx

How to get compiled HTML

What I am trying to is to upload Blob file using MVC controller.
Here is the client code
var blob = new Blob('file');
var fd = new FormData();
fd.append('blob', blob);
$.ajax({
type: 'POST',
url: "/api/materialList/GenerateReportForMac",
processData: false,
contentType: false,
data: fd
});
Here is server MVC code
public HttpResponseMessage GenerateReportForMac(HttpPostedFileWrapper blob)
{
// do something here
}
Here is routeconfig
routes.MapHttpRoute("GenerateReportForMac", "api/materialList/GenerateReportForMac", new { controller = "MaterialListReportApi", action = "GenerateReportForMac" });
However router doesn't map the ajax call to the controller. What did I miss? I have read a number of similar questions here and on other sites and I followed what is suggested but no luck. I appreciate any tip.
I have spent enough time to figure out by my self but I couldn't so please don't flag it'

Calling POST as URL ASP.NET web api

I want to know how to test POST by typing in the url.
Here's my route Config
config.Routes.MapHttpRoute(
name: "myWebApi",
routeTemplate: "api/mywebapi/{action}/{ID}/{DeptID}",
defaults: new { Controller = "mywebapi", ID = #"\d+", DeptID = #"\d+" }
);
programmatically this is how I call POST
I have 3 text boxes and a button. When user clicks on the button the below program gets called
function parseform(button) {
var id = $("#ID").val();
var deptid = $("#DeptID").val();
var name = $("#Name").val();
var inputdata = {
id: id,
deptid: deptid,
name: name
}
if (button.attr('value') === "POST") {
postdata(inputdata);
} else {
console.log("ERROR");
}
}
function postdata(inputdata) {
$("#response").text("Posted");
$.ajax({
type: "POST",
dataType: "json",
url: "api/mywebapi/Post/",
contentType: "application/json",
data: JSON.stringify(inputdata),
xhrFields: {
withCredentials: true
},
success: function (data, status, xhr) {
$("#response").text(status+" - "+data)
},
error: function (xhr, status, error) {
var json = jQuery.parseJSON(xhr.responseText);
$("#response").text(status)
}
});
}
In the controller
[System.Web.Http.AcceptVerbs("POST")]
public void Post([FromBody]mywebapi value)
{
saves to database
}
Here's what I tested
http://localhost:222/api/mywebapi/Post/new newwebapi ({"id":"1","deptid":"2","name":"testing"})
I get error. How to test this?
thanks
R
Since it's a POST request, you can't test it in your browser by typing in an address (those are GET requests, which contain no body).
To test these types of things you can use something like Postman
or Rest Console (if you're using chrome), there's tons of these types of things in whatever your browsers extension store is called.
Some tools you can use are something like Fiddler
this will let you see what the requests and responses look like, and you can change/modify them as well, though it's probably a bit harder to use than something like PostMan or Rest Console (also more powerful)

asp.net webapi validation

I have an API Controller and call action from JS:
$('#create-se').on('click', function () {
var data = {};
$.ajax({
url: 'api/registration',
type: 'POST',
data: data,
dataType: 'json',
contentType: 'application/json',
success: function () {
}
});
});
public bool Post(UserRegistrationViewModel model)
{
if (!ModelState.IsValid) { return false; }
return true;
}
Model has few required properties and few StringLength. When I send data from js to controller ModelState.IsValid always returns true. I can't figure out how to solve it. Even if posted model is null, Model.IsValid is true anyway
http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/
This website has a better way of doing validation and using headers to send the token across and if it invalid it will return validation failed.