Can an ASP.NET MVC controller return an Image?
Can I create a Controller that simply returns an image asset?
I would like to route this logic through a controller, whenever a URL such as the following is requested:
www.mywebsite.com/resource/image/topbanner
The controller will look up topbanner.png
and send that image directly back to the client.
I've seen examples of this where you have to create a View - I don't want to use a View. I want to do it all with just the Controller.
Is this possible?
Use the base controllers File method.
public ActionResult Image(string id)
{
var dir = Server.MapPath("/Images");
var path = Path.Combine(dir, id + ".jpg"); //validate the path for security or use other means to generate the path.
return base.File(path, "image/jpeg");
}
As a note, this seems to be fairly efficient. I did a test where I requested the image through the controller ( http://localhost/MyController/Image/MyImage
) and through the direct URL ( http://localhost/Images/MyImage.jpg
) and the results were:
Note: this is the average time of a request. The average was calculated by making thousands of requests on the local machine, so the totals should not include network latency or bandwidth issues.
Using the release version of MVC, here is what I do:
[AcceptVerbs(HttpVerbs.Get)]
[OutputCache(CacheProfile = "CustomerImages")]
public FileResult Show(int customerId, string imageName)
{
var path = string.Concat(ConfigData.ImagesDirectory, customerId, "", imageName);
return new FileStreamResult(new FileStream(path, FileMode.Open), "image/jpeg");
}
I obviously have some application specific stuff in here regarding the path construction, but the returning of the FileStreamResult is nice and simple.
I did some performance testing in regards to this action against your everyday call to the image (bypassing the controller) and the difference between the averages was only about 3 milliseconds (controller avg was 68ms, non-controller was 65ms).
I had tried some of the other methods mentioned in answers here and the performance hit was much more dramatic... several of the solutions responses were as much as 6x the non-controller (other controllers avg 340ms, non-controller 65ms).
To expland on Dyland's response slightly:
Three classes implement the FileResult class:
System.Web.Mvc.FileResult
System.Web.Mvc.FileContentResult
System.Web.Mvc.FilePathResult
System.Web.Mvc.FileStreamResult
They're all fairly self explanatory:
FilePathResult
- this is the easiest way and avoids you having to use Streams. FileContentResult
. FileStreamResult
in a similar way to below, but with a MemoryStream
and using GetBuffer()
. Streams
use FileStreamResult
. It's called a FileStreamResult but it takes a Stream
so I'd guess it works with a MemoryStream
. Below is an example of using the content-disposition technique (not tested):
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetFile()
{
// No need to dispose the stream, MVC does it for you
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "myimage.png");
FileStream stream = new FileStream(path, FileMode.Open);
FileStreamResult result = new FileStreamResult(stream, "image/png");
result.FileDownloadName = "image.png";
return result;
}
链接地址: http://www.djcxy.com/p/8422.html
上一篇: 在ASP.NET MVC中编译视图