I wrote this code for show stream file in browser:
public IActionResult GetAvatar()
{
var id = httpContextAccessor.HttpContext.User.Identity.GetUserId<long>();
if (id > 0)
{
var user = dispatchers.QueryAsync(new GetUserByIdQuery { id = id }).Result;
if (user.Success)
{
return PhysicalFile(Path.Combine(this.finder.PathAvatarUserUploadFolder(), user.Result.Photo), "application/octet-stream");
}
return BadRequest(user.ErrorMessage);
}
return BadRequest("Id not valid");
}
this line : return PhysicalFile(Path.Combine(this.finder.PathAvatarUserUploadFolder(), user.Result.Photo), "application/octet-stream");
But it have problem because when I enter the url in the browser, it downloads the file and it must go to downloads and open that file.
I need to open file in the browser. How can i solve this problem?
When you check the response headers using Chrome Developer tools or Fiddler, what is your Content-Disposition header set to? If its set to attachment the browser will always download the file. You can set the Content-Disposition to inline to tell browser to show the content inline if possible and offer download if it can't show content inline. This header can be set in different ways, but the simplest would be adding a header right before returning the file contents like below.
Response.Headers["Content-Disposition"] = $"inline; filename={user.Result.Photo}";
return PhysicalFile(Path.Combine(this.finder.PathAvatarUserUploadFolder(), user.Result.Photo), "application/octet-stream");
Related
I'm following this blog post to upload an image using C# Web API.
The article explains how to do it using ARC and it works fine.
But when I'm trying to do the same using POSTMAN it's failing.
Here is my request snapshot.
TL;DR: You are doing everything correct except that you are setting the Content-Type header explicitly in the tool. Get rid of the header and your issue will be resolved.
Detailed Explanation: To begin with, you attach the files using form-data option in the Body tab in the tool:
The moment you select the file(s), Postman auto-detects the Content-Type. Then behind the scenes, Postman inserts the automatically detected Content-Type into the POST request without us knowing it. So setting up Content-Type header explicitly on our own messes up the request.
Setting the value of Content-Type header to multipart/form-data involves a complex concept of setting up boundaries of multiple parts of the file as detailed here. It can be error-prone. So heavy lifting of setting up the boundaries is done automatically for us by the tool itself. This is the reason why it doesn't expect us to set the content-type header explicitly in this case. Please see how I've set only Authorization header while uploading the image file on my PC (Refer screenshot):
Authorization header is an optional header. It is required only if you've setup some sort of authentication on the web server. So if anonymous access is allowed on your website then Headers tab in your case should be empty i.e. no key value pairs at all.
Note: Just for information, the correct content type for image files in a POST request is multipart/form-data even though we don't need to set it explicitly in the tool. Screenshot in the question shows that Content-Type header is being set as application/x-www-form-urlencoded which is not right.
In the post you referrer to the data is being uploaded as "x-www-form-url-encoded"
Your Postman screen shot shows you are uploading it as "form-data"
Additionally, you adding a key "image01" where the ARC example doesn't appear to be sending a key.
If you want to upload the file using form-data you need a different approach:
// POST api/files
public async Task<HttpResponseMessage> Post()
{
// 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);
string value;
try
{
// Read the form data and return an async data.
var result = await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
// return multiple value from FormData
if (key == "value")
value = val;
}
}
if (result.FileData.Any())
{
// This illustrates how to get the file names for uploaded files.
foreach (var file in result.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
if (fileInfo.Exists)
{
//do somthing with file
}
}
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, value);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = files.Id }));
return response;
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
I am sending an excel file with some data to insert in database.
For each line I have to validate the data, if the row has invalid data I must return the file with only invalid rows.
The download, reading and returning are working fine, but when I return the file containing the invalid values, I must update the modal by writing a text that tells the user that the downloaded file contains the rows with invalid data, so the user can rewrite and send back.
I am sending file by submiting and form, and receaving in the Action this way:
public ActionResult LoadData(HttpPostedFileBase _file)
and returning this way:
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename= Colabs.xlsx");
using (var stream = new MemoryStream())
{
xlWorkbookFile.SaveAs(stream);
stream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
When you send content-disposition header with value as an attachment, that means browser treat that as downloaded file. The UI is never updated with that response
You can refer: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
To solve your issue, you should return your action result with Model(do not respond with the file), and in your view keep one hidden iframe pointing to that downloadable file(or URL of separate action which sends the file).
The solution I founded was:
Before submit, create an Interval that searches for a cookie that will be created in controller;
You will store the extra data in cookies, and read them in javascript;
Creating cookie in controller:
Response.AppendCookie(new HttpCookie("someDataCookieName", dataValue));
In JS, check for the values:
function CheckForValues() {
intervalId = window.setInterval(function () {
var cookieValue = $.cookie('someDataCookieName');
if (cookieValue == token) {
alert(cookieValue)
} else if (stopInterval) {
clearInterval(intervalId );
stopInterval = false;
}
}, 1000);
}
You can create your own condition for stop if any error occours.
Consider a UserGuide PDF file that must provide help for website users.
Here is the link to it in view :
#Html.ActionLink("User Guide","Help","Portal")
the controller that returns the file :
public ActionResult Help()
{
string path = Server.MapPath("~/Content/UserGuide.pdf");
var fileBytes = System.IO.File.ReadAllBytes(path);
var responseFile = new FileContentResult(fileBytes, "application/pdf")
{
FileDownloadName = "Guide.pdf"
};
return responseFile;
}
but here, after user clicks the link, browser will prompt for downloading the file but the better way is, when user clicks the link, PDF pages show up inside browser. Just like a web page! can any body mention the best way to achieve this?
Looks like you need to return a FileStreamResult e.g.
Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")
From SO here
or you can try FileResult e.g.
return File(fileArray, contentType, fileName)
From SO here
I send a request via ajax and if response data success is true, I make a GET request in ajax success function:
success: function (data, status) {
if (!data["Success"]) {
alert("Error occurred: Cant read data properly," + data["Message"]);
return null;
}
window.location = '/Home/downloadanddelete?file=output.' + data["filetype"];
The problem is when Get request posted to controller the response is:
As you see the file request url is:"http://localhost:53091/Home/downloadanddelete?file=output.xml"
And I expect download this "output.xml" file and return the referrer page url.
here is download method in controller:
[HttpGet]
public ActionResult downloadanddelete(string file)
{
string fullName = Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data", file);
if (System.IO.File.Exists(fullName))
{
return File(fullName, "application/xml");
}
return View("Index");
}
What is it wrong here?
You'll need to change two things. In the server code, you need to send a Content-Disposition header to indicate the content is an "attachment". Add these lines before sending the file:
var cd = new System.Net.Mime.ContentDisposition
{
FileName = "filename.xml",
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
Secondly, you ought to use window.location.assign(...); instead of setting window.location for a more seemless experience in the browser.
You can use the Header type "Content-Disposition" to tell the browser to preferably download and save the file, instead of displaying it. There is some information on it here: https://stackoverflow.com/a/20509354/1862405
For your specific case, you'd want to use the attachment disposition, which you can add to your controller action with AddHeader:
HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=\"download.xml\"");
Another thing is that Firefox might overrule this, but you can set up for file types how it should handle them.
i faced an issue with downloading file from website.
A user can fill in the textbox (example: hello.html) and then click on a button to download the html file. Now my issue is: even the file "hello.html" is not exists, my code will tend to download it as well. There will be "index.html" file appears in folder. How do I write "if" statement so that I can tell the code not to download if the file is not exist?
My code:
if (FILE NOT EXIST ON THE WEBSITE)
{
//MessageBox.Show("There is no such file on the website. Please check your spelling.");
}
else
{
client.DownloadFile("http://example.com/" + txtbox.Text.ToUpper().ToString(),
sourceDir + txtbox.Text.ToUpper().ToString() + ".html");
}
Thank you so much.
System.IO.File.Exists(fpath) returns false in Chrome and Firefox
if (File.Exists(fileLocation))
{
// Download File!
}
That problem is specific for uploading but its the same concept.
OR:
Taken Directly from: http://www.dotnetthoughts.net/how-to-check-remote-file-exists-using-c/
Add this method to your class.
private bool RemoteFileExists(string url)
{
try
{
//Creating the HttpWebRequest
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
//Setting the Request method HEAD, you can also use GET too.
request.Method = "HEAD";
//Getting the Web Response.
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//Returns TURE if the Status code == 200
return (response.StatusCode == HttpStatusCode.OK);
}
catch
{
//Any exception will returns false.
return false;
}
}
Then when you want to check if a file exists at a url use this:
if (RemoteFileExists("http://blog.stackoverflow.com/wp-content/uploads/stackoverflow-logo-300.png")
{
//File Exists
}
else
{
//File does not Exist
}