How to upload file with web-api - asp.net

Client side code:
<form action="api/MyAPI" method="post" enctype="multipart/form-data">
<label for="somefile">File</label> <input name="somefile" type="file" />
<input type="submit" value="Submit" />
</form>
And how to process upload file with mvc web-api,have some sample code?

HTML Code:
<form action="api/MyAPI" method="post" enctype="multipart/form-data">
<label for="somefile">File</label>
<input name="somefile" type="file" />
<input type="submit" value="Submit" />
</form>
Controller
// POST api/MyAPI
public HttpResponseMessage Post()
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.AllKeys[0] == "image")
{
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/Images/" + postedFile.FileName);
postedFile.SaveAs(filePath);
docfiles.Add(filePath);
}
result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return result;
}
try below link
this link use for me hopefully it will work you
http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-2

You can use ApiMultipartFormFormmatter to upload file to web api 2.
By using this library, you can define a view model to get parameters submitted from client-side. Such as:
public class UploadFileViewModel
{
public HttpFile Somefile{get;set;}
}
And use it in your Api controller like this:
public IHttpActionResult Upload(UploadFileViewModel info)
{
if (info == null)
{
info = new UploadFileViewModel();
Validate(info);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok();
}
Nested objects can be parsed by this library.

Related

How can I download a PDF file from a path or folder using asp.net

Good afternoon, I have an asp.net project and I would like that through an asp.net c # form a patient can download a certificate from a path or folder through their identification number or code, the folder it contains contains pdf and are organized by ID number
Thank you
Due to your vague description, I am not sure if you are an mvc project
or a core project.
The following is a case of downloading pdf in each project, please refer to:
In mvc:
public ActionResult DownLoad()
{
return View();
}
[HttpPost]
public ActionResult DownLoad(string id)
{
//PdfFiles is the name of the folder where these pdf files are located
var path = Server.MapPath("~/PdfFiles/pdf" + id + ".pdf");
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, "application/pdf", Path.GetFileName(path));
}
View:
<form method="post" action="DownLoad">
Pdf Id: <input id="Text1" type="text" name="id" />
<input id="Submit1" type="submit" value="submit" />
</form>
Here is the test result:
In Core:
public IActionResult DownLoad()
{
return View();
}
[HttpPost]
public async Task<IActionResult> DownLoad(string id)
{
//here i put the PdfFiles folder in the wwwroot folder
var path = Path.Combine(
Directory.GetCurrentDirectory(),
"wwwroot", "PdfFiles/pdf" + id + ".pdf");
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, "application/pdf", Path.GetFileName(path));
}
View:
<form asp-action="DownLoad" method="post">
Pdf Id: <input id="Text1" type="text" name="id"/>
<input id="Submit1" type="submit" value="submit" />
</form>
Here is the test result:

How to render input elements inside form elements

Antaris RazorEngine v3.9.3 is used in ASP.NET MVC4 controller to create form element.
In result html input elements are rendered outside form element.
For example
#using (Html.BeginForm("Test", "Upload"))
{
<input type="file" />
<input type="submit"/>
}
produces
<form action="/Upload/Test" method="post"></form>
<input type="file" />
<input type="submit"/>
while correct result should be
<form action="/Upload/Test" method="post">
<input type="file" />
<input type="submit"/>
</form>
RenderScript returns only input elements. <form action="/Upload/Test" method="post"> is written to output directly. It looks like BeginForm() writes directly to view and Razorengine does not capture its output.
How to fix this ?
View:
#Model.RenderScript()
Model:
public IHtmlString RenderScript() {
var config = new TemplateServiceConfiguration();
config.BaseTemplateType = typeof(HtmlTemplateBase<>);
config.Namespaces = new HashSet<string>(new string[] {
"System",
"System.Collections",
"System.Collections.Generic",
"System.Globalization",
"System.Linq",
"System.Web",
"System.Web.Mvc",
"System.Web.Mvc.Html"
});
razor = RazorEngineService.Create(config);
// In real application colModel is retrieved from database
var colModel=#"
#using (Html.BeginForm(""Test"", ""Upload""))
{
<input type='file' />
<input type='submit'/>
}
";
string res = razor.RunCompile(colmodel, colmodel, typeof(object), new object());
return MvcHtmlString.Create(res);
}
Template base class:
using RazorEngine.Templating;
using RazorEngine.Text;
using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
public class HtmlTemplateBase<T> : TemplateBase<T>, IViewDataContainer
{
// http://stackoverflow.com/questions/8561164/razorengine-issues-with-html
HtmlHelper<T> helper = null;
ViewDataDictionary viewdata = null;
public HtmlHelper<T> Html
{
get
{
// https://github.com/Antaris/RazorEngine/issues/150
if (helper == null)
{
var p = WebPageContext.Current;
var wvp = p.Page as WebViewPage;
var context = wvp != null ? wvp.ViewContext : null;
context.Writer = this.CurrentWriter;
helper = new HtmlHelper<T>(context, this);
}
return helper;
}
}
public ViewDataDictionary ViewData
{
get
{
if (viewdata == null)
{
viewdata = new ViewDataDictionary();
viewdata.TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = string.Empty };
if (this.Model != null)
{
viewdata.Model = Model;
}
}
return viewdata;
}
set
{
viewdata = value;
}
}
public override void WriteTo(TextWriter writer, object value)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (value == null) return;
//try to cast to RazorEngine IEncodedString
var encodedString = value as IEncodedString;
if (encodedString != null)
{
writer.Write(encodedString);
}
else
{
var htmlString = value as IHtmlString;
if (htmlString != null) writer.Write(htmlString.ToHtmlString());
else
{
encodedString = TemplateService.EncodedStringFactory.CreateEncodedString(value);
writer.Write(encodedString);
}
}
}
}
Posted also in https://github.com/Antaris/RazorEngine/issues/443

