Using ASP Web API, I create a method that takes an ID then deliver a pdf file, then using Google docs viewer, or similar service, to view the file,
The code looks something like this,
[HttpGet]
public HttpResponseMessage GetAttachment(string id)
{
try {
string mapping = #"\\192.168.3.3\Archieve";
string sourcedir = #"\Digital\";
string filename = id + ".pdf";
string sourceFullPath = mapping + sourcedir + filename;
byte[] dataBytes = new byte[0];
// connect to other network using custom credential
var credential = new NetworkCredential("user", "pass", "192.168.3.3");
using (new NetworkConnection(mapping, credential)) {
dataBytes = File.ReadAllBytes(sourceFullPath);
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(new MemoryStream(dataBytes));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = filename;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return response;
}
catch (Exception ex) {
return Request.CreateResponse(HttpStatusCode.Gone, ex.Message);
}
}
With this code, I'm able to download the pdf file when I open the link on web browser, but when I try to display it using Google docs viewer, like this
https://docs.google.com/viewerng/viewer?url=http://myserver/webapi/api/File/GetAttachment/0317101532
Google failed to display the file without error,
And when I use other service like https://www.pdfescape.com/open/ the error is The remote server returned an error: (405) Method Not Allowed.
EDIT: I think both Google Docs viewer and pdfescape need direct link to the file, can I generate direct link on Web API controller?
Try to copy the file to local, and then return the file link, something like this
[HttpGet]
public IHttpActionResult GetAttachment(string id)
{
try {
string mapping = #"\\192.168.3.3\Archieve";
string sourcedir = #"\Digital\";
string filename = id + ".pdf";
string sourceFullPath = mapping + sourcedir + filename;
byte[] dataBytes = new byte[0];
// connect to other network using custom credential
var credential = new NetworkCredential("user", "pass", "192.168.3.3");
using (new NetworkConnection(mapping, credential)) {
dataBytes = File.ReadAllBytes(sourceFullPath);
}
// write file to local
string destFullPath = string.Format("{0}/Content/Data//{2}", HttpContext.Current.Server.MapPath("~"), filename);
File.WriteAllBytes(destFullPath, dataBytes);
// return the file name,
return Ok(filename);
// then you can view your docs using Google Viewer like this
// https://docs.google.com/viewer?url=http://[YOUR_SERVER_BASE_URL]/content/data/[FILENAME]
}
catch (Exception ex) {
return Content(HttpStatusCode.PreconditionFailed, ex.Message);
}
}
Don't forget to add required permission on 'Content' folder
Related
I tried to test my APIs (Direct Download Pdf API) using postman (Send & Download) and all went well and the file was downloaded successfully, no need to set login information. But when i tried to use mozilla browser, it's tell me login required? why?
Here is my response header using postman:
And here when i try using browser, show idm downloader ask username password:
Here is my code
[Authorize]
[HttpGet]
public IHttpActionResult GetDownloadPdf(string date)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
ResponseData responseData = new ResponseData();
try
{
_logDataBLL.SaveRequestLogRecord(RequestType.GET, MethodBase.GetCurrentMethod().Name);
MA_MS_Agent objdata = new MA_MS_Agent();
//Update - Checking current user still active
var identity = User.Identity as ClaimsIdentity;
if (LoginBLL.isStillActive(identity) == false)
{
dynamic Reject = new ExpandoObject();
Reject.Message = "Authorization has been denied for this request.";
return Content(HttpStatusCode.Unauthorized, Reject);
}
date = "01" + date.Substring(2);
string filename = "1000007"+ "_" + date + ".pdf";
ByteArrayContent pdfByte;
MA_MS_ApplicationParameter Selected_Parameter = AddReferralBLL.getAppParameterByCode("APPP025");
string param_value = Selected_Parameter.ApplicationParameter_Value;
string pdfFilePath = param_value + filename;
byte[] bytes = null;
if (File.Exists(pdfFilePath))
{
bytes = System.IO.File.ReadAllBytes(pdfFilePath);
}
else
{
return BadRequest();
}
using (var m = new MemoryStream())
{
pdfByte = new ByteArrayContent(bytes);
}
if (pdfByte == null)
{
responseData = _responseDataBLL.GenerateResponseData(HttpStatusCode.NoContent);
responseData.status = true;
return Ok(responseData);
}
response.Content = pdfByte;
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = filename;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("Application/pdf");
//response.Headers.Add("MyHeader", "MyHeaderValue");
//response.Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json");
return ResponseMessage(response);
}
catch (Exception ex)
{
string error = ex.Message;
if (ex.InnerException != null)
error += " => " + ex.InnerException.Message;
responseData = _responseDataBLL.GenerateResponseData(HttpStatusCode.InternalServerError, error);
_logDataBLL.SaveResponseLogRecord(JsonConvert.SerializeObject(responseData));
return Content(HttpStatusCode.InternalServerError, responseData);
}
}
Oauth2 Flow:
When you try to access your api from a browser, like your Mozilla browser, you need to get the access token from your oauth server first. So your clientapp should authorize the user and use the users token for the authorisation.
Getting the authtoken depends from your Auth Server.
The keycloak project explains how you can authorize in a JS-ClientApplication like an angular or react app and pass the bearer token to another api.
https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter
Without Authorisation:
you are forcing authorization in your code.
You should replace the [Authorize] attribute with [AllowAnonymous]
[AllowAnonymous]
[HttpGet]
public IHttpActionResult GetDownloadPdf(string date)
{
//.. code
}
Update better link:
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/simple?view=aspnetcore-3.1
Looks like your URL requires a basic auth.
It is working in postman because you are sending an Authorization header in postman. But in the browser, when you try to open that URL, it doesn't have any authorization header.
I am having an API.Net Core Web API app that has a POST method that accepts and processes a PDF file.
However, when I try to test in POSTMAN (Selecting POST, selecting Binary, choosing a file) I get a following error
InvalidOperationException: Incorrect Content-Type: text/plain
At the following line
var file = Request.Form.Files[0];
Please let me know if there is anything I need to fix
Thank you in advance
Here is the entire method
[HttpPost]
[Route("SubmitForm")]
public async Task<IActionResult> SubmitForm()
{
var file = Request.Form.Files[0];
HttpClient client = GetClient();
try
{
byte[] docAsBytes;
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
docAsBytes = ms.ToArray();
string s = Convert.ToBase64String(docAsBytes);
// act on the Base64 data
}
PdfReader pdfReader = new PdfReader(docAsBytes);
MemoryStream m = new MemoryStream();
PdfStamper outStamper = new PdfStamper(pdfReader, m);
string formName = outStamper.AcroFields.GetField("FormSeqNo");
string endpointUrl = "https://myproject.sharepoint.com/sites/project" + String.Format(
"/_api/web/GetFolderByServerRelativeUrl('{0}')/Files/Add(url='{1}', overwrite=true)",
this.Config["TemplateLibrary"].Replace(" ", "%20"),
formName + ".pdf");
ByteArrayContent imageBytes = new ByteArrayContent(docAsBytes);
var result = await client.PostAsync(endpointUrl, imageBytes);
//return result.Content.ToString();
}
catch (Exception ex)
{
//return ex.ToString();
}
return Ok();
}
I am trying to upload file using web api in c#. I tried in postman. It works properly. I was confuse how to do it in c# code .
I have tried following code but it gives error.
var request = (HttpWebRequest)WebRequest.Create("http://Api_projects/add_project");
var postData = "name=thisIsDemoName&img=" + Server.MapPath(FileUpload1.FileName) +"&info=ThisIsDemoInfo";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "multipart/form-data";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Response.Write(responseString);
When run the code it write following error message on screen
A PHP Error was encountered
Severity: Notice
Message: Undefined index: img
Filename: controllers/Api_projects.php
Line Number: 27
Backtrace:
File: /home/fpipj1blp4wo/public_html/ecosense.in/application/controllers/Api_projects.php
Line: 27
Function: _error_handler
File: /home/fpipj1blp4wo/public_html/ecosense.in/application/libraries/REST_Controller.php
Line: 785
Function: call_user_func_array
File: /home/fpipj1blp4wo/public_html/ecosense.in/index.php
Line: 315
Function: require_once
plz help
Sending multipart/form-data is a bit more complicated. Have a look at: Upload files with HTTPWebrequest (multipart/form-data)
Since you didn't write what are you using (.NET Framework or .NET Core,...) I will assume that you mean .NET Core Web Api.
So, I do this by creating folder (for instance Resources (this dir is in the same dir that is controllers, migrations, models,....), and inside Resource folders I create another folder called Images.
Then in desired controller, I do this:
[HttpPost]
public IActionResult Upload() {
try {
var file = Request.Form.Files[0];
var folderName = Path.Combine("Resources", "Images");
var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);
if (file.Length > 0) {
var fname = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
var fullPath = Path.Combine(pathToSave, fname);
var dbPath = Path.Combine(folderName, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create)) {
file.CopyTo(dbPath);
}
return Ok(new { dbPath });
}
else {
return BadRequest();
}
}
catch (Exception ex) {
return StatusCode(500, "Internal server error");
}
}
This should work. However, this uploaded files/images, are stored in Resource folder, and we need to make this folder servable. So you need to modify the Configure method in Startup.cs class
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions() {
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), #"Resources")),
RequestPath = new PathString("/Resources")
});
This is just an example. There are many more ways to upload an image.
Hope it helps
I have a Web API project that is running on a server. It is supposed to return PDFs from two different kinds of sources: an actual portable document file (PDF), and a base64 string stored in a database. The trouble I'm having is sending the document back to a client MVC application. The rest of this is the details on everything that's happened and that I've already tried.
I have written code that successfully translates those two formats into C# code and then (back) to PDF form. I have successfully transferred a byte array that was supposed to represent one of those documents, but I can't get it to display in browser (in a new tab by itself). I always get some kind of "cannot be displayed" error.
Recently, I made a way to view the documents on the server side to make sure I can at least get it to do that. It gets the document into the code and creates a FileStreamResult with it that it then returns as an (implicit cast) ActionResult. I got that to return to a server side MVC controller and threw it into a simple return (no view) that displays the PDF just fine in the browser. However, trying to simply go straight to the Web API function simply returns what looks like a JSON representation of a FileStreamResult.
When I try to get that to return properly to my client MVC application, it tells me that "_buffer" can't be directly set. Some error message to the effect that some of the properties being returned and thrown into an object are private and can't be accessed.
The aforementioned byte-array representation of the PDF, when translated to a base64 string, doesn't seem to have the same number of characters as the "_buffer" string returned in the JSON by a FileStreamResult. It's missing about 26k 'A's at the end.
Any ideas about how to get this PDF to return correctly? I can provide code if necessary, but there has to be some known way to return a PDF from a server-side Web API application to a client-side MVC application and display it as a web page in a browser.
P.S. I do know that the "client-side" application isn't technically on the client side. It will also be a server application, but that shouldn't matter in this case. Relative to the Web API server, my MVC application is "client-side".
Code
For getting pdf:
private System.Web.Mvc.ActionResult GetPDF()
{
int bufferSize = 100;
int startIndex = 0;
long retval;
byte[] buffer = new byte[bufferSize];
MemoryStream stream = new MemoryStream();
SqlCommand command;
SqlConnection sqlca;
SqlDataReader reader;
using (sqlca = new SqlConnection(CONNECTION_STRING))
{
command = new SqlCommand((LINQ_TO_GET_FILE).ToString(), sqlca);
sqlca.Open();
reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
try
{
while (reader.Read())
{
do
{
retval = reader.GetBytes(0, startIndex, buffer, 0, bufferSize);
stream.Write(buffer, 0, bufferSize);
startIndex += bufferSize;
} while (retval == bufferSize);
}
}
finally
{
reader.Close();
sqlca.Close();
}
}
stream.Position = 0;
System.Web.Mvc.FileStreamResult fsr = new System.Web.Mvc.FileStreamResult(stream, "application/pdf");
return fsr;
}
API Function that gets from GetPDF:
[AcceptVerbs("GET","POST")]
public System.Web.Mvc.ActionResult getPdf()
{
System.Web.Mvc.ActionResult retVal = GetPDF();
return retVal;
}
For displaying PDF server-side:
public ActionResult getChart()
{
return new PDFController().GetPDF();
}
The code in the MVC application has changed a lot over time. The way it is right now, it doesn't get to the stage where it tries to display in browser. It gets an error before that.
public async Task<ActionResult> get_pdf(args,keys)
{
JObject jObj;
StringBuilder argumentsSB = new StringBuilder();
if (args.Length != 0)
{
argumentsSB.Append("?");
argumentsSB.Append(keys[0]);
argumentsSB.Append("=");
argumentsSB.Append(args[0]);
for (int i = 1; i < args.Length; i += 1)
{
argumentsSB.Append("&");
argumentsSB.Append(keys[i]);
argumentsSB.Append("=");
argumentsSB.Append(args[i]);
}
}
else
{
argumentsSB.Append("");
}
var arguments = argumentsSB.ToString();
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(URL_OF_SERVER+"api/pdf/getPdf/" + arguments).ConfigureAwait(false);
jObj = (JObject)JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
}
return jObj.ToObject<ActionResult>();
}
The JSON I get from running the method directly from the Web API controller is:
{
"FileStream":{
"_buffer":"JVBER...NjdENEUxAA...AA==",
"_origin":0,
"_position":0,
"_length":45600,
"_capacity":65536,
"_expandable":true,
"_writable":true,
"_exposable":true,
"_isOpen":true,
"__identity":null},
"ContentType":"application/pdf",
"FileDownloadName":""
}
I shortened "_buffer" because it's ridiculously long.
I currently get the error message below on the return line of get_pdf(args,keys)
Exception Details: Newtonsoft.Json.JsonSerializationException: Could not create an instance of type System.Web.Mvc.ActionResult. Type is an interface or abstract class and cannot be instantiated. Path 'FileStream'.
Back when I used to get a blank pdf reader (the reader was blank. no file), I used this code:
public async Task<ActionResult> get_pdf(args,keys)
{
byte[] retArr;
StringBuilder argumentsSB = new StringBuilder();
if (args.Length != 0)
{
argumentsSB.Append("?");
argumentsSB.Append(keys[0]);
argumentsSB.Append("=");
argumentsSB.Append(args[0]);
for (int i = 1; i < args.Length; i += 1)
{
argumentsSB.Append("&");
argumentsSB.Append(keys[i]);
argumentsSB.Append("=");
argumentsSB.Append(args[i]);
}
}
else
{
argumentsSB.Append("");
}
var arguments = argumentsSB.ToString();
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/pdf"));
var response = await client.GetAsync(URL_OF_SERVER+"api/webservice/" + method + "/" + arguments).ConfigureAwait(false);
retArr = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
}
var x = retArr.Skip(1).Take(y.Length-2).ToArray();
/*Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "inline;filename=document.pdf");
Response.BufferOutput = true;
Response.BinaryWrite(x);
Response.Flush();
Response.End();*/
return new FileStreamResult(new MemoryStream(x),MediaTypeNames.Application.Pdf);
}
Commented out is code from some other attempts. When I was using that code, I was returning a byte array from the server. It looked like:
JVBER...NjdENEUx
Some Server side code to return PDF (Web Api).
[HttpGet]
[Route("documents/{docid}")]
public HttpResponseMessage Display(string docid) {
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest);
var documents = reader.GetDocument(docid);
if (documents != null && documents.Length == 1) {
var document = documents[0];
docid = document.docid;
byte[] buffer = new byte[0];
//generate pdf document
MemoryStream memoryStream = new MemoryStream();
MyPDFGenerator.New().PrintToStream(document, memoryStream);
//get buffer
buffer = memoryStream.ToArray();
//content length for use in header
var contentLength = buffer.Length;
//200
//successful
var statuscode = HttpStatusCode.OK;
response = Request.CreateResponse(statuscode);
response.Content = new StreamContent(new MemoryStream(buffer));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentLength = contentLength;
ContentDispositionHeaderValue contentDisposition = null;
if (ContentDispositionHeaderValue.TryParse("inline; filename=" + document.Name + ".pdf", out contentDisposition)) {
response.Content.Headers.ContentDisposition = contentDisposition;
}
} else {
var statuscode = HttpStatusCode.NotFound;
var message = String.Format("Unable to find resource. Resource \"{0}\" may not exist.", docid);
var responseData = responseDataFactory.CreateWithOnlyMetadata(statuscode, message);
response = Request.CreateResponse((HttpStatusCode)responseData.meta.code, responseData);
}
return response;
}
On my a View you could do something like this
<a href="api/documents/1234" target = "_blank" class = "btn btn-success" >View document</a>
which will call the web api and open the PDF document in a new tab in the browser.
Here is how i basically do the same thing but from a MVC controller
// NOTE: Original return type: FileContentResult, Changed to ActionResult to allow for error results
[Route("{docid}/Label")]
public ActionResult Label(Guid docid) {
var timestamp = DateTime.Now;
var shipment = objectFactory.Create<Document>();
if (docid!= Guid.Empty) {
var documents = reader.GetDocuments(docid);
if (documents.Length > 0)
document = documents[0];
MemoryStream memoryStream = new MemoryStream();
var printer = MyPDFGenerator.New();
printer.PrintToStream(document, memoryStream);
Response.AppendHeader("Content-Disposition", "inline; filename=" + timestamp.ToString("yyyyMMddHHmmss") + ".pdf");
return File(memoryStream.ToArray(), "application/pdf");
} else {
return this.RedirectToAction(c => c.Details(id));
}
}
return this.RedirectToAction(c => c.Index(null, null));
}
Hope this helps
I needed to return a pdf file from a .NET core 3.1 web api, and found this excellent article:
https://codeburst.io/download-files-using-web-api-ae1d1025f0a9
Basically, you call:
var bytes = await System.IO.File.ReadAllBytesAsync(pathFileName);
return File(bytes, "application/pdf", Path.GetFileName(pathFileName));
Whole code is:
using Microsoft.AspNetCore.Mvc;
using System.IO;
using Reportman.Drawing;
using Reportman.Reporting;
using System.Text;
using System.Threading.Tasks;
[Route("api/[controller]")]
[ApiController]
public class PdfController : ControllerBase
{
[HttpGet]
[Route("ot/{idOT}")]
public async Task<ActionResult> OT(string idOT)
{
Report rp = new Report();
rp.LoadFromFile("ot-net.rep"); // File created with Reportman designer
rp.ConvertToDotNet();
// FixReport
rp.AsyncExecution = false;
PrintOutPDF printpdf = new PrintOutPDF();
// Perform the conversion from one encoding to the other.
byte[] unicodeBytes = Encoding.Convert(Encoding.ASCII, Encoding.Unicode, Encoding.ASCII.GetBytes($"Orden de trabajo {idOT}"));
string unicodeString = new string(Encoding.Unicode.GetChars(unicodeBytes));
// todo: convert to unicode
// e = Encoding.GetEncoding(unicodeString);
// System.Diagnostics.Trace.WriteLine(e);
if (rp.Params.Count > 0)
{
rp.Params[0].Value = unicodeString;
}
printpdf.FileName = $"ot-{idOT}.pdf";
printpdf.Compressed = false;
if (printpdf.Print(rp.MetaFile))
{
// Download Files using Web API. Changhui Xu. https://codeburst.io/download-files-using-web-api-ae1d1025f0a9
var bytes = await System.IO.File.ReadAllBytesAsync(printpdf.FileName);
return File(bytes, "application/pdf", Path.GetFileName(printpdf.FileName));
}
return null;
}
Call to this API looks like: https://localhost:44387/api/pdf/ot/7
Reportman is a pdf generator you can found at:
https://reportman.sourceforge.io/
Enjoy!
I have been asked to do the following in C#:
/**
* 1. Create a MultipartPostMethod
* 2. Construct the web URL to connect to the SDP Server
* 3. Add the filename to be attached as a parameter to the MultipartPostMethod with parameter name "filename"
* 4. Execute the MultipartPostMethod
* 5. Receive and process the response as required
* /
I have written some code that has no errors, however, the file is not attached.
Can someone have a look at my C# code to see if I have written the code incorrectly?
Here is my code:
var client = new HttpClient();
const string weblinkUrl = "http://testserver.com/attach?";
var method = new MultipartFormDataContent();
const string fileName = "C:\file.txt";
var streamContent = new StreamContent(File.Open(fileName, FileMode.Open));
method.Add(streamContent, "filename");
var result = client.PostAsync(weblinkUrl, method);
MessageBox.Show(result.Result.ToString());
Posting MultipartFormDataContent in C# is simple but may be confusing the first time.
Here is the code that works for me when posting a .png .txt etc.
// 2. Create the url
string url = "https://myurl.com/api/...";
string filename = "myFile.png";
// In my case this is the JSON that will be returned from the post
string result = "";
// 1. Create a MultipartPostMethod
// "NKdKd9Yk" is the boundary parameter
using (var formContent = new MultipartFormDataContent("NKdKd9Yk"))
{
formContent.Headers.ContentType.MediaType = "multipart/form-data";
// 3. Add the filename C:\\... + fileName is the path your file
Stream fileStream = System.IO.File.OpenRead("C:\\Users\\username\\Pictures\\" + fileName);
formContent.Add(new StreamContent(fileStream), fileName, fileName);
using (var client = new HttpClient())
{
// Bearer Token header if needed
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _bearerToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
try
{
// 4.. Execute the MultipartPostMethod
var message = await client.PostAsync(url, formContent);
// 5.a Receive the response
result = await message.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
// Do what you want if it fails.
throw ex;
}
}
}
// 5.b Process the reponse Get a usable object from the JSON that is returned
MyObject myObject = JsonConvert.DeserializeObject<MyObject>(result);
In my case I need to do something with the object after it posts so I convert it to that object with JsonConvert.
I debugged this the problem is here:
method.Add(streamContent, "filename");
This 'Add' doesn't actually put the file in the BODY of Multipart Content.
I know this is an old post But to those searching for a solution, to provide a more direct answer, here's what I've found:
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFormData()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
Trace.WriteLine(file.Headers.ContentDisposition.FileName);
Trace.WriteLine("Server file path: " + file.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
Here's where I found it:
http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-2
For a more Elaborate implementation:
http://galratner.com/blogs/net/archive/2013/03/22/using-html-5-and-the-web-api-for-ajax-file-uploads-with-image-preview-and-a-progress-bar.aspx
Specify the third parameter which is a fileName.
Something like this:
method.Add(streamContent, "filename", "filename.pdf");