Get a black/no image with asp.net web api - c#

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

Related

InvalidOperationException in Memory Streams

I am trying to upload an image to cloudinary cloud. The file converts fine to memory stream but when I try to call upload method of cloudinary to upload the image, I get InvlalidOperationException. What I think is, there is something wrong with converting file to stream.See the image showing error
[HttpPost]
public async Task<IActionResult> AddPhotoForUser(int userId, [FromForm] AddPhotoDto addPhotoDto)
{
try
{
if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
{
return Unauthorized();
}
var userFromRepo = await _datingRepository.GetUser(userId);
var file = addPhotoDto.File;
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var stream = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(file.Name, stream),
Transformation = new Transformation()
.Width(500).Height(500).Crop("fill").Gravity("face")
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
addPhotoDto.Url = uploadResult.Url.ToString();
addPhotoDto.PublicId = uploadResult.PublicId;
var photo = _mapper.Map<Photo>(addPhotoDto);
if (!userFromRepo.Photos.Any(p => p.IsMain))
{
photo.IsMain = true;
}
userFromRepo.Photos.Add(photo);
if (await _datingRepository.SaveAll())
{
var photoToReturn = _mapper.Map<ReturnPhotoDto>(photo);
return CreatedAtRoute("GetPhoto", new { id = photo.Id }, photoToReturn);
}
return BadRequest("Could not add photo");
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
Can you please share why do you use open stream? You can try:
var imageuploadParams = new ImageUploadParams () {
File = new FileDescription (#"https://res.cloudinary.com/demo/image/upload/v1561532539/sample.jpg"),
PublicId = "myimage",
Transformation = new Transformation().Width(500).Height(500).Crop("fill").Gravity("face")
};
var ImageuploadResult = cloudinary.Upload (imageuploadParams);

Cannot access disposed object application connecting to WebAPI

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

How do I detect canceled asynchronous post

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);
}
}

Pass the value to database in asp.net web api

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.

WCF Streaming File Transfer ON .NET 4

I need a good example on WCF Streaming File Transfer.
I have found several and tried them but the posts are old and I am wokding on .net 4 and IIS 7 so there are some problems.
Can you gives me a good and up-to-date example on that.
The following answers detail using a few techniques for a posting binary data to a restful service.
Post binary data to a RESTful application
What is a good way to transfer binary data to a HTTP REST API service?
Bad idea to transfer large payload using web services?
The following code is a sample of how you could write a RESTful WCF service and is by no means complete but does give you an indication on where you could start.
Sample Service, note that this is NOT production ready code.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class FileService
{
private IncomingWebRequestContext m_Request;
private OutgoingWebResponseContext m_Response;
[WebGet(UriTemplate = "{appName}/{id}?action={action}")]
public Stream GetFile(string appName, string id, string action)
{
var repository = new FileRepository();
var response = WebOperationContext.Current.OutgoingResponse;
var result = repository.GetById(int.Parse(id));
if (action != null && action.Equals("download", StringComparison.InvariantCultureIgnoreCase))
{
response.Headers.Add("Content-Disposition", string.Format("attachment; filename={0}", result.Name));
}
response.Headers.Add(HttpResponseHeader.ContentType, result.ContentType);
response.Headers.Add("X-Filename", result.Name);
return result.Content;
}
[WebInvoke(UriTemplate = "{appName}", Method = "POST")]
public void Save(string appName, Stream fileContent)
{
try
{
if (WebOperationContext.Current == null) throw new InvalidOperationException("WebOperationContext is null.");
m_Request = WebOperationContext.Current.IncomingRequest;
m_Response = WebOperationContext.Current.OutgoingResponse;
var file = CreateFileResource(fileContent, appName);
if (!FileIsValid(file)) throw new WebFaultException(HttpStatusCode.BadRequest);
SaveFile(file);
SetStatusAsCreated(file);
}
catch (Exception ex)
{
if (ex.GetType() == typeof(WebFaultException)) throw;
if (ex.GetType().IsGenericType && ex.GetType().GetGenericTypeDefinition() == typeof(WebFaultException<>)) throw;
throw new WebFaultException<string>("An unexpected error occurred.", HttpStatusCode.InternalServerError);
}
}
private FileResource CreateFileResource(Stream fileContent, string appName)
{
var result = new FileResource();
fileContent.CopyTo(result.Content);
result.ApplicationName = appName;
result.Name = m_Request.Headers["X-Filename"];
result.Location = #"C:\SomeFolder\" + result.Name;
result.ContentType = m_Request.Headers[HttpRequestHeader.ContentType] ?? this.GetContentType(result.Name);
result.DateUploaded = DateTime.Now;
return result;
}
private string GetContentType(string filename)
{
// this should be replaced with some form of logic to determine the correct file content type (I.E., use registry, extension, xml file, etc.,)
return "application/octet-stream";
}
private bool FileIsValid(FileResource file)
{
var validator = new FileResourceValidator();
var clientHash = m_Request.Headers[HttpRequestHeader.ContentMd5];
return validator.IsValid(file, clientHash);
}
private void SaveFile(FileResource file)
{
// This will persist the meta data about the file to a database (I.E., size, filename, file location, etc)
new FileRepository().AddFile(file);
}
private void SetStatusAsCreated(FileResource file)
{
var location = new Uri(m_Request.UriTemplateMatch.RequestUri.AbsoluteUri + "/" + file.Id);
m_Response.SetStatusAsCreated(location);
}
}
Sample Client, note that this is NOT production ready code.
// *********************************
// Sample Client
// *********************************
private void UploadButton_Click(object sender, EventArgs e)
{
var uri = "http://dev-fileservice/SampleApplication"
var fullFilename = #"C:\somefile.txt";
var fileContent = File.ReadAllBytes(fullFilename);
using (var webClient = new WebClient())
{
try
{
webClient.Proxy = null;
webClient.Headers.Add(HttpRequestHeader.ContentMd5, this.CalculateFileHash());
webClient.Headers.Add("X-DaysToKeep", DurationNumericUpDown.Value.ToString());
webClient.Headers.Add("X-Filename", Path.GetFileName(fullFilename));
webClient.UploadData(uri, "POST", fileContent);
var fileUri = webClient.ResponseHeaders[HttpResponseHeader.Location];
Console.WriteLine("File can be downloaded at" + fileUri);
}
catch (Exception ex)
{
var exception = ex.Message;
}
}
}
private string CalculateFileHash()
{
var hash = MD5.Create().ComputeHash(File.ReadAllBytes(#"C:\somefile.txt"));
var sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString();
}
private void DownloadFile()
{
var uri = "http://dev-fileservice/SampleApplication/1" // this is the URL returned by the Restful file service
using (var webClient = new WebClient())
{
try
{
webClient.Proxy = null;
var fileContent = webClient.DownloadData(uri);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

Categories