How to upload object from JavaScript to Rest API - javascript

I have a Rest API:
[HttpPost]
[Route("Services/Image/Upload")]
public string Upload([FromBody]GalleryItem galleryItem)
{
try
{
var appSettings = ConfigurationManager.AppSettings["GalleryPath"].ToString();
using (FileStream fs = new FileStream(appSettings + galleryItem.KeyCode + ".jpg", FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
byte[] data = Convert.FromBase64String(galleryItem.Base64);
bw.Write(data);
bw.Close();
}
}
return "OK";
}
catch (Exception ex)
{
return ex.ToString();
}
}
and I call it from my Javascript client like:
var galleryItem = new Object();
galleryItem.Base64 = base64;
galleryItem.KeyCode = '1234';
url = "http://my domain name/api/Services/Image/Upload";
$.ajax({
type: 'POST',
url: url,
data: JSON.stringify(galleryItem),
contentType: 'application/json; charset=utf-8',
dataType: 'text/plain',
success: function (msg) {
alert('Image saved successfully !');
},
error: function (jqXHR, textStatus, err) {
$('#error').html('Error: ' + err);
}
});
my model:
public class GalleryItem
{
public string Base64 { get; set; }
public string KeyCode { get; set; }
}
I a testing this via a mobile device as I am taking image from camera to send up.
Nothing appears to happen? I just 'Error: error'?
thanks
ADDITIONAL:
After porting to a test script (wished I had done that sooner) I found the error is this:
net::ERR_NAME_NOT_RESOLVED
Though why I am unsure as I am calling another method from that api with no issues

Solved!
Thank God!
I changed the url to relative:
url = "/api/Services/Image/Upload";
without prefixing with domain name.
it must have got confused and thought it needed cors? (guess here)

Related

Can't figure out how WEB API Calls URLS

I'm learning WEB API on ASP.NET web forms and already implementing it on my project to show some data on a modal but I can't figure out how is the api url created.
I followed this tutorial
https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
this is my AJAX call
<script type="text/javascript">
function ShowUserModal(lnk, IdColaborador) {
debugger
//var s = lnk.id;
//var start = s.indexOf("lnkEdit");
//var end = s.lastIndexOf("_");
//sub = s.substring(start, end);
//s = s.replace(sub, "IdMatriz");
//var hidden = document.getElementById(s);
//var id = hidden.value;
//alert(id);
var uri = 'api/users/';
$.ajax({
URL: uri,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: IdColaborador,
success: function (data) {
alert("Saved successfully");
},
fail: function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
}
})
}
</script>
this is my controller
public class UsersController : ApiController
{
public User user { get; set; }
//public IEnumerable<User> GetAllUsers()
//{
// return users;
//}
public IHttpActionResult GetUser(int id)
{
user = new User();
string constr = ConfigurationManager.ConnectionStrings["ControloInterno_ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("spOperadores", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Action", "SELECTINF");
cmd.Parameters.AddWithValue("#IdColaborador", id);
con.Open();
using(SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
user.Nome = sdr["Nome"].ToString();
user.Criador = sdr["criador"].ToString();
user.DataAdm = Convert.ToDateTime(sdr["dataadmin"]);
user.AltData = Convert.ToDateTime(sdr["AltData"]);
user.Telemovel = sdr["tele"].ToString();
user.Departamento = sdr["Departamento"].ToString();
user.status = sdr["status"].ToString();
user.DescricaoPerfil = sdr["DescricaoPerfil"].ToString();
user.Observacoes = sdr["Observacoes"].ToString();
}
}
}
}
return Ok(user);
}
}
and I had to use this in global.asax to work
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
}
so my question is, how is the url generated? why is it called api/users if my controller is called UsersController and the class is called User
If you are using attribute routing make sure you call the following function on your HttpConfiguration:
// Web API routes
config.MapHttpAttributeRoutes();
You can read more about attribute routing here:
Web api attribute routing
Or if you will use MVC instead read here:
Attribute routing in MVC

How to resolve 400() error when file uploading via REST service