InvalidCastexception upload multiple images

Hi everyone I am creating an application using MVC 5, with a code first database,The code below shows the code I am currently trying to use to upload multiple images but I get an InvalidCastexception when trying to cast 'System.String' to type 'System.Web.HttpPostedFileBase'.
Thanks for your time and any help with this issue is greatly appreciated.
Images Controller
// GET: Images/Upload
[HttpGet]
public ActionResult Upload()
{
return View();
}
// POST: Images/Upload
[HttpPost]
public ActionResult Upload(IEnumerable<HttpPostedFileBase> uploadFiles)
{
HttpFileCollectionBase files = Request.Files;
foreach (HttpPostedFileBase file in files)
{
int length = file.ContentLength;
string type = file.ContentType;
string filename = file.FileName;
}
return RedirectToAction("Upload");
}
upload view
#{Layout = null;}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Upload</title>
</head>
<body>
<form method="post" action="~/Images/Upload" id="form1" enctype="multipart/form-data">
#if (ViewData.Model != null)
{
foreach (var item in ViewData.Model)
{
<img src="/Images/#item["Path"]" alt="FileUpload Image" />
}
}
<input type="file" name="uploadFiles" id="FileUpload" multiple="multiple" />
<input type="submit" name="btnSubmit" value="Upload" id="btnSubmit" />
</form>
</body>
</html>
You can't do that
foreach (HttpPostedFileBase file in files)
because the enumerator of HttpFileCollection will return names of the files (string) but not HttpPostedFileBase so you will got InvalidCastexception
Use uploadFiles in the loop instead of HttpFileCollectionBase
public ActionResult Upload(IEnumerable<HttpPostedFileBase> uploadFiles)
{
foreach (var file in uploadFiles)
{
int length = file.ContentLength;
string type = file.ContentType;
string filename = file.FileName;
}
return RedirectToAction("Upload");
}
or use for and index:
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
int length = files[i].ContentLength;
string type = files[i].ContentType;
string filename = files[i].FileName;
}

Asp.net MVC, Pass Array to Controller From View Without Using Ajax

