我可以创建一个简单地返回图像资产的控制器吗?
我想通过控制器路由这个逻辑,每当请求如下URL时:
www.mywebsite.com/resource/image/topbanner
控制器将查找topbanner.png并将图像直接发送回客户端。
我见过这样的例子,你必须创建一个视图-我不想使用视图。我想只用控制器来做。
这可能吗?
我可以创建一个简单地返回图像资产的控制器吗?
我想通过控制器路由这个逻辑,每当请求如下URL时:
www.mywebsite.com/resource/image/topbanner
控制器将查找topbanner.png并将图像直接发送回客户端。
我见过这样的例子,你必须创建一个视图-我不想使用视图。我想只用控制器来做。
这可能吗?
当前回答
是的,你可以返回图像
public ActionResult GetImage(string imageFileName)
{
var path = Path.Combine(Server.MapPath("/Images"), imageFileName + ".jpg");
return base.File(path, "image/jpeg");
}
(请不要忘记将此标记为答案)
其他回答
从Core 3.2下的字节[],你可以使用:
public ActionResult Img(int? id) {
MemoryStream ms = new MemoryStream(GetBytes(id));
return new FileStreamResult(ms, "image/png");
}
这对我很管用。 因为我将图像存储在SQL Server数据库上。
[HttpGet("/image/{uuid}")]
public IActionResult GetImageFile(string uuid) {
ActionResult actionResult = new NotFoundResult();
var fileImage = _db.ImageFiles.Find(uuid);
if (fileImage != null) {
actionResult = new FileContentResult(fileImage.Data,
fileImage.ContentType);
}
return actionResult;
}
在上面的代码片段中,_db.ImageFiles.Find(uuid)正在db (EF上下文)中搜索图像文件记录。它返回一个FileImage对象,它只是一个我为模型制作的自定义类,然后将其用作FileContentResult。
public class FileImage {
public string Uuid { get; set; }
public byte[] Data { get; set; }
public string ContentType { get; set; }
}
if (!System.IO.File.Exists(filePath))
return SomeHelper.EmptyImageResult(); // preventing JSON GET/POST exception
else
return new FilePathResult(filePath, contentType);
SomeHelper.EmptyImageResult()应该返回具有现有图像的FileResult(例如1x1透明)。
这是最简单的方法,如果你有文件存储在本地驱动器。 如果文件是字节[]或流-然后使用FileContentResult或FileStreamResult Dylan建议。
使用MVC的发布版本,下面是我所做的:
[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");
}
显然,我在这里有一些关于路径构造的应用程序特定的东西,但返回FileStreamResult很好,很简单。
我做了一些性能测试,针对您每天对图像的调用(绕过控制器),平均值之间的差异仅为3毫秒(控制器的平均值为68ms,非控制器的平均值为65ms)。
我尝试了答案中提到的其他一些方法,性能的影响要大得多……一些解决方案的响应高达非控制器的6倍(其他控制器平均340ms,非控制器65ms)。
您可以创建自己的扩展,并这样做。
public static class ImageResultHelper
{
public static string Image<T>(this HtmlHelper helper, Expression<Action<T>> action, int width, int height)
where T : Controller
{
return ImageResultHelper.Image<T>(helper, action, width, height, "");
}
public static string Image<T>(this HtmlHelper helper, Expression<Action<T>> action, int width, int height, string alt)
where T : Controller
{
var expression = action.Body as MethodCallExpression;
string actionMethodName = string.Empty;
if (expression != null)
{
actionMethodName = expression.Method.Name;
}
string url = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection).Action(actionMethodName, typeof(T).Name.Remove(typeof(T).Name.IndexOf("Controller"))).ToString();
//string url = LinkBuilder.BuildUrlFromExpression<T>(helper.ViewContext.RequestContext, helper.RouteCollection, action);
return string.Format("<img src=\"{0}\" width=\"{1}\" height=\"{2}\" alt=\"{3}\" />", url, width, height, alt);
}
}
public class ImageResult : ActionResult
{
public ImageResult() { }
public Image Image { get; set; }
public ImageFormat ImageFormat { get; set; }
public override void ExecuteResult(ControllerContext context)
{
// verify properties
if (Image == null)
{
throw new ArgumentNullException("Image");
}
if (ImageFormat == null)
{
throw new ArgumentNullException("ImageFormat");
}
// output
context.HttpContext.Response.Clear();
context.HttpContext.Response.ContentType = GetMimeType(ImageFormat);
Image.Save(context.HttpContext.Response.OutputStream, ImageFormat);
}
private static string GetMimeType(ImageFormat imageFormat)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
return codecs.First(codec => codec.FormatID == imageFormat.Guid).MimeType;
}
}
public ActionResult Index()
{
return new ImageResult { Image = image, ImageFormat = ImageFormat.Jpeg };
}
<%=Html.Image<CapchaController>(c => c.Index(), 120, 30, "Current time")%>