I use the following code to upload a file and form data asynchronous. What do I need to change in order to detect if the transfer has been cancelled or interrupted and then take proper action?
[HttpPost]
public async Task<object> UploadFile()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
}
var streamProvider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data/Temp/"));
try
{
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync(streamProvider);
var paramName = "formInput";
var formStreamToRead = filesReadToProvider.Contents.First(x => x.Headers.ContentDisposition.Name == $"\"{formInput}\"");
var formInput = await formStreamToRead.ReadAsStringAsync();
foreach (var fileData in streamProvider.FileData)
{
var fileName = "";
if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
{
fileName = Guid.NewGuid().ToString();
}
fileName = fileData.Headers.ContentDisposition.FileName;
if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(#"/") || fileName.Contains(#"\"))
{
fileName = Path.GetFileName(fileName);
}
File.Move(fileData.LocalFileName, Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), Path.GetDirectoryName(fileName) + Guid.NewGuid() + Path.GetExtension(fileName)));
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
Related
I have content of video and object being created an pass into a http client web api. When ever I pass the image to the client it works find it gets to the post method, but when it comes to the video the client has trouble posting the video. I checked the video size length to make sure it meets the content length and it well under the specific ranges. The error that I receive is that the object has been disposed. If you look at the code the object is never disposed.
Here's the code on the app
public async Task<bool> AddToQueueAsync(Incident i, ContentPage page, MediaFile file)
{
HttpResponseMessage result = null;
Uri webserviceURL = i.IncidentType == IncidentType.Trooper ? trooperURL : gspURL;
var fileStream = File.Open(file.Path, FileMode.Open);
try
{
using (var client = new HttpClient())
{
using (fileStream)
{
using (var stream = new StreamContent(fileStream))
{
using (var content = new MultipartFormDataContent("----MyBoundary"))
{
if(i.MediaType == "Video")
{
content.Add(stream,"file", Guid.NewGuid().ToString() + ".mp4");
}
else
{
content.Add(stream, "file", Guid.NewGuid().ToString() + ".png");
}
content.Add(new StringContent(JsonConvert.SerializeObject(i)), "metadata");
result = await client.PostAsync(webserviceURL, content);
}
}
}
}
Here is the code on the web api:
[HttpPost]
public IHttpActionResult StarGSPDATA() {
try {
if(!Request.Content.IsMimeMultipartContent()) {
Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
starGSPDATAinfo suspicousInfo;
string homeDir = AppDomain.CurrentDomain.BaseDirectory;
string dir = $"{homeDir}/uploads/";
Directory.CreateDirectory(dir);
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
if(HttpContext.Current.Request.Form.Count > 0) {
suspicousInfo = MetaDataFromRequest(HttpContext.Current.Request.Form);
} else {
suspicousInfo = new starGSPDATAinfo();
}
if(file != null && file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(dir, fileName);
suspicousInfo.MediaFilePath = fileName;
try {
file.SaveAs(path);
} catch(Exception e) {
Console.WriteLine($"not saving: {e.ToString()}");
}
} else {
throw new HttpResponseException(
new HttpResponseMessage(
HttpStatusCode.NoContent));
}
CleanData(suspicousInfo);
db.starGSPDATAinfoes.Add(suspicousInfo);
db.SaveChanges();
return Created("http://localhost:50641/api/StarGSPDATA/", JsonConvert.SerializeObject(suspicousInfo));
} catch(Exception e) {
return InternalServerError(e);
}
}
It works for an image but not for a video Please help thank you!
Here is a picture of the error
I have a list of reports page. I have a download button for each report. If I click 4-5 reports download button I only get the last one downloaded. Below you can see my code
public async Task<ActionResult> Download(ReportPage currentPage, string id)
{
var token = RystadIdentity.Current.AuthenticatedUser.Token;
try
{
DocumentRequestInput documentRequestInput = new DocumentRequestInput(int.Parse(id), 2);
documentRequestInput.Add(token);
}
catch
{ }
Report report = await RystadGlobal.api.GetReport(token, int.Parse(id));
string ext = Path.GetExtension(report.fileName);
byte[] byteArray = await RystadGlobal.api.DownloadReport(token, report.Id);
if (ext.ToLower() == ".pdf")
{
var name = RystadIdentity.Current.AuthenticatedUser.UserInfo.name;
var company = RystadIdentity.Current.AuthenticatedUser.UserInfo.company;
try
{
byteArray = PdfWatermarker.Watermark(byteArray, name, company);
}
catch (Exception ex)
{
//Ignore if failed and give the user the pdf anyway
}
}
return File(byteArray, System.Net.Mime.MediaTypeNames.Application.Octet, report.fileName);
}
public async Task<byte[]> DownloadReport(Token token, int reportId)
{
clientForDownloading.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
var result = await clientForDownloading.GetAsync("api/" + ApiVersion + "/LibraryDocument/" + reportId + "/download");
if (!result.IsSuccessStatusCode)
throw new ApiException("Could not download the report");
var contentBytes = await result.Content.ReadAsByteArrayAsync();
return SevenZipHelper.Decompress(contentBytes);
}
public async Task<Report> GetReport(Token token, int reportId)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
var result = await client.GetAsync("api/" + ApiVersion + "/LibraryDocument/" + reportId);
if (!result.IsSuccessStatusCode)
throw new ApiException("Could not get report");
Report report = await result.Content.ReadAsAsync<Report>();
return report;
}
Does anyone see the issue which I am missing?
You can try to do it Synchronously like so:
public ActionResult Download(ReportPage currentPage, string id)
{
var token = RystadIdentity.Current.AuthenticatedUser.Token;
try
{
DocumentRequestInput documentRequestInput = new DocumentRequestInput(int.Parse(id), 2);
documentRequestInput.Add(token);
}
catch
{ }
Report report = RystadGlobal.api.GetReport(token, int.Parse(id)).Result;
string ext = Path.GetExtension(report.fileName);
byte[] byteArray = RystadGlobal.api.DownloadReport(token, report.Id).Result;
if (ext.ToLower() == ".pdf")
{
var name = RystadIdentity.Current.AuthenticatedUser.UserInfo.name;
var company = RystadIdentity.Current.AuthenticatedUser.UserInfo.company;
try
{
byteArray = PdfWatermarker.Watermark(byteArray, name, company);
}
catch (Exception ex)
{
//Ignore if failed and give the user the pdf anyway
}
}
return File(byteArray, System.Net.Mime.MediaTypeNames.Application.Octet, report.fileName);
}
The other problem might be in this method:
RystadGlobal.api.GetReport(token, int.Parse(id))
I do not know that this method looks like inside
EDIT
Try creating new instances of your clients in the methods you added in your question:
public async Task<byte[]> DownloadReport(Token token, int reportId)
{
using(var clientForDL = new System.Net.Http.HttpClient())
{
clientForDL.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
var result = await clientForDL.GetAsync("api/" + ApiVersion + "/LibraryDocument/" + reportId + "/download");
if (!result.IsSuccessStatusCode)
throw new ApiException("Could not download the report");
var contentBytes = await result.Content.ReadAsByteArrayAsync();
return SevenZipHelper.Decompress(contentBytes);
}
}
public async Task<Report> GetReport(Token token, int reportId)
{
using(var clientForGet = new System.Net.Http.HttpClient())
{
clientForGet.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
var result = await clientForGet.GetAsync("api/" + ApiVersion + "/LibraryDocument/" + reportId);
if (!result.IsSuccessStatusCode)
throw new ApiException("Could not get report");
Report report = await result.Content.ReadAsAsync<Report>();
return report;
}
}
Am trying to save the images to the database using the asp.net webapi. In this controller am saving the image into my /Content/Banner/ Folder.
[HttpPost]
[Route("PostBanner")]
[AllowAnonymous]
public HttpResponseMessage PostBannerImage()
{
Dictionary<string, object> dict = new Dictionary<string, object>();
try
{
var httpRequest = HttpContext.Current.Request;
foreach (string file in httpRequest.Files)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);
var postedFile = httpRequest.Files[file];
if (postedFile != null && postedFile.ContentLength > 0)
{
int MaxContentLength = 1024 * 1024 * 1; //Size = 1 MB
IList<string> AllowedFileExtensions = new List<string> { ".jpg", ".gif", ".png" };
var ext = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf('.'));
var extension = ext.ToLower();
if (!AllowedFileExtensions.Contains(extension))
{
var message = string.Format("Please Upload image of type .jpg,.gif,.png.");
dict.Add("error", message);
return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
}
else if (postedFile.ContentLength > MaxContentLength)
{
var message = string.Format("Please Upload a file upto 1 mb.");
dict.Add("error", message);
return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
}
else
{
var filePath = HttpContext.Current.Server.MapPath("~/Content/Banner/" + postedFile.FileName + extension);
postedFile.SaveAs(filePath);
}
}
var message1 = string.Format("Image Updated Successfully.");
return Request.CreateErrorResponse(HttpStatusCode.Created, message1); ;
}
var res = string.Format("Please Upload a image.");
dict.Add("error", res);
return Request.CreateResponse(HttpStatusCode.NotFound, dict);
}
catch (Exception ex)
{
var res = string.Format("some Message");
dict.Add("error", res);
return Request.CreateResponse(HttpStatusCode.NotFound, dict);
}
}
Now what i need to send this filePath to database. I know i just need to pass this file path to the following service controller. But i dont know how to pass it. could anyone help me to solve this problem.
This Is my services.cs
public async Task<int?> Addbanner(DisplayBannersDto dto)
{
try
{
var d = _dbContext.Banners
.FirstOrDefault();
d.Banner_Description = dto.Description;
d.Banner_Location = dto.Location;
//mark entry as modifed
_dbContext.Entry(d).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
return d.Banner_Id;
}
catch (Exception ex)
{
throw ex;
}
}
This is my controller
[HttpPost]
[Route("AddBanner")]
public async Task<IHttpActionResult> AddBanner(DisplayBannersDto dto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
int? result = await _service.Addbanner(dto);
return Ok();
}
Change your else condition like below:
else
{
var filePath = HttpContext.Current.Server.MapPath("~/Content/Banner/" + postedFile.FileName + extension);
postedFile.SaveAs(filePath);
return new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Created,
Content = new StringContent(filePath, Encoding.UTF8, "application/json")
};
}
Now, you have the filepath in the content of the API response.
and use that response like :
var displayBannersDto = new DisplayBannersDto();
displayBannersDto.Banner_Location = response.Content.ToString();
then call your AddBanner() API with displayBannersDto as the dto.
I am working on Windows 10 UWP app and my requirement is to upload 5 images on the server with unique value. So, I have used System.Threading.Tasks.Task.Factory.StartNew().Now, when I checked while debugging, I found that randomly sometimes for 2 images, it sends same unique key. Can someone suggest is it better to use System.Threading.Tasks.Task.Factory.StartNew()?
All the images are sent using a web service. My sample code for this is following
WebServiceUtility serviceUtility = new WebServiceUtility();
List<System.Threading.Tasks.Task> tasks = new List<System.Threading.Tasks.Task>();
var cancelSource = new CancellationTokenSource();
cancellationToken = cancelSource.Token;
System.Threading.Tasks.Task currentTask = null;
List<System.Threading.Tasks.Task> uploadTasks = new List<System.Threading.Tasks.Task>();
List<string> uploadedImageIdList = new List<string>();
foreach (var image in _imageCollection)
{
if (!cancellationToken.IsCancellationRequested)
{
currentTask = await System.Threading.Tasks.Task.Factory.StartNew(async () =>
{
string imageName = string.Empty;
string imagePath = string.Empty;
if (image.IsEvidenceImage)
{
imageName = image.EvidencePath.Split('\\')[1];
imagePath = image.EvidencePath;
}
else
{
imageName = image.EvidencePath.Split('#')[1].Split('\\')[1];
imagePath = image.EvidencePath.Split('#')[1];
}
byte[] _imageAsByteArray = await GetEvidenceFromIsoStore(imagePath);
if (null != _imageAsByteArray && _imageAsByteArray.Length > 0)
{
IRestResponse response = await serviceUtility.UploadImage
(_imageAsByteArray, imageName,
new RequestDataGenerator().generateRequestDataForMediaUpload(
(null != _imageItem.I_IS_PRIMARY && "1".Equals(_imageItem.I_IS_PRIMARY) ? "1" : "0"),
evidenceName
));
if (response != null && response.RawBytes.Length > 0)
{
var successMessage = MCSExtensions.CheckWebserviceResponseCode(response.StatusCode);
if (successMessage.Equals(Constants.STATUS_CODE_SUCCESS))
{
byte[] decryptedevidenceresponse = WebserviceED.finaldecryptedresponse(response.RawBytes);
string responseString = Encoding.UTF8.GetString(decryptedevidenceresponse, 0, decryptedevidenceresponse.Length);
JObject reponseObject = JObject.Parse(responseString);
//Debug.WriteLine("Evidence Upload Response : " + Environment.NewLine);
uploadedimageIdList.Add(reponseObject["P_RET_ID"].ToString());
try
{
if (image.IsEvidenceImage)
{
if (await FileExists(image.EvidencePath))
{
StorageFile file = await localFolder.GetFileAsync(image.EvidencePath);
await file.DeleteAsync();
}
}
else
{
string[] evidenceMedia = image.EvidencePath.Split('#');
foreach (string evidenceItem in evidenceMedia)
{
if (await FileExists(evidenceItem))
{
StorageFile file = await localFolder.GetFileAsync(evidenceItem);
await file.DeleteAsync();
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
else
{
UserMessageUtil.ShowMessage(successMessage);
}
}
}
}, cancellationToken);
uploadTasks.Add(currentTask);
}
}
await System.Threading.Tasks.Task.WhenAll(uploadTasks.ToArray());
Just make it a separate method:
...
foreach (var image in _imageCollection)
{
if (!cancellationToken.IsCancellationRequested)
{
currentTask = UploadAsync(...);
uploadTasks.Add(currentTask);
}
}
await Task.WhenAll(uploadTasks);
async Task UploadAsync(...)
{
string imageName = string.Empty;
string imagePath = string.Empty;
...
}
Or, a bit more simply at the call site:
...
var uploadTasks = _imageCollection.Select(x => UploadAsync(...));
await Task.WhenAll(uploadTasks);
I'am posting an image from a console application to a asp.net web api. I'am getting a file in the folder but the image is black (no image). Do I have something wrong in my code?
public class UploadController : ApiController
{
[System.Web.Mvc.HttpPost]
public string Upload()
{
var request = HttpContext.Current.Request;
var filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Uploads/"), request.Headers["filename"]);
try
{
using (var fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
{
request.InputStream.CopyTo(fs);
}
}
catch (Exception e)
{
return e.Message;
}
return "uploaded";
}
}
Edit
My console app
http://pastebin.com/VsnDMYpb
try this. This works for me. I used this for multiple file upload
var httpRequest = HttpContext.Current.Request;
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/Uploads/" + postedFile.FileName);
postedFile.SaveAs(filePath);
}
Use Request.Content.ReadAsMultipartAsync
public Task<IQueryable<HDFile>> Post()
{
try
{
var uploadFolderPath = HostingEnvironment.MapPath("~/App_Data/" + UploadFolder);
log.Debug(uploadFolderPath);
if (Request.Content.IsMimeMultipartContent())
{
var streamProvider = new WithExtensionMultipartFormDataStreamProvider(uploadFolderPath);
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<IQueryable<HDFile>>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
var fileInfo = streamProvider.FileData.Select(i =>
{
var info = new FileInfo(i.LocalFileName);
return new HDFile(info.Name, Request.RequestUri.AbsoluteUri + "?filename=" + info.Name, (info.Length / 1024).ToString());
});
return fileInfo.AsQueryable();
});
return task;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
catch (Exception ex)
{
log.Error(ex);
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message));
}
}
The code I get from this post