I am Using asp.net mvc 5. I want to pass array of string from view to controller without using Ajax. Can Anyone help?
This is the controller, value is to be gotten in packagelist[]
public ActionResult Create(Business business, string loc, string serv, string[] packagelist)
{
try
{
if (ModelState.IsValid)
{
var a = locationIds;
business.ServiceId = db.Services.Where(x => x.Title ==serv).Select(x => x.Id).SingleOrDefault();
business.LocationId = db.Locations.Where(x => (x.Title + " (" + x.State + "), " + x.PostalCode)==loc).Select(x => x.Id).SingleOrDefault();
db.Businesses.Add(business);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
foreach(var error in ModelState.Values)
{
foreach(var er in error.Errors)
ModelState.AddModelError("", er.Exception.ToString());
}
}
ViewData["Packages"] = db.BusinessPackages.Select(x => new SelectListItem
{
Text = x.Package,
});
return View(business);
}
catch(Exception ex)
{
ModelState.AddModelError("", ex);
return View(business);
}
}
Have created an hidden input on view
<input type="hidden" name="packagelist" id="packagelist" value="" />
Then set the value of this hidden field via this function
$("#theform").submit(function (e) {
e.preventDefault();
var locdiv=$("#maindiv");
var locations = locdiv.children();
var loc = [];
for (var i = 0; i < locations.length; i++)
{
loc.push(locations.eq(i).text());
}
// SaveLocations(loc);
$("#packagelist").val(loc);
$("#theform").submit();
Now main problem is that when I set value of the input via Jquery and submit it to the controller, controller is considering the array of values as single value.
To receive an array as param in controller, your inputs need specific naming
<input type="hidden" name="packagelist[0]" id="packagelist_0_" value="" />
<input type="hidden" name="packagelist[1]" id="packagelist_1_" value="" />
<input type="hidden" name="packagelist[2]" id="packagelist_2_" value="" />
...
<input type="hidden" name="packagelist[x]" id="packagelist_x_" value="" />
I think you can use cookies.
In JS,
document.cookie = "CookiesName=" + value + "; " + "365;path=/";
In Controller,
var data = Request.Cookies["CookiesName"]

spring 3 upload many files

yeah,our customer want to upload more than one file.
we use spring 3 mvc.
the official example like this:
markup:
<form method="post" action="/form" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
code:
#RequestMapping(value = "/form", method = RequestMethod.POST)
public String handleFormUpload(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
} else {
return "redirect:uploadFailure";
}
}
there is only one file,so i can write the file input name in the method.
but what should i do if i want to upload many files.
i could not write all the file input names because if is generated by the js code.
i only know that its name like 'attach_'
then ,what should i write in the method ? if i write like this
#RequestParam() MultipartFile file
or
#RequestParam("attach_") MultipartFile file
i'll get a error.
A much simpler way - works for me
/*** Upload Images ***/
#RequestMapping(value = "/images/upload", method = RequestMethod.POST)
public void upload(#RequestParam("file") List<MultipartFile> files, #RequestParam("user") String user) {
files.forEach((file -> System.out.println(file.getOriginalFilename())));
}
I have it working with Spring 3.0.4 (there was an issue in previous versions of Spring, so be sure to use >= 3.0.4).
To test it, you can use the following steps:
public class MultiPartFileUploadBean {
private List<MultipartFile> files;
public void setFiles(List<MultipartFile> files) {
this.files = files;
}
public List<MultipartFile> getFiles() {
return files;
}
}
The controller:
#RequestMapping(value = "/uploadtest", method = RequestMethod.POST)
public String uploadtestProcess(MultiPartFileUploadBean file, BindingResult bindingResult,
Model model) throws IOException {
... // binding check
StringBuilder sb = new StringBuilder();
List<MultipartFile> files = file.getFiles();
for(MultipartFile f:files)
sb.append(String.format("File: %s, contains: %s<br/>\n",f.getOriginalFilename(),new String(f.getBytes())));
String content = sb.toString();
model.addAttribute("content", content);
return "uploadtest";
}
The jsp:
<form method="post" action="/uploadtest" enctype="multipart/form-data">
<p>Type: <input type="text" name="type" value="multiPartFileSingle" size="60" /></p>
<p>File 1: <input type="file" name="files[0]" size="60" /></p>
<p>File 2: <input type="file" name="files[1]" size="60" /></p>
<p><input type="submit" value="Upload" /></p>
</form>
<c:if test="${not empty content}">
<p>The content uploaded: <br/>${content}</p>
I found clearer to use the MultipartHttpServletRequest object as a parameter to the controller method:
#RequestMapping(value = "/save", method=RequestMethod.POST)
protected String save(Model model, MultipartHttpServletRequest multipartRequest) {
MultipartFile file = multipartRequest.getFile("field-name");
// Also multiple files with same name
List<MultipartFile> files = multipartRequest.getFiles("multifield-name");
// ...
}
Link to the docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-multipart-resolver-commons
You use model and form.
( Html / Jsp )
<form id="uploadForm" method="POST"enctype="multipart/form-data/charset=UTF-8">
//...multi file, add dynamic input
<input type="file" name="file"/>
<input type="file" name="file"/>
<input type="file" name="file"/>
<input type="file" name="file"/>
</form>
<input type="button" id="save_button" value="save" />
(Js)
var form = new FormData(document
.getElementById('uploadForm'));
$.ajax({
url : "/test/upload/file,
type : 'POST',
dataType : 'text',
data : form,
processData : false,
contentType : false,
success : function(response) {
if (response == "success") {
document.location.reload(true);
} else {
$("#editMsg").text("fail");
}
},
error : function(request, status, error) {
}
});
( Model )
public class fileModel {
private List<MultipartFile> file; // this name = input name
... setter, getter
}
( Controller )
#RequestMapping(value = "/upload/file", method = RequestMethod.POST)
public #ResponseBody String uploadFiles(fileModel model, HttpServletRequest req) {
return "success" // <-- debug. break point !! Your watch model.
}
You can find it here:
http://dhruba.name/2008/12/27/implementing-single-and-multiple-file-multipart-uploads-using-spring-25/

Resources