widok MVC generowany na podstawie XML-a

0

Hej,

potrzebne mi jest rozwiązanie w którym dynamicznie będę tworzył widoki w zależności od danych otrzymanych z zewnątrz. Tzn: czasem będą to dwa tekstowe pola, czasem pola numeryczne, czasem datowe etc.
Myślałem o zastosowaniu XML-a, udało mi się znaleźć bardzo prsoty przykład jednakże nie bardzo widzę inne materiały... Czy moglibyście mnie czymś wspomóc? Jak się do tego zabrać etc.

Tutaj jest link który znalazłem: http://blog.kurtschindler.net/dynamic-forms-with-asp-net-mvc-and-xml/

1

Taka luźna myśl jak masz MVC i część modelu podmienił na plik np. xml i za pomocą jakiegoś zmyślnego kontrolera parsował i generował dane na widok(kontrolki). Jak by to tak na to spojrzeć nie wydaje się to jakoś skomplikowane. Przynajmniej jak bym próbował iść w tą stronę. Tak mi się nasunęło nie mówię ze tak powinno się robić. ;)

0

Udało mi się to zrobić w ten sposób:

  public ActionResult Index()
        {
            XElement xml = XElement.Load(Server.MapPath("~/App_Data/form.xml")); //.Load("~/Content/form.xml");
            ViewData["xml"] = xml;
            return this.View();
        }

xml:

<?xml version="1.0" encoding="utf-8" ?>
<form name="form1">
<section number="1">
<field type="text" name="First name" class="textbox" />
</section>
<section number="2">
<field type="text" name="Biography" class="textarea" />
</section>
</form>

następnie dodaje do folderu Shared kolejny folder i nazywam go "EditorTemplates" w którym mam:
checkbox.cshtml:

@Html.CheckBox("name")

oraz textbox.cshtml:

@Html.TextBox("name")

następnie w widoku Index mam:

@using System.Xml.Linq
@using Microsoft.Ajax.Utilities
@{
XElement xml = (XElement)ViewData["xml"];   
 }

@using (Html.BeginForm())
{


    var q = from s in xml.Descendants("section") select s;

    foreach (var sec in q)
    {
        <fieldset>
            <legend>Section @sec.Attribute("number").Value</legend>
            <table>
                @{
                    var qq = from f in sec.Descendants("field") select f;
                    foreach (XElement field in qq)
                    {
                        <tr>
                            <td>  @Html.Editor("", (string)field.Attribute("class"))</td>
                        </tr>
                    
                    }
                }
                
            </table>
        </fieldset>
    }
<input type="submit" value="submit"/>
}

co myślisz?

1

Jak dla mnie koncepcja jest słuszna. ;)

0

Ja bym nie wymyslal kola od nowa, przegladnal jakiegos CMS'a darmowego, np N2CMS. Wykorzystal jego mechanizmy i wprowadzil nowa warstwe - parser, ktory przeksztalci XMLa do formatu zrozumialego dla tego CMSa.

0

Problem polega na tym że to nie jest ot taki sobie projekt... Generowanie XML-a to jakieś 5% tego co potrzebuje, to co już mam powyżej w 110% mi wystarcza :) ale dzięki za radę! :)

0

Pojawił się pewien problem i nie wiem jak to rozwiązać... a mianowicie jak potem obsłużyć dane z takiego formularza... ? normalnie miałbym model z polami i tyle...a tutaj nie mam modelu...jakieś pomysły?

0

Musisz napisac sobie custom model binder

0

a miałbyś może pomysł czy dało by się tak napisać taki model binder aby operował o to co jest w XML ?

W czym mam problem: będę miał XML, na podstawie którego wygeneruje widok... ale potem chciałbym wygenerować na jego podstawie model i obsłużyć ten model w kontrolerze (czyli pobrać dane wpisane przez usera do widoku) i chciałbym to trochę zautomatyzować tak abym nie musiał tworzyć klasy modelu, tylko aby działało to na podstawie XMLa, ewentualnie mogę dopisać jakiś specjalny parser to XMLa który go przerobi odpowiednio (np. w Dictionary<nazwa_pola, typ_pola>)

1

Zrob sobie jakis jeden model "XmlFormatModel", ktory wlasnie bedzie zawieral jakas liste/drzewo obiektow typu "XmlFormatModelElement" z jakimis wlasciwosciami: Typ pola, nazwa, wartosc etc. Dodatkowo daj w XmlFormatModel wlasciwosc TypModelu, ktory bedzie mowil co to wlasciwie jest - uzytkownik, zamowienie, cokolwiek tam masz.
Nastepnie sobie utworz klase-fabryke, do ktorej dajesz jako parametr XmlFormatModel i ktora na podstawie TypuModelu, bedzie tworzyla i zwracala konkretny model, ktory sobie dalej obsluzysz tak jak chcesz.

0

To teraz się rodzą dwa pytania: 1. czy mógłbyś mi pomóc i napisać trochę kodu tej klasy-fabryki albo chociaż powiedz czego mam szukać. 2.Co ta fabryka tak naprawdę mi zwróci? bo przecież nie plik klasy C# w którym będą pola..

0
    public enum ModelType
    {
        USER,
        ORDER
    };
    public class XmlFormatModel
    {
        public ModelType ModelType { get; set; }
    }
    public abstract class ConcreteModel
    {

    }
    public class OrderModel : ConcreteModel
    {
        public int Id { get; set; }
    }
    public interface IConcreteModelBuilder
    {
        ConcreteModel Build(XmlFormatModel model);
    }
    public class OrderModelBuilder
    {
        public ConcreteModel Build(XmlFormatModel model)
        {
            var model = new OrderModel { Id = 1 };
            //tworzenie obiektu
        }
    }
    public class ConcreteModelFactory
    {
        public T CreateConcreteAs<T>(XmlFormatModel model) where T : ConcreteModel
        {
            if (model.ModelType == ModelType.ORDER)
            {
                var result = new OrderModelBuilder().Build(model);
                return (T)result;
            }
            else return default(T);
        }

    }

Jak chcesz od razu scastowany obiekt przekazac do dalszych warstw to uzywasz sobie np CreateConcreteAs<OrderModel>(xmlFormatModel) - ale musisz wiedziec na co rzutujesz.
Jak dalsza warstwa sobie to zrzutuje po swojemu to zrob sobie metode niegeneryczna, ktora zwroci obiekt typu ConcreteModel, a w kolejnej warstwie zrzutujesz sobie to na interesujacy Cie typ.
Ewentualnie mozna sie pobawic refleksja i od razu castowac jak trzeba na podstawie ModelType ale to juz wiecej zabawy.

0

Czy mógłbyś mi to jeszcze wytłumaczyć?

1 użytkowników online, w tym zalogowanych: 0, gości: 1