Pluggable MVC view return null

Go To StackoverFlow.com

0

I tried following some of the code from here and here, but I am getting an error on the page when trying to reference the remote view located in a separate project: "Value cannot be null. Parameter name: stream"

Below is my AssemblyResourceProvider and controller in my master MVC 4 project. I have also attached the whole solution itself here. Can anyone help to see what is going wrong? Thanks for any help or suggestions.

public class AssemblyResourceProvider : System.Web.Hosting.VirtualPathProvider
    {
        private bool IsAppResourcePath(string virtualPath)
        {
            string checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
            return checkPath.StartsWith("~/Plugin/", StringComparison.InvariantCultureIgnoreCase);
        }

        public override bool FileExists(string virtualPath)
        {
            return IsAppResourcePath(virtualPath) || base.FileExists(virtualPath);
        }

        public override VirtualFile GetFile(string virtualPath)
        {
            return IsAppResourcePath(virtualPath)
                ? new AssemblyResourceVirtualFile(virtualPath)
                : base.GetFile(virtualPath);
        }

        public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            return !IsAppResourcePath(virtualPath)
                ? base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart)
                : null;
        }
    }

    public class AssemblyResourceVirtualFile : VirtualFile
    {
        string path;

        public AssemblyResourceVirtualFile(string virtualPath) : base(virtualPath)
        {
            path = VirtualPathUtility.ToAppRelative(virtualPath);
        }

        public override Stream Open()
        {
            string[] parts = path.Split('/');
            string assemblyName = parts[2];
            string resourceName = parts[3];

            var assembly = Assembly.LoadFile(Path.Combine(HttpRuntime.BinDirectory, assemblyName));

            return assembly != null
                ? assembly.GetManifestResourceStream(resourceName)
                : null;
        }
    }

And my home controller:

public ActionResult Pluggable()
{
    //ViewBag.Name = name;
    return View("~/Plugin/PluginView1.dll/PluginView1.Views.Home.Pluggable.cshtml");
}

enter image description here

2012-04-05 16:17
by TruMan1
Yes, public override Stream Open() is not able to find the assembly and returns a null stream or the GetManifestResourceStream finds no resource with the name. This could happen if the cshtml file is not set to an Embedded Resource or your full namespace is wrong - Nick Bork 2012-04-05 16:19
I did remember to embed the resource and I believe my namespace is correct according to the other post - TruMan1 2012-04-05 16:55
Did you remember to copy the DLL in to the Bin folder? or where ever else your loading your plugins from - Nick Bork 2012-04-05 17:14
Yes thx. My master MVC app is referencing the project and ensured that the DLL is in fact in the bin folder there - TruMan1 2012-04-05 17:21
For some reason, it is choking on this even tho I never called this: ~/Plugin/PluginView1.dll/_ViewStart.cshtm - TruMan1 2012-04-05 17:35
My opinion: DON'T EVER DO THIS EVER. The better thing to so is use your source control to put the assets you want in your current project. Reading the code it looks like you are not finding the assembly and then returning a null stream so get rid if the return ? : at the end and let it blow up when you call getmanifestresourcestream. This will give you a better debug message. In fact get rid of all the inline ifs in the code because all the null results are just swallowing failure. Exceptions are good they tell us where our code is failing. Hiding them wont fix the underlying problem - Peter 2012-04-06 20:04


0

Here is my AssemblyResourceVirtualFile that I used in a project before:

public class AssemblyResourceVirtualFile : VirtualFile
{
    string path;
    public AssemblyResourceVirtualFile(string virtualPath) : base(virtualPath)
    {
        path = VirtualPathUtility.ToAppRelative(virtualPath);
    }
    public override System.IO.Stream Open()
    {
        string[] parts = path.Split('/');
        string assemblyName = parts[2];
        string resourceName = parts[3];

        assemblyName = Path.Combine(HttpRuntime.BinDirectory, assemblyName);

        System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(assemblyName);
        if (assembly != null)
        {
            Stream resourceStream = assembly.GetManifestResourceStream(resourceName);
            return resourceStream;
        }
        return null;
    }
}

Really the only difference is I've made it so you can stick break points in there and walk to see what it finds. Put your break point in and walk the code, is the assembly == null? If not, is resourceStream null?

2012-04-05 17:20
by Nick Bork
For some reason, it is choking on this event tho I never called this: ~/Plugin/PluginView1.dll/_ViewStart.cshtm - TruMan1 2012-04-05 17:34
Thats because the default behavior of Razor is to load the ViewStart to load the default settings (Layout file, etc - Nick Bork 2012-04-05 17:49
Ads