I have a program (Spring Boot) which is using REST service to upload files to the server or any other given location. But when I use the same service below error happened and below is the problem.
I am getting 400() error without any description when uploading a file via REST service. This application is Spring boot application which use java-script front-end to upload and download files via implemented rest service.
Help to resolve this. your help is appreciated. Thanks.
error is :
below is the code:
JS:
document.getElementById('import2').onclick = function () {
var files = document.getElementById('selectFiles').files;
console.log(files);
if (files.length <= 0) {
return false;
}
//serverUploaded = true;
var form_data = new FormData(files.item(0));
//from new NLP
$.ajax({
type: "POST",
url: "http://localhost:8080/gsta/upload",
processData: false,
contentType: false,
async: false,
cache: false,
data: form_data,
success: function (result) {
//alert(JSON.stringify(result));
//$("#out_lexalytics").html(JSON.stringify(result));
if (result) {
if(result.statusCode == 200)
{
serverUploaded = true;
}
}
}
});
}
REST service:
#PostMapping("/upload")
// If not #RestController, uncomment this
#ResponseBody
public ResponseEntity<?> uploadFile(#RequestParam("data") MultipartFile uploadfile) {
logger.debug("Single file upload!");
if (uploadfile != null && uploadfile.isEmpty()) {
return new ResponseEntity("please select a file!", HttpStatus.OK);
}
try {
saveUploadedFiles(Arrays.asList(uploadfile));
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity("Successfully uploaded - " + uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK);
}
I created the same scenario in my local environment with postman like this;
Server side with one small change (#RequestMapping(value = "/upload", method = RequestMethod.POST));
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity<?> uploadFile(#RequestParam("data") MultipartFile uploadfile) {
logger.debug("Single file upload!");
if (uploadfile != null && uploadfile.isEmpty()) {
return new ResponseEntity("please select a file!", HttpStatus.OK);
}
return new ResponseEntity("Successfully uploaded - " + uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK);
}
It works.
My assumption: your method saveUploadedFiles throws an IOException.
As you are getting a 400 Bad Request as response, I Think you should debug your
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
Block in order to find out what causes a IOException.

Angular JS + Spring MVC: Getting a 406 while trying to download a generated file

I'm trying to download a file that was generated from the database base64 String field. I see that file is created successfully but download fails...
This is my Spring MVC controller method:
#RequestMapping(value = "/download", method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Response download(#RequestBody DocumentCaseFile documentCaseFile) throws ServiceLogicException {
return documentCaseFileService.prepareFile(documentCaseFile);
}
Here is the service method:
#Override
public Response prepareFile(DocumentCaseFile documentCaseFile) throws ServiceLogicException {
final String contents = documentCaseFile.getContent();
final String pathAndFileName = "files/" + documentCaseFile.getFilename();
File file = new File(pathAndFileName);
byte[] decodedImg = Base64.getDecoder().decode(contents.getBytes(StandardCharsets.UTF_8));
Path destinationFile = Paths.get(file.getAbsolutePath());
try {
Files.write(destinationFile, decodedImg);
file = destinationFile.getFileName().toFile();
} catch (IOException e) {
e.printStackTrace();
file = null;
}
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM_VALUE)
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"" ) //optional
.build();
}
And here is the frontend part for the download function:
$scope.downloadFile = function(documentCaseFile) {
$http.post(webserviceUrl + documentCaseFileDownload, documentCaseFile, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/octet-stream'
}
}).then(function successCallback(response) {
console.log('file download response');
console.log(response);
}, function errorCallback(response) {
console.error('file download error');
console.log(response);
});
};
Any help greatly appreciated!
Generally speaking, when you have response.getOutputStream(), you can write anything there. You can pass this output stream as a place to put generated PDF to your generator. Also, if you know what file type you are sending, you can set
response.setContentType("application/pdf");
and you are use into you angular code, you need to change it with fie type
headers: {
'Content-Type': 'application/json',
'Accept': 'application/octet-stream'
}
Turns out produces = MediaType.APPLICATION_OCTET_STREAM_VALUE was causing the problem in the controller, I had to remove it to make the error go away:
#RequestMapping(value = "/download", method = RequestMethod.POST)

How to print receipt without print dialog box in client side

