- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个新的 MediaFileSystemProvider,它将媒体无缝存储在 Azure Blob 存储中。
我从 Umbraco v6.1 源代码中复制了 MediaFileSystem 类作为我的起点。
然后,我编辑了/config/FileSystemProviders.config 文件,插入了我的新类详细信息。
当我重新启动 Umbraco 时,会调用新类,但收到错误:
“找不到接受 0 个参数的类型‘mysite.core.umbracoExtensions.FileSystemProviders.AzureBlobStorageProvider, mysite.core’的构造函数”
这是我的类(class):
...
[FileSystemProvider("media")]
public class AzureBlobStorageProvider : FileSystemWrapper
{
private string rootUrl;
CloudStorageAccount storageAccount;
CloudBlobClient blobClient;
CloudBlobContainer container;
public AzureBlobStorageProvider(IFileSystem wrapped)
: base(wrapped)
{
var constring = ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString;
// Retrieve storage account from connection string.
storageAccount = CloudStorageAccount.Parse(constring);
// Create the blob client.
blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
container = blobClient.GetContainerReference("mymedia");
//container.CreateIfNotExists();
//container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
rootUrl = "https://mysite.blob.core.windows.net/media";
}
...
方法
知道我在这里做错了什么吗?
干杯
最佳答案
考虑到我从这里的人们那里得到的所有帮助,我不能让这一半完成:)
我设置了一个新的 Umbraco v6.1.6 并确认 MediaService.Deleted 事件绝对不会通过以下代码被触发/ Hook 。我会去了解如何提交错误...
对于任何有兴趣在 Azure 存储中存储 Umbraco 媒体项目的人,以下是我的做法。您可以使用“CDNEnabled”键打开/关闭 CDN 以显示图像内容,并使用“AzureCDNUploadEnabled”键打开/关闭上传,而无需每次都触摸您的 View 。
仅供引用,Azure Blob 存储的实际 CDN 部分目前不可用。过去是,现在不是,而且显然有一天还会再次出现。
您可以通过设置“AzureCDNCacheControlHeader”值在上传时更新缓存控制 header 来限制数据使用并加快图像传输速度。以下值将图像设置为在 30 天后过期,然后重新验证。
将其添加到您的 web.config appsettings 节点:
<!-- cdn config -->
<!-- used for razor rendering -->
<add key="CDNPath" value="https://utest.blob.core.windows.net"/>
<add key="CDNEnabled" value="true"/>
<!-- used for media uploads -->
<add key="AzureCDNStorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName={yourAccount};AccountKey={yourKey}"/>
<add key="AzureCDNStorageAccountName" value="{yourStorageAccount}"/>
<add key="AzureCDNBlobContainerName" value="media"/>
<add key="AzureCDNRootUrl" value="https://{yourAccount}.blob.core.windows.net"/>
<add key="AzureCDNUploadEnabled" value="true"/>
<add key="AzureCDNCacheControlHeader" value="must-revalidate, public, max-age=604800"/> <!-- change to whatever suits you -->
<!-- end cdn -->
这是事件处理程序:
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Configuration;
using System.Web;
using System.Linq;
using System.IO;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace utest1.umbracoExtensions.events
{
public class SaveMediaToAzure : ApplicationEventHandler
{
/* either add your own logging class or remove this and all calls to 'log' */
private log4net.ILog log = log4net.LogManager.GetLogger(typeof(utest1.logging.PublicLogger));
CloudStorageAccount storageAccount;
private string blobContainerName;
CloudBlobClient blobClient;
CloudBlobContainer container;
string cacheControlHeader;
private bool uploadEnabled;
public SaveMediaToAzure()
{
try
{
storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureCDNStorageConnectionString"]);
blobContainerName = ConfigurationManager.AppSettings["AzureCDNStorageAccountName"];
blobClient = storageAccount.CreateCloudBlobClient();
container = blobClient.GetContainerReference(ConfigurationManager.AppSettings["AzureCDNBlobContainerName"]);
uploadEnabled = Convert.ToBoolean(ConfigurationManager.AppSettings["AzureCDNUploadEnabled"]);
cacheControlHeader = ConfigurationManager.AppSettings["AzureCDNCacheControlHeader"];
MediaService.Saved += MediaServiceSaved;
MediaService.Trashed += MediaServiceTrashed;
MediaService.Deleted += MediaServiceDeleted; // not firing
}
catch (Exception x)
{
log.Error("SaveMediaToAzure Config Error", x);
}
}
void MediaServiceSaved(IMediaService sender, SaveEventArgs<IMedia> e)
{
if (uploadEnabled)
{
foreach (var fileItem in e.SavedEntities)
{
try
{
log.Info("Saving media to Azure:" + e.SavedEntities.First().Name);
var path = fileItem.GetValue("umbracoFile").ToString();
var filePath = HttpContext.Current.Server.MapPath(path);
UploadToAzure(filePath, path);
if (fileItem.GetType() == typeof(Umbraco.Core.Models.Media))
{
UploadThumbToAzure(filePath, path);
}
}
catch (Exception x)
{
log.Error("Error saving media to Azure: " + fileItem.Name, x);
}
}
}
}
/*
* Using this because MediaServiceDeleted event is not firing in v6.1.6
*
*/
void MediaServiceTrashed(IMediaService sender, MoveEventArgs<IMedia> e)
{
if (uploadEnabled)
{
try
{
log.Info("Deleting media from Azure:" + e.Entity.Name);
var path = e.Entity.GetValue("umbracoFile").ToString();
CloudBlockBlob imageBlob = container.GetBlockBlobReference(StripContainerNameFromPath(path));
imageBlob.Delete();
CloudBlockBlob thumbBlob = container.GetBlockBlobReference(StripContainerNameFromPath(GetThumbPath(path)));
thumbBlob.Delete();
}
catch (Exception x)
{
log.Error("Error deleting media from Azure: " + e.Entity.Name, x);
}
}
}
/*
* MediaServiceDeleted event not firing in v6.1.6
*
*/
void MediaServiceDeleted(IMediaService sender, DeleteEventArgs<IMedia> e)
{
//if (uploadEnabled)
//{
// try
// {
// log.Info("Deleting media from Azure:" + e.DeletedEntities.First().Name);
// var path = e.DeletedEntities.First().GetValue("umbracoFile").ToString();
// CloudBlockBlob imageBlob = container.GetBlockBlobReference(StripContainerNameFromPath(path));
// imageBlob.Delete();
// CloudBlockBlob thumbBlob = container.GetBlockBlobReference(StripContainerNameFromPath(GetThumbPath(path)));
// thumbBlob.Delete();
// }
// catch (Exception x)
// {
// log.Error("Error deleting media from Azure: " + e.DeletedEntities.First().Name, x);
// }
//}
Console.WriteLine(e.DeletedEntities.First().Name); // still not working
}
private string StripContainerNameFromPath(string path)
{
return path.Replace("/media/", String.Empty);
}
/*
*
*
*/
private void UploadToAzure(string filePath, string relativePath)
{
System.IO.MemoryStream data = new System.IO.MemoryStream();
System.IO.Stream str = System.IO.File.OpenRead(filePath);
str.CopyTo(data);
data.Seek(0, SeekOrigin.Begin);
byte[] buf = new byte[data.Length];
data.Read(buf, 0, buf.Length);
Stream stream = data as Stream;
if (stream.CanSeek)
{
stream.Position = 0;
CloudBlockBlob blob = container.GetBlockBlobReference(StripContainerNameFromPath(relativePath));
blob.UploadFromStream(stream);
SetCacheControl(blob);
}
else
{
log.Error("Could not read image for upload: " + relativePath);
}
}
private void SetCacheControl(CloudBlockBlob blob)
{
blob.Properties.CacheControl = cacheControlHeader;
blob.SetProperties();
}
private void UploadThumbToAzure(string filePath, string relativePath)
{
var thumbFilePath = GetThumbPath(filePath);
var thumbRelativePath = GetThumbPath(relativePath);
UploadToAzure(thumbFilePath, thumbRelativePath);
}
private string GetThumbPath(string path)
{
var parts = path.Split('.');
var filename = parts[parts.Length - 2];
return path.Replace(filename, filename + "_thumb");
}
}
}
这是渲染助手:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace utest1.umbracoExtensions.helpers
{
public class CDNImage
{
public static string ConvertUrlToCDN(string source)
{
if (String.IsNullOrEmpty(source))
{
return null;
}
var cdnUrl = System.Configuration.ConfigurationManager.AppSettings["CDNPath"];
var cdnOn = System.Configuration.ConfigurationManager.AppSettings["CDNEnabled"];
if (cdnOn == "true")
{
/*
* check if the url is absolute or not and whether it should be intercepted - eg. an external image url
* if it's absolute you'll need to strip out everything before /media...
*/
if (source.Contains(GetBaseUrl()))
{
source = StripBaseUrl(source);
}
}
return source;
}
private static string GetBaseUrl()
{
var url = System.Web.HttpContext.Current.Request.Url;
var baseUrl = url.Scheme + "//" + url.Host;
if (url.Port != 80 && url.Port != 443)
{
baseUrl += ":" + url.Port;
}
return baseUrl;
}
private static string StripBaseUrl(string path)
{
return path.Replace(GetBaseUrl(), String.Empty);
}
}
}
最后显示在 RazorView 中:
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
Layout = "BasePage.cshtml";
}
@using utest1.umbracoExtensions.helpers
@{
var ms = ApplicationContext.Current.Services.MediaService;
var img = ms.GetById(int.Parse(CurrentPage.Image));
}
<h1>Umbraco on Azure is getting there!</h1>
<p>@img.Name</p>
<img alt="@img.Name" src="@CDNImage.ConvertUrlToCDN(img.GetValue("umbracoFile").ToString())" />
欢迎提出改进建议。
啊啊啊,回馈的感觉真好:)
关于c# - Umbraco v6.1 的 FileSystemProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17416050/
嗨,我正在将 Umbraco 安装到我网站的根目录。而且我想将我的 wordpress 博客安装到根目录中的子文件夹中。 然而,对子文件夹的任何请求都被 Umbraco 拦截,并显示无法找到文档 UR
我对 umbraco 比较陌生,刚刚建立了网站,但客户要求一个具有全新外观和感觉的微型网站。 那么如何在 umbraco 中建立一个新的微型站点。 请帮忙。 万分感谢 最佳答案 要使 Umbraco
正如标题所问,Umbraco 将其版本信息存储在数据库的哪个位置? 最佳答案 它存储在 web.config 文件中(umbracoConfigurationStatus 设置)而不是数据库中。 理查
好吧,我刚刚在 Umbraco 的杂草中度过了过去 6-8 周的时间,并对我们的网站和环境进行了一些修复/改进。我花了很多时间尝试纠正较低级别的 Umbraco 缓存相关问题。现在反射(reflect
我正忙于学习 Umbraco,但我在 Internet 上看不到任何信息告诉我 Umbraco 是否允许我使用连接到 SQL Server 数据库的 C# 代码创建自定义 ASP.NET 表单。 如果
我正在尝试从数据库中导出成员属性,如名字、姓氏,但我似乎无法找到它。我看到有一个带有正确列的 loginUser 表,但它似乎只包含 5 个条目,而不是我在管理界面中看到的完整人员列表。 最佳答案 道
我们在后端有一个混合语言的 umbraco 安装。当我将用户的语言切换为“英语(英国)”或“英语(美国)”时,我仍然在后端看到一些德语单词,例如在搜索框中用“Durchsuchen”代替“Type t
我正在使用 umbraco cms 设置 af 多语言页面。 我有一个看起来像这样的内容结构: 内容 达 丹麦语子页 1 丹麦语子页 2 恩 英文子页1 英文子页2 我希望路由是这样的: http:/
我正在尝试在 umbraco 中创建一个新闻文件,它会在其中显示按月组织的新闻页面列表。每个页面都会显示当月新闻项目的列表。 我关注了 tutorial for creating news items
是否可以在 Umbraco 后台关闭 Umbraco 升级消息。不一定希望我的用户看到这一点。 最佳答案 有一个umbracoVersionCheckPeriod键入 appSettings web.
我的情况是,我负责为 Umbraco 制作应用程序或扩展,使后端用户能够将他们在开发站点上的更改迁移到实时站点。这种迁移应该每天发生一次,或者在后端用户按下后端的按钮时发生。 我知道 Umbraco
我想知道是否有人可以解释 Umbraco Cms Core Binaries Package 和 Umbraco Cms NuGet Package 之间的区别? 最佳答案 一个好问题。首先,我会推荐
有没有一种方法可以简单地在 umbraco 4 中创建文件夹以组织内容?我搜索了论坛并没有找到合理的答案。 最佳答案 这是文档有点缺乏的领域,但它是完全可行的: 创建一个名为“内容文件夹”之类的文档类
我最近决定与 Umbraco 一起开发我们的新公司网站 (http://www.idealcode.net:8005/AboutUs.aspx)。我聘请了一位 Umbraco 开发人员,我们开始工作。
有没有人遇到过 Umbraco 说内容更改已成功保存的问题,您关闭了所有内容(包括 webmatrix),然后返回并发现更改已丢失? 我正在我的本地主机上工作。 我认为这与 webmatrix 上的数
我已经创建了基于内置下拉列表的自定义数据类型,但不知道如何为列表指定默认值。默认值始终为空: 最佳答案 默认下拉不支持默认值 有两种方法可以实现你想要的 创建您自己的下拉数据类型(或使用其他人制作的插
我正在运行 umbraco 7 的一个实例。但我似乎无法设置 miniprofiler 来使用它。 在我的 global.asax 上设置: protected void Applicatio
我想将我自己的部分添加到 umbraco 仪表板,以便我可以将我自己的管理部分集成到现有的登录/管理结构中。如果不编辑和重新编译 umbraco 源代码本身,这可能吗?是否推荐?如果是这样,是否有人有
我想在 umbraco 4.7 中显示最后更新日期 假设我什至对管理面板中的内容进行了微小的更改,它都必须提取更新日期,以便我可以在网站的页脚中动态显示。 谢谢。 最佳答案 每个节点都有一个名为 up
我已经使用 Umbraco 6.02 创建了一个站点,现在我将检查该站点的所有最终配置,并且已经开始索引。我做了一些研究,但我无法简单地找到每个部分需要包含的内容以及原因。 我应该在 中包含哪些字段
我是一名优秀的程序员,十分优秀!