asp.net-mvc - 将 VirtualPathProvider 与 MVC 和 Azure 存储结合使用时不断出现错误

标签 asp.net-mvc asp.net-mvc-4 razor azure

我定义了一个 VirtualPathProvider,用于从 Azure 存储获取 cshtml 文件以用作部分 View 。

启动时出现以下错误:

The view at '~/Views/Home/Index.aspx' must derive from ViewPage, ViewPage, ViewUserControl, or ViewUserControl.

看来我的 virtualPathProvider 正在阻止使用 razor View 引擎。

这是 VirtualPathProvider:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure;
using System.IO;
using System.Configuration;

namespace VTSMVC.Helpers.Utilities
{
public class BlobStorageVirtualPathProvider:VirtualPathProvider
{
    protected readonly CloudStorageAccount accountInfo;
    protected readonly CloudBlobContainer container;
    public CloudBlobContainer BlobContainer
    { 
        get { return container; } 
    }

    public BlobStorageVirtualPathProvider()
    {

        // Retrieve storage account from connection string.
        switch (ConfigurationManager.AppSettings["WebCloud"])
        {
            case "Cloud":
                // Retrieve storage account from connection string.
                accountInfo =     CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
                break;

            case "Web":
            default:
                accountInfo = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
                break;
        }

        // Create the blob client.
        CloudBlobClient blobClient = accountInfo.CreateCloudBlobClient();

        // Retrieve a reference to a container. 
        container = blobClient.GetContainerReference("stockreports");
    }

    public override bool FileExists(string virtualPath)
    {
        // Check if the file exists on blob storage 
        //string cleanVirtualPath = virtualPath.Replace("~", "").Substring(1);
        string cleanVirtualPath = virtualPath;
        if (container.GetBlockBlobReference(cleanVirtualPath) != null)
        {
            return true;
        }
        else
        {
            return Previous.FileExists(virtualPath);
        }

    }

    public override VirtualFile GetFile(string virtualPath)
    {
        // Check if the file exists on blob storage 
        //string cleanVirtualPath = virtualPath.Replace("~", "").Substring(1);
        string cleanVirtualPath = virtualPath;
        if (container.GetBlockBlobReference(cleanVirtualPath) != null)
        {
            return new BlobStorageVirtualFile(virtualPath, this);
        }
        else
        {
            return Previous.GetFile(virtualPath);
        }
    }

    public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
    {
        return null;
    }
}

public class BlobStorageVirtualFile : VirtualFile
{
    protected readonly BlobStorageVirtualPathProvider parent;

    public BlobStorageVirtualFile(string virtualPath, BlobStorageVirtualPathProvider parentProvider) : base(virtualPath)
    {
        parent = parentProvider;
    }

    public override System.IO.Stream Open()
    {
        MemoryStream ms = new MemoryStream();

        try
        {
            //string cleanVirtualPath = this.VirtualPath.Replace("~", "").Substring(1);
            string cleanVirtualPath = this.VirtualPath;

            // Retrieve reference to a blob
            CloudBlockBlob blockBlob = parent.BlobContainer.GetBlockBlobReference(cleanVirtualPath);

            //Retrive the memorystream
            blockBlob.DownloadToStream(ms);
        }
        catch (Exception)
        {
            // TODO: log your error messages here
        }
        return ms;
    }
}
} 

这是我的 global.asax

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Hosting; 
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using VTSMVC.Helpers.Utilities;

namespace VTSMVC
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    // Register the virtual path provider with ASP.NET 
    System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new BlobStorageVirtualPathProvider()); 
}
}
}

与我的 azure 存储的连接似乎可以正常工作,因为我已经用它来保存了。

有人知道这是怎么回事吗?

最佳答案

为了其他用户的利益:

页面需要从 System.Web.Mvc.ViewPage 或类似的基本类型派生。这可以使用 .cshtml 文件中的 @inherits 来完成。

我们通常不需要它的原因是 Views 文件夹包含一个 web.config 文件,该文件将默认页面基本类型设置为 WebViewPage。或者,您可以从该 web.config 文件复制该部分并将其放入主 web.config 文件中。

关于asp.net-mvc - 将 VirtualPathProvider 与 MVC 和 Azure 存储结合使用时不断出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918881/

相关文章:

javascript - ASP MVC 将数组对象发送到 JavaScript 函数

javascript - 如何在div中找到下拉选择的值

c#-4.0 - 如何在 Lucene.Net 3 中提升字段

html - 彼此下方的复选框

c# - Mvc raw没有输出

c# - 运算符 '>' 无法使用 Asp.net Mvc 应用于类型 'string' 和 'int' 的操作数

javascript - 如何使用 e.preventDefault() 进行验证; MVC?

jquery - 超出的最大上传文件大小将被忽略

jquery - 使用 ICanHaz 从 JSON 渲染 HTML 字符串

forms - Webmatrix - 从查询字符串更新输入值