Доля частичных представлений для нескольких проектов в библиотеке классов не так проста. Прежде всего, необходимо создать виртуальный файл и провайдер виртуального
public class AspNetVirtualFile : VirtualFile
{
private string path;
public AspNetVirtualFile(string virtualPath)
: base(virtualPath)
{
path = VirtualPathUtility.ToAppRelative(virtualPath);
}
public override System.IO.Stream Open()
{
var parts = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var assemblyName = parts[2];
var resourceName = parts[3];
assemblyName = Path.Combine(HttpRuntime.BinDirectory, assemblyName);
var assembly = Assembly.LoadFile(assemblyName + ".dll");
if (assembly != null)
{
return assembly.GetManifestResourceStream(resourceName);
}
return null;
}
}
VirtualProvider
public class AspNetVirtualProvider : VirtualPathProvider
{
public const string StartPath = "~/UserControls/";
public const string Path = "~/UserControls/{0}/{1}";
public AspNetVirtualProvider() { }
private bool IsEmbeddedResourcePath(string virtualPath)
{
try
{
var checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
return checkPath.StartsWith(StartPath, StringComparison.InvariantCultureIgnoreCase);
}
catch
{
}
return false;
}
public override bool FileExists(string virtualPath)
{
return IsEmbeddedResourcePath(virtualPath) || base.FileExists(virtualPath);
}
public override VirtualFile GetFile(string virtualPath)
{
if (IsEmbeddedResourcePath(virtualPath))
{
return new AspNetVirtualFile(virtualPath);
}
else
{
return base.GetFile(virtualPath);
}
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
{
if (IsEmbeddedResourcePath(virtualPath))
{
return null;
}
else
{
return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
}
Посмотреть, что поставщик будет найти файлы в папке UserControls в этой общей .dll, вы можете изменить, если вы хотите. В Global.asax Application_Start:
System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new AspNetVirtualProvider());
Создание HtmlHelper, не забывайте о помощи System.Web.Mvc.Html:
public static class HtmlHelpers
{
public static void SharedRenderPartial(this HtmlHelper h, string assemblyName, string fileName, object model)
{
h.RenderPartial(String.Format(AspNetVirtualProvider.Path, assemblyName, fileName), model);
}
}
Теперь в вашем View вы можете сделать:
@{ Html.SharedRenderPartial("My.Qualified.Assembly", String.Format("My.Qualified.Assembly.UserControls.{0}", "_ViewName.cshtml"), Model); }
Теперь вы создаете cshtml в папке UserControls в проекте My.Qualified.Assembly, вам необходимо изменить файл BuildAction на EmbededResource. По вашему мнению, вам нужно будет объяснить, добавьте использование и @inherits System.Web.Mvc.WebViewPage.
Я ценю усилия, с которыми вы столкнулись, с ответом, но он быстро говорит мне, что это слишком много для того, чего я хочу достичь. – VictorySaber
Эта конфигурация вам нужно сделать только один раз, после этого вам просто нужно использовать. Если я понял ваш вопрос, ваши взгляды находятся в другом проекте? Оверкилл, который вы сказали, является решением, которое я сделал, или вы сдадите, чтобы поместить пользовательские элементы в другую библиотеку? Другой способ сделать это - скопировать ссылку на ваши общие файлы в ваш проект. –