Upload File with angularJs passing additional parametres - javascript

I must do an upload of some images with Angularjs... The upload must be done in a custom folder, depending on the client is doing the upload... The folder could not exists, so, if it does not, I must create it...
I am doing the upload using this module ...
Here the controller that receive the file:
[HttpPost]
public IHttpActionResult UploadFile()
{
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
...
return Ok();
}
It works, but I cannot pass parameters to the method.. or perhaps I am not able... I would like something like:
[HttpPost]
public IHttpActionResult UploadFile(MyModel parameters)
{
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
...
return Ok();
}
Where MyModel, for example, is something like:
public class MyModel
{
public string folderName ....;
...
public List<File> FilesToUpload ...;
}
Perhaps the module I am using is complicating my life, so I can remove it with no problem... Do you have any suggestion?
Thank you

Please refer to following link for detailed information uploading file and sending json data in a single call
"http://shazwazza.com/post/uploading-files-and-json-data-in-the-same-request-with-angular-js/"

Related

Passing javascript variable to spring MVC controller with request param

Is it possible to send a javascript variable to a controller endpoint, and then have the controller return a new view?
I've tried using a requestbody and ajax to do it, which passes the variable correctly, but is unable to load a new view.
Maybe there's a way to do it with thymeleaf?
If you're using Thymeleaf then just reference the template you want to return to the user by its filename.
#Controller
public class YourController {
#GetMapping("/someUrl")
public String getTemplate(#RequestParam String templateName){
return templateName;
}
}
This would be the bare minimum that you'd need, assuming your templates are in the correct folder - by default in resources/static. If the frontend sends a GET (/someUrl?templateName=xyz) to the backend, it would return the xyz.html from your templates. If it does not find the template that was requested in the parameters then it will return a 404.
Edit: Reading through the comments I realized there might be a confusion between #RequestParam and #PathVariable. In case you want to use a path variable to define the template name, so that the frontend can call GET (/someUrl/xyz), then you can do
#Controller
public class YourController {
#GetMapping("/someUrl/{templateName}")
public String getTemplate(#PathVariable String templateName){
return templateName;
}
}
Resources for both below:
https://www.baeldung.com/spring-request-param
https://www.baeldung.com/spring-pathvariable

Not Able to map AJAX URL request into .java file

I have created one bootstrap modal on index.jsp. When I click on save button I have navigated my controller from .jsp file to .js file where i have written requestToChangePassword() in .js file. Now my question is, from that function i want to make ajax call request so that i can enter into one of the .java file and proceed further.
I have written ajax call like following code is in .js file:
ajaxCallFunctionget("../view/passwordChangeRequest",data,handlePasswordChangeHandler,"text", true);
In java file I have written
#Controller
public class UserGridAjaxController {
static Logger log = Logger.getLogger( UserGridAjaxController.class.getName() );
#RequestMapping(value = "/passwordChangeRequest", method = RequestMethod.GET)
#ResponseBody
public String passwordChangeRequest( /*#RequestParam("userNameForEdit")String userNameForEdit,*/HttpServletResponse response )
{
log.debug( "In passwordChangeRequest() method of class " + getClass().getName() );
System.out.println( "In passwordChangeRequest() method of class !!!" );
String result = "";
//result = delegate.deleteUser(userNameForEdit);
return result;
}
}
When I hit ajax request getting following exception in browser.
VM230 jquery.js:4 GET
http://localhost:8080/view/passwordChangeRequest?fromDate=05102019&_=1557482141385 404 (Not Found)
Hi I have created small project and shared proect on GitHub Please check and let me know where I am doing wrong.

Sending files through Axios to Asp.net Core Api?

How can I send my files from my javascript(files are through react dropzone) to my asp.net core api?
I am using axios and I have something like this
var data = new FormData();
data.append('folderName', "4141515");
data.append('file', files[0].fileObject); //dropzone wraps the fileobject
axiosInstance2.post("/inventories/ImportImage", data)
[HttpPost("ImportImage")]
public async Task<IActionResult> ImportImage(IFormFile file, string folderName){}
This does work but only the "file" is populated, "foldername" variable is empty.
I tried to put it in a model but it did not work (400 status code)
public class Test
{
public IFormFile file { get; set; }
public string folderName { get; set; }
}
Also is FormData the only way to send it to the server?
Edit
Seems like I need to use [FromForm] Test test
With the .net core api controller, you have to use the [FromBody] tag before the parameter, and change the parameter to type Test, it will bind the values to a class that you can use. Like this:
public async Task ImportImage([FromBody] Test your_values_here){}

In an action method, how can I bind post data to a dynamic object?

