Widoki w oddzielnych zespołach w ASP.NET MVC

Próbuję utworzyć webaplikację, w której chcę mieć możliwość podłączenia oddzielnych zespołów. Używam MVC preview 4 w połączeniu z Unity for dependency injection, którego używam do tworzenia kontrolerów z moich zestawów wtyczek. Używam WebForms (domyślnie aspx) jako mojego silnika widoku.

Jeśli chcę użyć widoku, utknąłem na tych, które są zdefiniowane w projekcie core, z powodu dynamicznej kompilacji części ASPX. Szukam odpowiedniego sposobu na umieszczenie Plików ASPX w inny montaż, bez konieczności przechodzenia przez cały etap wdrażania. Przegapiłem coś oczywistego? A może powinienem uciekać się do tworzenia moich poglądów programowo?


Update: zmieniłem zaakceptowaną odpowiedź. Mimo że odpowiedź Dale ' a jest bardzo dokładna, wybrałem rozwiązanie z innym dostawcą wirtualnej ścieżki. To działa jak urok, i zajmuje tylko około 20 linijek kodu w sumie myślę.

Author: tereško, 2008-08-21

4 answers

Zasadniczo jest to ten sam problem, co ludzie mieli z WebForms i próbując skompilować swoje pliki UserControl ASCX do biblioteki DLL. Znalazłem to http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx to może zadziałać również dla Ciebie.

 15
Author: Joseph Kingry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-29 20:34:48

Zajęło mi zbyt dużo czasu, aby to działało poprawnie z różnych próbek częściowych, więc oto Pełny kod potrzebny do uzyskania widoków z folderu widoków w bibliotece współdzielonej o strukturze podobnej do zwykłego folderu widoków, ale ze wszystkim ustawionym na budowanie jako osadzone zasoby. Użyje osadzonego pliku tylko wtedy, gdy zwykły plik nie istnieje.

Pierwsza linia Application_Start:

HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedViewPathProvider());

VirtualPathProvider

   public class EmbeddedVirtualFile : VirtualFile
{
    public EmbeddedVirtualFile(string virtualPath)
        : base(virtualPath)
    {
    }

    internal static string GetResourceName(string virtualPath)
    {
        if (!virtualPath.Contains("/Views/"))
        {
            return null;
        }



        var resourcename = virtualPath
            .Substring(virtualPath.IndexOf("Views/"))
            .Replace("Views/", "OrangeGuava.Common.Views.")
            .Replace("/", ".");

        return resourcename;

    }


    public override Stream Open()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();


        var resourcename = GetResourceName(this.VirtualPath);
        return assembly.GetManifestResourceStream(resourcename);
    }




}

public class EmbeddedViewPathProvider : VirtualPathProvider
{


    private bool ResourceFileExists(string virtualPath)
    {

        Assembly assembly = Assembly.GetExecutingAssembly();


        var resourcename = EmbeddedVirtualFile.GetResourceName(virtualPath);
        var result = resourcename != null && assembly.GetManifestResourceNames().Contains(resourcename);
        return result;
    }

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


    public override VirtualFile GetFile(string virtualPath)
    {

        if (!base.FileExists(virtualPath))
        {
            return new EmbeddedVirtualFile(virtualPath);
        }
        else
        {
            return base.GetFile(virtualPath);
        }

    }

}

Ostatnim krokiem, aby go uruchomić jest to, że sieć korzeniowa.Config musi zawierać odpowiednie ustawienia do przetwarzania silnie wpisanych widoków MVC, ponieważ nie będzie używany ten w folderze views:

<pages
    validateRequest="false"
    pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
    pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
    userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
  <controls>
    <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
  </controls>
</pages>

Wymagane jest kilka dodatkowych kroków, aby uruchomić go z Mono. Po pierwsze, musisz zaimplementować GetDirectory, ponieważ wszystkie pliki w folderze views są ładowane podczas uruchamiania aplikacji, a nie w razie potrzeby:

public override VirtualDirectory GetDirectory(string virtualDir)
    {
        Log.LogInfo("GetDirectory - " + virtualDir);
        var b = base.GetDirectory(virtualDir);
        return new EmbeddedVirtualDirectory(virtualDir, b);
    }

public class EmbeddedVirtualDirectory : VirtualDirectory
{
    private VirtualDirectory FileDir { get; set; } 

    public EmbeddedVirtualDirectory(string virtualPath, VirtualDirectory filedir)
        : base(virtualPath)
    {
        FileDir = filedir;
    }

    public override System.Collections.IEnumerable Children
    {
        get { return FileDir.Children; }
    }

    public override System.Collections.IEnumerable Directories
    {
        get { return FileDir.Directories; }
    }

    public override System.Collections.IEnumerable Files
    {
        get {

            if (!VirtualPath.Contains("/Views/") || VirtualPath.EndsWith("/Views/"))
            {
                return FileDir.Files;
            }

            var fl = new List<VirtualFile>();

            foreach (VirtualFile f in FileDir.Files)
            {
                fl.Add(f);
            }


            var resourcename = VirtualPath.Substring(VirtualPath.IndexOf("Views/"))
.Replace("Views/", "OrangeGuava.Common.Views.")
.Replace("/", ".");

            Assembly assembly = Assembly.GetExecutingAssembly();

            var rfl = assembly.GetManifestResourceNames()
                .Where(s => s.StartsWith(resourcename))
                .Select(s => VirtualPath + s.Replace(resourcename, ""))
                .Select(s => new EmbeddedVirtualFile(s));
            fl.AddRange(rfl);

            return fl;
        }
    }
}

Wreszcie, silnie wpisane widoki będą prawie, ale nie do końca działać idealnie. Model będzie traktowany jako obiekt nieopisany, więc aby uzyskać mocne odpisywanie musisz zacząć współdzielone poglądy od czegoś takiego jak

<% var Model2 = Model as IEnumerable<AppModel>;  %>
 29
Author: Tom Clarkson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-02 10:19:18
protected void Application_Start()
{
    WebFormViewEngine engine = new WebFormViewEngine();

    engine.ViewLocationFormats = new[] { "~/bin/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };
    engine.PartialViewLocationFormats = engine.ViewLocationFormats;

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(engine);

    RegisterRoutes(RouteTable.Routes);
}

Ustaw właściwość' Copy to output 'widoku na' Copy always '

 12
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-03 20:29:31

Dodatek do wszystkich, którzy wciąż szukają Świętego Graala: zbliżyłem się nieco do znalezienia go, jeśli nie jesteś zbyt przywiązany do WebForms viewengine.

Ostatnio wypróbowałem Spark viewengine. Poza tym, że jest całkowicie niesamowity i nie wróciłbym do webforms, nawet gdybym był threathened, zapewnia również kilka bardzo ładnych hooków dla modułowości aplikacji. Przykładem w ich dokumentach jest użycie Windsora jako kontenera IoC, ale nie wyobrażam sobie, aby było to o wiele trudniejsze, jeśli chcesz podejść inaczej.

 2
Author: Erik van Brakel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-05 18:33:19