Kendo UI Asp.Net Core 的数据库驱动图像浏览器
Database driven Imagebrowser for Kendo UI for Asp.Net Core
这个问题我会自己回答。根据此处提供的示例,我花了几个小时试图让它工作:https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/editor/database-image-browser/DatabaseImageBrowser
由于我不维护博客,这是我记录的方式,以防其他人面临相同的用例,这可能会节省他们一些时间
问题是:如何实现一个 Imagebrowser,它不能与本地文件夹一起使用,但可以与数据库一起使用。 Telerik 提供的示例使用虚拟文件夹,存储在一个 table 中,图像链接在一个单独的文件夹中,并与文件夹 ID 链接。因为我不想使用文件夹,所以我需要找到一种方法来解决这个问题。另外: IImageBrowserController
只提供了一个同步接口,这使得它不适合 table 用于异步操作:
public interface IImageBrowserController : IFileBrowserController
{
IActionResult Thumbnail(string path);
}
public interface IFileBrowserController
{
ActionResult Create(string path, FileBrowserEntry entry);
ActionResult Destroy(string path, FileBrowserEntry entry);
JsonResult Read(string path);
ActionResult Upload(string path, IFormFile file);
}
第二个问题是:如何将Image读取路径从虚拟路径.Image("~/Content/UserFiles/Images/{0}")
转换为mvc路由
最后,您如何实现自定义控制器或 Razor 页面,这样您就不需要在 Asp.Net Core 上使用虚拟文件夹。
首先,创建一个适合异步操作的接口:
public interface IImageBrowserControllerAsync
{
Task<IActionResult> Create(string name, FileBrowserEntry entry);
Task<IActionResult> Destroy(string name, FileBrowserEntry entry);
Task<IActionResult> Image(string path);
Task<JsonResult> Read(string path);
Task<IActionResult> Thumbnail(string path);
Task<IActionResult> Upload(string name, IFormFile file);
}
接下来,创建控制器实现。我将省略一些方法,以免浪费宝贵的阅读时间。实现类似于提供的方法:
public class ImageBrowserController : ControllerBase, IImageBrowserControllerAsync
{
private IImageRepository _repo;
private const int ThumbnailHeight = 80,
ThumbnailWidth = 80;
public ImageBrowserController(IImageRepository repo)
{
_repo = repo;
}
[Route("Image")]
public async Task<IActionResult> Image(string path)
{
var image = await _repo.GetByName(path);
if (image != null)
{
return File(image.Data, image.ContentType);
}
return NotFound("Errormessage");
}
//read all images, when the widget loads
[Route("Read")]
public async Task<JsonResult> Read(string path)
{
var images = await _repo.Get(); // do not return the image data. it is not
//needed and will clog up your resources
var fbe = images.Select(x => new FileBrowserEntry
{
Name = x.Name,
EntryType = FileBrowserEntryType.File
});
return new JsonResult(fbe);
}
//Create thumbnail using SixLabors.Imagesharp library
[Route("Thumbnail")]
public async Task<IActionResult> Thumbnail(string path)
{
var image = await _repo.GetByName(path);
if (image != null)
{
var i = SixLabors.ImageSharp.Image
.Load(image.Data);
i.Mutate(ctx => ctx.Resize(ThumbnailWidth, ThumbnailHeight));
using (var ms = new MemoryStream())
{
i.SaveAsJpeg(ms);
return File(ms.ToArray(), image.ContentType);
}
}
return NotFound();
}
[Route("Upload")]
public async Task<IActionResult> Upload(string name, IFormFile file)
{
if (file == null || file.Length == 0) return BadRequest();
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
var img = new Entities.Image
{
Name = file.FileName,
ContentType = file.ContentType,
Data = ms.ToArray()
};
await _repo.CreateImage(img);
return Ok();
}
}
}
这是图像浏览器/编辑器配置:
@(Html.Kendo().Editor()
.Name("editor")
.HtmlAttributes(new { style = "width: 100%;height:440px
.Tools(tools => tools
.Clear()
/*omitted config*/
)
.ImageBrowser(ib => ib
//use actionmethod, controller, route values format
.Image("Image", "ImageBrowser", new {path = "{0}"})
.Read("Read", "ImageBrowser") // path can be null if you don't use folders
.Destroy("Destroy", "ImageBrowser")
.Upload("Upload", "ImageBrowser")
.Thumbnail("Thumbnail", "ImageBrowser"))
)
无论谁读到这篇文章:我希望这个例子能帮助您节省一些时间在 Asp.Net Core 上实现它。
重要提示:在加载所有图像时,不要 return byte[]
。 Kendo 只需要一个具有名称和类型的 FileBrowserEntry 属性。
我强烈建议在这里实现缓存。在每次加载页面时为数十或数百张图像创建缩略图,会给您的基础架构带来巨大压力。
这个问题我会自己回答。根据此处提供的示例,我花了几个小时试图让它工作:https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/editor/database-image-browser/DatabaseImageBrowser 由于我不维护博客,这是我记录的方式,以防其他人面临相同的用例,这可能会节省他们一些时间
问题是:如何实现一个 Imagebrowser,它不能与本地文件夹一起使用,但可以与数据库一起使用。 Telerik 提供的示例使用虚拟文件夹,存储在一个 table 中,图像链接在一个单独的文件夹中,并与文件夹 ID 链接。因为我不想使用文件夹,所以我需要找到一种方法来解决这个问题。另外: IImageBrowserController
只提供了一个同步接口,这使得它不适合 table 用于异步操作:
public interface IImageBrowserController : IFileBrowserController
{
IActionResult Thumbnail(string path);
}
public interface IFileBrowserController
{
ActionResult Create(string path, FileBrowserEntry entry);
ActionResult Destroy(string path, FileBrowserEntry entry);
JsonResult Read(string path);
ActionResult Upload(string path, IFormFile file);
}
第二个问题是:如何将Image读取路径从虚拟路径.Image("~/Content/UserFiles/Images/{0}")
转换为mvc路由
最后,您如何实现自定义控制器或 Razor 页面,这样您就不需要在 Asp.Net Core 上使用虚拟文件夹。
首先,创建一个适合异步操作的接口:
public interface IImageBrowserControllerAsync
{
Task<IActionResult> Create(string name, FileBrowserEntry entry);
Task<IActionResult> Destroy(string name, FileBrowserEntry entry);
Task<IActionResult> Image(string path);
Task<JsonResult> Read(string path);
Task<IActionResult> Thumbnail(string path);
Task<IActionResult> Upload(string name, IFormFile file);
}
接下来,创建控制器实现。我将省略一些方法,以免浪费宝贵的阅读时间。实现类似于提供的方法:
public class ImageBrowserController : ControllerBase, IImageBrowserControllerAsync
{
private IImageRepository _repo;
private const int ThumbnailHeight = 80,
ThumbnailWidth = 80;
public ImageBrowserController(IImageRepository repo)
{
_repo = repo;
}
[Route("Image")]
public async Task<IActionResult> Image(string path)
{
var image = await _repo.GetByName(path);
if (image != null)
{
return File(image.Data, image.ContentType);
}
return NotFound("Errormessage");
}
//read all images, when the widget loads
[Route("Read")]
public async Task<JsonResult> Read(string path)
{
var images = await _repo.Get(); // do not return the image data. it is not
//needed and will clog up your resources
var fbe = images.Select(x => new FileBrowserEntry
{
Name = x.Name,
EntryType = FileBrowserEntryType.File
});
return new JsonResult(fbe);
}
//Create thumbnail using SixLabors.Imagesharp library
[Route("Thumbnail")]
public async Task<IActionResult> Thumbnail(string path)
{
var image = await _repo.GetByName(path);
if (image != null)
{
var i = SixLabors.ImageSharp.Image
.Load(image.Data);
i.Mutate(ctx => ctx.Resize(ThumbnailWidth, ThumbnailHeight));
using (var ms = new MemoryStream())
{
i.SaveAsJpeg(ms);
return File(ms.ToArray(), image.ContentType);
}
}
return NotFound();
}
[Route("Upload")]
public async Task<IActionResult> Upload(string name, IFormFile file)
{
if (file == null || file.Length == 0) return BadRequest();
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
var img = new Entities.Image
{
Name = file.FileName,
ContentType = file.ContentType,
Data = ms.ToArray()
};
await _repo.CreateImage(img);
return Ok();
}
}
}
这是图像浏览器/编辑器配置:
@(Html.Kendo().Editor()
.Name("editor")
.HtmlAttributes(new { style = "width: 100%;height:440px
.Tools(tools => tools
.Clear()
/*omitted config*/
)
.ImageBrowser(ib => ib
//use actionmethod, controller, route values format
.Image("Image", "ImageBrowser", new {path = "{0}"})
.Read("Read", "ImageBrowser") // path can be null if you don't use folders
.Destroy("Destroy", "ImageBrowser")
.Upload("Upload", "ImageBrowser")
.Thumbnail("Thumbnail", "ImageBrowser"))
)
无论谁读到这篇文章:我希望这个例子能帮助您节省一些时间在 Asp.Net Core 上实现它。
重要提示:在加载所有图像时,不要 return byte[]
。 Kendo 只需要一个具有名称和类型的 FileBrowserEntry 属性。
我强烈建议在这里实现缓存。在每次加载页面时为数十或数百张图像创建缩略图,会给您的基础架构带来巨大压力。