I want to do this:
public ActionResult SaveStuff(dynamic vm) {
StoreTheValue(vm.myvalue);
return Content("Saved :)");
}
This doesn't work, MVC doesn't seem to want to create a dynamic object with properties that correspond to the post data of the request.
Now I know that the whole point of properly defined view models is to create strongly typed data structures and have MVC bind data into them, but given that I'm posting data from javascript using ajax it's not strongly typed data anyway, so I don't see that I'm loosing any maintainability by doing this, and it will save me time and effort creating view model classes.
Can anyone help suggest how I can bind post data to a dynamic object, posssibly using a custom model binder?
One possible way to achieve this would be to use a custom model binder, assuming that you are posting Json to the action
public class DynamicBinder : IModelBinder
{
public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext )
{
using( var streamReader = new StreamReader( controllerContext.HttpContext.Request.InputStream ) )
{
return JsonConvert.DeserializeObject< dynamic >( streamReader.ReadToEnd() );
}
}
}
then in your action you can tell it, to use the custom binder
public ActionResult SaveStuff([ModelBinder(typeof(DynamicBinder))]dynamic vm) {
StoreTheValue(vm.myvalue);
return Content("Saved :)");
}
then post your json as such :
{
"myvalue":{...}
}
dynamic type and ajax request that you do with javascript is not corresponding.
You always can create your strongly typed object properties on javascript side.
Anyway you can use FormCollection like this:
[HttpPost]
public ActionResult yourAction(FormCollection collection)
{
StoreTheValue(Convert.ToString(collection["myvalue"]));
return Content("Saved :)");
}
But I think it's better to think of a strongly typed way.

Custom action result return specific view in MVC C#

I have an MVC application which i am trying to give the user the opportunity to download a zip of files,but unsuccesfully.Let me explain further.
Inside my view(ImageViewer.cshtml) i have a div class with an on click event that when pressed i call the controller method(ImageViewerController.GetZipPhotos) which handles the download of the zip file.See below:
div class="text" onclick="GetZipPhotos()">Download</div>
and the Javascript that get called is this:
function GetZipPhotos() {
$.ajax({
url: '#Url.Action("GetZipPhotos", "ImageViewer",Request.Url.Scheme)',
type: 'POST',
contentType: 'application/zip',
error: function () {
alert('There was an error!'+result);
}
});
}
Now, inside my ImageViewerController i have the following method:
[HttpPost]
public ActionResult GetZipPhotos()
{
ZipResult newZipResult=new ZipResult(
Server.MapPath("~/File1.txt"),
Server.MapPath("~/File2.txt")
);
newZipResult.OutPutZipFileName = "PhotosZip.zip";
return newZipResult;
}
and the declaration of the ZipResult custom action is:
public class ZipResult:ActionResult
{
private IEnumerable<string> _filesToZip;
private string _outPutZipFileName="ZipFile.zip";
public ZipResult(params string[] filesToZip)
{
this._filesToZip = filesToZip;
}
public override void ExecuteResult(ControllerContext context)
{
using (ZipFile oneZipFile = new ZipFile()) {
oneZipFile.AddFiles(_filesToZip);
context.HttpContext.Response.ContentType = "application/zip";
context.HttpContext.Response.AppendHeader("content-disposition", "attachment; filename=" + _outPutZipFileName);
oneZipFile.Save(context.HttpContext.Response.OutputStream);
}
}
}
The problem is that the code ofcourse doesn't work because the name of the view that called the controller is different from the actual method(GetZipPhotos).The view's name is ImageViewer.cshtml and the controller's name is ImageViewerController.
As fas as i have understood, the MVC framework uses code conventions, so it expects the name of the method to be the same as the view.The problem is that my view and the method are diferrent so the response never gets to back to the view.
I thought of creating a new view that has basically nothing inside, just to call it from the method and return the zip file.If this could be a possible solution, how can i tell from the action result which view to send the response?
No need to use ajax for the file download. The browser will normally start the download and keep you on the same page. Also, no need for a custom action result, you can just use FileResult. Try something like this:
public FileResult GetZipPhotos()
{
var filesToZip = new List<string> { Server.MapPath("~/File1.txt"), Server.MapPath("~/File2.txt") };
var oneZipFile = new ZipFile();
oneZipFile.AddFiles(filesToZip);
return File(oneZipFile.ToByteArray(), "application/zip", "PhotosZip.zip");
}
Of course, you'll need to figure out this part oneZipFile.ToByteArray(), but the ZipFile class probably already has something like that.
Your ajax call is redirecting the response into nowhere.
I would do it like this:
use a hidden iframe, change its src to the desired path in your function and it should be prompting a file dialog.

Categories

Resources