I have some html files in another directory with some javascripts, images and css. I want to use that files in my site and restrict users to access that index.html link. I used return File method in my controller action but it couldn't open images on that directory so it didn't work. What is the proper solution?Do you have an idea?
ps. (when i debugged code, i saw that js, css and html files could open with proper mime types except jpg or png files)
public ActionResult User(string name)
{
string file = (Server.MapPath(Url.Content("~/Content/Users/" + name)));
string path = Path.Combine(file);
string mime = GetMimeType(path);
return File(path, mime);
}
public string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
{
mimeType = regKey.GetValue("Content Type").ToString();
}
return mimeType;
}
Better just qyery the IIS for static content mime types. That way you have a single location where to administer them.
using Microsoft.Web.Administration;
//--- stuff goes on ---//
ServerManager serverManager = new ServerManager();
var config = serverManager.GetApplicationHostConfiguration();
var staticContent = config.GetSection("system.webServer/staticContent");
var mimeMap = staticContent.GetCollection();
var mType =mimeMap.FirstOrDefault(a => (string) a.Attributes["fileExtension"].Value == ".pdf");
return (mType == null) ? "text/plain" : mType["mimeType"];
Make sure that during the debugging process the following values are returned to the image extensions:
.jpg/.jpeg => mime type: image/jpeg,
.png => mime type:image/png
You can use an xml file where each file extension is mapped to its mime type. This will make sure that your system could handle all of the possible extensions. This link has a suggested xml file
Related
I am using an Azure Function that has a HTTP trigger with a route parameter {id} which is the fileId of the JSON file I want to read.
I am using a Blob Input Binding to bind where my JSON files are stored. The JSON files are stored in a container called "conversations" and then in a folder called "Conversation".
An example of a file route is "https://<STORAGE_ACCOUNT_NAME>/conversations/Conversation/8da3d7ad3e35273-1aWpKU4rVghHiTaYkjOjVC-eu%7C0000000.json"
Below is my code.
public static class GetConvo
{
[FunctionName("GetConvo")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "getConvo/{id}")] HttpRequest req,
[Blob("conversations/{id}", FileAccess.Read, Connection = "AzureWebJobsStorage")] string json,
ILogger log, string id)
{
log.LogInformation($"File name: {id}");
if (json == null)
{
log.LogInformation($"File {id} not found");
return new NotFoundResult();
}
else
{
log.LogInformation($"Content: {json}");
}
return new OkObjectResult(JsonConvert.DeserializeObject<Message>(json));
The above code works if I move a JSON file to outside the "Conversation" folder, I can access it and receive a 200OK code.
I have tried changing the Blob input binding path to "conversations/Conversation/{id}" as below but that returns a 404 code.
[FunctionName("GetConvo")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "getConvo/{id}")] HttpRequest req,
[Blob("conversations/Conversation/{id}", FileAccess.Read, Connection = "AzureWebJobsStorage")] string json,
ILogger log, string id)
Is this a blob input path problem?
How would I read JSON files that are in a folder in a blob container using an azure function?
#AjgB, yes the Blob path is incorrect. You need to provide the file extension.
Lets say the file is placed directly in your 'conversations' folder. Then your BLOB input bindings should be -
[Blob("conversations/{id}.json", FileAccess.Read, Connection = "AzureWebJobsStorage")] string json
Note the .json in the blob path
I found out what my error was.
The blob input path was correct. It was a URL encoding problem for:
https://<STORAGE_ACCOUNT_NAME>/conversations/Conversation/8da3d7ad3e35273-1aWpKU4rVghHiTaYkjOjVC-eu%7C0000000.json
The % was not recognised and required; putting 25 after the % resolved this error:
https://<STORAGE_ACCOUNT_NAME>/conversations/Conversation/8da3d7ad3e35273-1aWpKU4rVghHiTaYkjOjVC-eu%257C0000000.json
Sending a POST request (Apache httpclient, here Kotlin source code):
val httpPost = HttpPost("http://localhost:8000")
val builder = MultipartEntityBuilder.create()
builder.addBinaryBody("file", File("testFile.zip"),
ContentType.APPLICATION_OCTET_STREAM, "file.ext")
val multipart = builder.build()
httpPost.entity = multipart
val r = httpClient.execute(httpPost)
r.close()
I receive the request in my post handler as a via spark-java Request-object. How do I retrieve the original file (plus the file name as a bonus) from the post request? The request.bodyAsBytes() method seems to add some bytes because the body is larger than the original file.
Thanks, Jörg
Near the bottom of Spark's Documentation page there is a section "Examples and FAQ". The first example is "How do I upload something?".
From there, it links further to an example on GitHub.
In short:
post("/yourUploadPath", (request, response) -> {
request.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("/temp"));
try (InputStream is = request.raw().getPart("file").getInputStream()) {
// Use the input stream to create a file
}
return "File uploaded";
});
To access the original file name:
request.raw().getPart("file").getSubmittedFileName()
To handle multiple files or parts, I usually have code similar to the following (assuming only files are included in the multi-part encoded upload):
for (Part part : req.raw().getParts()) {
try (InputStream stream = part.getInputStream()) {
String filename = part.getSubmittedFileName();
// save the input stream to the filesystem, and the filename to a database
}
}
User will upload .htm file and that uploaded file i have to convert to .jsp .
User will give me plain html file only with design and required fields. When he will upload I have to parse ans copy all html content also i have to add additional scripts and jstl code in jsp file. Is there any easy way to do this.
Thanks in advance
Handle it through file extension through servlet.
private String extractFileName(Part part) {
String contentDisp = part.getHeader("content-disposition");
String[] items = contentDisp.split(";");
for (String s : items) {
if (s.trim().startsWith("filename")) {
String cccfileName = s.substring(s.indexOf("=") + 2, s.length() - 1);
return cccfileName.substring(cccfileName.lastIndexOf("."), cccfileName.length());
}
}
return "";
}
Use it like String fileNameExt = extractFileName(part); and change the file extension to .jsp, it should work.
I have a Silverlight application that uses Web API to upload a document that is stored in a Database as a Filestream. Currently it's done by a POST with a Content-Type: application/json. The object containing a byte array of the File along with some metadata about the file is serialized to JSON and posted to the Web API. Web API then saves the byte array as a Filestream to the Database.
Following is a sample of the current request:
{"FileContent":"JVBERi0xLjUNJeLjz9MNCjEwIDAgb2JqDTw8L0xpbmVhcml6ZWQgMS9MIDI3MTg2L08gMTIvRSAyMjYyNi9OIDEvVCAyNjg4NC9IIFsgNDg5IDE2OF0+Pg1lbmRvYmoNICAgICAgICAgICAgICAgICAgDQoyNyAwIG9iag08PC9EZWNvZGVQYXJtczw8L0NvbHVtbnMgNC9QcmVkaWN0b3IgMTIg0K","ProductId":"85c98324-092a-4d10-bab0-03912e437234","OrderId":"7b826322-7526-4a69-b67c-5c88a04f4c60","FileName":"test.pdf","FileType":1,"FileDescription":"test"}
I would like to change this logic to Post as a Content-Type of Multipart. What would be the best way to form my request? Also, what's the best way to structure my Web API Controller to process the Multipart request?
This is a sample for a Multipart upload.
[HttpPost]
[Route("upload")]
public async Task<IHttpActionResult> Upload()
{
MultipartFileData file = null;
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
return UnsupportedMediaType();
}
// initialize path and provider
string root = HttpContext.Current.Server.MapPath("~/App_Data");
if (Directory.Exists(root) == false) Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
try
{
// we take the first file here
file = provider.FileData[0];
// and the associated datas
int myInteger;
if (int.TryParse(provider.FormData["MyIntergerData"], out myInteger) == false)
throw new ArgumentException("myInteger is missing or not valid.");
var fileContent = File.ReadAllBytes(file.LocalFileName);
// do something with your file!
}
finally
{
// get rid of temporary file
if (file != null)
File.Delete(file.LocalFileName);
}
// successfull!
return NoContent();
}
This is a sample I got from an API of mine. You can have multiple files for each upload (check the provider.FileData array), and different datas inside the provider.FormData array.
For the client side aspect of this I suggest you to check this answer for a sample of a JS call to this API.
Hope it helps!
I am generating reports resulting in WORD files using xdocreport.
From the generated report, I create a InputStreamContent with MIME-TYPE "application/vnd.openxmlformats-officedocument.wordprocessingml.document" (MS WORD - DOCX) to write to Google Drive :
// create Word file stream using xdocreport
OutputStream2InputStream outputStream = new OutputStream2InputStream(); // buffer
report.process(context, outputStream);
// create inputstream for Google Drive
InputStreamContent inputStream = new InputStreamContent("application/vnd.openxmlformats-officedocument.wordprocessingml.document",
outputStream.getInputStream());
inputStream.setLength(outputStream.size());
WRITING MSWORD DOCUMENT WORKS FINE (CONVERT= FALSE) :
File file = new File();
Insert insertOperation = service.files().insert(file, inputStream).setConvert(false);
file.setTitle("test.docx");
file.setMimeType(inputstream.getType());
File result = insertOperation.execute();
Resulting in a WORD DOCX file created on my Google Drive.
WRITING SAME INPUTSTREAM WITH CONVERT=TRUE FAILS
File file = new File();
Insert insertOperation = service.files().insert(file, inputStream).setConvert(true);
file.setTitle("test");
//file.setMimeType(inputstream.getType()); // what here ?
File result = insertOperation.execute();
RESULT
1. When NOT setting the mime type : newly created File result has 0 bytes and MIME-type: application/vnd.google-apps.kix
2. When setting the mime type : MIME-TYPE set to "application/vnd.google-apps.document" and convert = true, results in 400: BAD REQUEST.
What am I doing wrong ?
This is a common problem. Don't set a MIME type in the request metadata. Google Drive will decide the MIME type to convert to.
Your line marked // what here ? should be left out.
All what you need to do is to update your getType() with the correct .docx MIME-type.
docx=> application/vnd.openxmlformats-officedocument.wordprocessingml.document
I had the same issue and this piece of code fixed it!