I want print receipt in client side without print dialog box, i am using mvc this is my solution to achieve my problem.
EPSON printer was installed in my system.This solution is working when host in my local iis but its not work when host in server and accessing from my local system getting "An error occurred while processing your request" error. In server no printer is installed.
$.ajax({
type: "POST",
url: '../Service/print',
cache: false,
data: { iprintData: printData, iprinterName: sPrinterName },
success: function (data) {
// alert('print Send Successfully');
},
error: function (ex) {
alert(ex.responseText);
// alert('error while Seding print');
}
});
this is my code in controller
public JsonResult print(string iprintData, string iprinterName)
{
Boolean bflag = false;
System.Web.HttpContext.Current.Session["_printData"] = iprintData;
PrintDocument printDocument = new PrintDocument();
printDocument.PrintController = new StandardPrintController();
printDocument.PrintPage += PrintDocumentOnPrintPage;
printDocument.PrinterSettings.PrinterName = iprinterName;
//printFont = new System.Drawing.Font("Arial", 10);
printDocument.Print();
bflag = true;
return Json(bflag, JsonRequestBehavior.AllowGet);
}
public static Image resizeImage(Image image, int new_height, int new_width)
{
Bitmap new_image = new Bitmap(new_height, new_width);
Graphics g = Graphics.FromImage((Image)new_image);
g.InterpolationMode = InterpolationMode.High;
g.DrawImage(image, 0, 0, new_width, new_height);
return new_image;
}
private void PrintDocumentOnPrintPage(object sender, PrintPageEventArgs e)
{
string printstring = System.Web.HttpContext.Current.Session["_printData"].ToString();
string path = HttpContext.Server.MapPath("~/content/Images/logo.png");
System.Drawing.Image img = Image.FromFile(path);
//img = resizeImage(img, 80, 60);
e.Graphics.DrawImage(img, 6, 100);
e.Graphics.DrawString(printstring, new System.Drawing.Font("ronnia", 9), Brushes.Black, 10, 150);
}
can any one help me from this ?
first you have to write windows service that contain HttpListener.
write your printing code inside the service
Install the service in client machine
call that service using ajax like below.
function PrintReceipt() {
var PrintData = JSON.parse($("#receiptData").html())
if (PrintData.length > 0) {
$.ajax({
type: "POST",
url: "http://localhost:41963/printOrder",
data: JSON.stringify({ "PrintData": PrintData }), //reciept data
crossDomain: true,
success: function (response) {
},
error: function () {
}
});
}
}
set System.Drawing.dll property
Copy Local=true

ASP AJAX POST call returns Unsupported Media Type

I am trying to make an AJAX call from a JavaScript script, but it keeps throwing Unsupported Media Type errors.
Here is the code for the AJAX call I am attempting:
var ParamList =
[{
"username": Username,
"oldPassword": OldPassword,
"newPassword": NewPassword
}];
$.ajax({
type: "POST",
url: "/LoginService.svc/ChangePassword",
data: JSON.stringify(ParamList),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var ReturnCode = data;
switch (ReturnCode) {
case 0:
$(Message).html("Password changed successfully");
break;
case -1:
$(Message).html("Password not changed");
break;
default:
$(Message).html("Error attempting to change the password - return code " + ReturnCode.toString());
break;
}
},
error: function (HelpRequest, ErrorCode, TheError) {
$(Message).html("Error attempting to change the password:<br />" + TheError);
}
});
and here is the code from LoginService.svc:
public class ChangePasswordParamList
{
public String username;
public String oldPassword;
public String newPassword;
}
[ServiceContract]
public interface LoginServiceInterface
{
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json)]
int ChangePassword(ChangePasswordParamList[] paramList);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class LoginService : LoginServiceInterface
{
public int ChangePassword(ChangePasswordParamList[] paramList)
{
String username = paramList[0].username;
String oldPassword = paramList[0].oldPassword;
String newPassword = paramList[0],newPassword;
int ReturnVal = 0;
// do some stuff here
return ReturnVal;
}
}
A similar AJAX POST call elsewhere in the code works fine. What am I missing here?
Problem solved - I needed to add the service to Web.Config (as pointed out in the other question Liam pointed out).

Categories

Resources