ASP.NET MVC3 приложение с возможностями CMS - PullRequest
2 голосов
/ 14 декабря 2011

Я изучаю ASP.NET MVC3 и создаю приложение с возможностями CMS - но столкнулся с некоторыми проблемами.

Основная идея заключается в том, что все страницы связаны с типом страницы, который в свою очередь имеетнабор свойств, связанных с ним.

Прекрасно работает, если я использую только строковые значения, но я хочу иметь возможность вводить все свойства (String, LongString, XhtmlString, Number и TrueFalse).

Это мои модели, которые я придумала.

public class Page
{
    public int PageId { get; set; }
    public int PageTypeId { get; set; }
    public string Name { get; set; }

    public PageType PageType { get; set; }

    public List<PropertyValues> Properties { get; set; }
}

public class PageType
{
    public int PageTypeId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public string Controller { get; set; }
    public string Action { get; set; }

    public List<PropertyDefinition> Properties { get; set; }
}

public class PropertyDefinition
{
    public int PropertyDefinitionId { get; set; }
    public string Name { get; set; }
    public string Type { get; set; } // NormalString, LongString, XhtmlString, Number, TrueFalse
}

public class PropertyValues
{
    public int PropertyValueId { get; set; }
    public int PageId { get; set; }
    public int PropertyDefinitionId { get; set; }

    public string ValueNormalString { get; set; } // input=text
    public string ValueLongString { get; set; } // textarea
    public string ValueXhtmlString { get; set; } // tinymce
    public int ValueNumber { get; set; } // input=text
    public bool ValueTrueFalse { get; set; } // input=checkbox

    public PropertyDefinition Definition { get; set; }
}

По сути, когда я нахожусь в моем виде, я хочу иметь возможность звонить, например,

@Page.Property["Whatever"]

иполучить значения.Я застрял с вышеизложенным, и не знаю, как действовать.

Редактировать:

С некоторой помощью из ответа, который я получил от Руси, я пришелсо следующим - который работает.Не знаете, есть ли лучшее решение проблемы.

У кого-нибудь есть предложения по улучшению моего решения?

Модели:

public class Page
{
    public int PageId { get; set; }
    public string Name { get; set; }

    public List<Property> Properties { get; set; }

    Dictionary<string, object> PageData = new Dictionary<string, object>();
    public object this[string name]
    {
        get
        {
            Property result = this.Properties.Find(
                delegate(Property p)
                {
                    return p.Name.Equals(name);
                });

            if (result != null)
            {
                switch (result.PropertyDefinition.Type)
                {
                    case "String":
                        return result.PropertyValue.ValueString;
                    case "LongString":
                        return result.PropertyValue.ValueLongString;
                    case "XHtmlString":
                        return result.PropertyValue.ValueXhtmlString;
                    case "Number":
                        return result.PropertyValue.ValueNumber;
                    case "Boolean":
                        return result.PropertyValue.ValueBoolean;
                    default:
                        return null;
                }
            }

            return null;
        }
        set
        {
            PageData[name] = value;
        }
    }
}

public class PropertyDefinition
{
    public int PropertyDefinitionId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Type { get; set; }
}

public class PropertyValue
{
    public int PropertyValueId { get; set; }
    public int PropertyId { get; set; }

    public string ValueString { get; set; }
    public string ValueLongString { get; set; }
    public string ValueXhtmlString { get; set; }
    public int ValueNumber { get; set; }
    public bool ValueBoolean { get; set; }
}

public class Property
{
    public int PropertyId { get; set; }
    public string Name { get; set; }
    public string Caption { get; set; }

    public Page Page { get; set; }
    public PropertyDefinition PropertyDefinition { get; set; }
    public PropertyValue PropertyValue { get; set; }

    public int PageId { get; set; }
    public int PropertyDefinitionId { get; set; }
    public int PropertyValueId { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public String Index()
    {
        List<Property> properties = new List<Property>();
        Property propertyOne = new Property {
            PropertyId = 1,
            Name = "Title",
            Caption = "Page Title",
            TestPageId = 1,
            PropertyValue = new PropertyValue {
                PropertyValueId = 1,
                PropertyId = 1,
                ValueString = "This is the page title"
            },
            PropertyDefinition = new PropertyDefinition {
                PropertyDefinitionId = 1,
                Name = "String",
                Description = "String (< 255 characters)",
                Type = "String"
            }
        };
        properties.Add(propertyOne);

        Page CurrentPage = new Page
        {
            TestPageId = 1,
            Name = "Testpage",
            Properties = properties
        };


        return CurrentPage["Title"].ToString();
    }

}

Ответы [ 3 ]

0 голосов
/ 14 декабря 2011

Если предположить, что модель, передаваемая строго типизированному представлению, имеет тип Page, тогда она должна быть просто @Model.Properties.Таким образом, ваше представление Razor выглядит примерно так:

@* set the model for the view to be of type Page *@
@model Page

@* to get the properties *@
@foreach(var prop in Model.Properties)
{
    <p>@prop.PageId</p>
}

Чтобы проиндексировать коллекцию Properties с использованием строки, я бы рекомендовал использовать Dictionary<string, PropertyDefinition> вместо List<PropertyDefintion> или сделать ее KeyedCollection<TKey, TItem>.

Вы можете решить создать свой собственный WebViewPage, который добавляет свойство Page, унаследовав от System.Web.Mvc.WebViewPage, а затем задав его как baseType в web.config подПапка видов

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <!-- Set your type here below -->
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
        <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
            <add namespace="System.Web.Configuration"/>
            <add namespace="System.ComponentModel.DataAnnotations"/>
        </namespaces>
    </pages>
</system.web.webPages.razor>
0 голосов
/ 14 декабря 2011

Рассматривали ли вы для изучения существующий код приложения CMS? Возможно, вы захотите взглянуть на такие проекты, как Orchard или даже Oxite, которые более не активно разрабатываются, но могут дать понимание.

0 голосов
/ 14 декабря 2011

В MVC вы должны хранить значения свойств в вашей модели, а не в представлении.

Подробнее о Model-View-Controller читайте в http://www.asp.net и http://www.manning.com/palermo3/ASP.NETMVC3iA_meap_ch01.pdf.

Удачи!

...