Идеи нужны для переменных, которые используются на всех страницах сайта c # - PullRequest
0 голосов
/ 30 июля 2009

У меня есть сайт, на котором размещаются псевдо-субдомены. Каждый поддомен имеет набор настроек (т. Е. Имя строки, строка css, заголовок строки), к которым мне нужно получить доступ на всех страницах. Как лучше всего хранить их для легкого доступа?

Я не могу использовать webconfig, потому что разные субдомены имеют свою собственную коллекцию настроек, поэтому я храню настройки на сервере sql. Я думал о кэшировании всех настроек с другим именем кэша, но меня беспокоит проблема с памятью. Независимо от использования кэша, я понимаю, что мне нужно написать какой-то класс, где я выставляю каждый параметр как свойство.

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 30 июля 2009

Я делаю нечто подобное с некоторым программным обеспечением, которое я написал, и которое я размещаю на общем сервере. В зависимости от входящего домена, у меня может быть другой скин и некоторые параметры конфигурации.

В корне находится класс «Сайт», который имеет название сайта, описание и некоторую другую основную информацию. Затем он также хранит список атрибутов.

Таблицы выглядят так:

Create Table [Site](
    [Id]          uniqueidentifier default newSequentialId(),
    [Name]        nvarchar(128),
    [Description] nvarchar(512),
    Constraint pk_Site Primary Key (Id)
)

Create Table [Attribute](
    [Id]        int identity(1,1),
    [Key]       varchar(128),
    [Type]      varchar(16),
    [OwnerMask] int,
    Constraint pk_AttributeId Primary Key (Id),
    Constraint uq_AttributeKey Unique ([Key])
)

Create Table [AttributeValue](
    [OwnerId]     uniqueidentifier,
    [AttributeId] int,
    [Value]       nvarchar(512),
    Constraint pk_Owner_Attrib Primary Key (OwnerId, AttributeId)
)

Я использую Guids, потому что я хотел иметь возможность прикреплять атрибуты к различным объектам и искать их по идентификатору объекта. OwnerMask должен определить, для каких объектов допустимы различные атрибуты. Это было бы необязательно для вас.

Каждый класс, который может иметь атрибуты, реализует этот интерфейс:

public interface IPropertyContainer
{
    void AddProperty(Property property);
    string FindPropertyValue(string name);
    Property FindProperty(string name);
    void SetPropertyValue(string name, string value);
}

Я сожалею о разнице в именах (Атрибут и Свойство), но стало раздражающим иметь дело с тем фактом, что Атрибут также является предопределенным классом в .NET Framework. Класс Site реализует этот интерфейс.

Затем у меня есть служба, которая проверяет домен, на который поступает запрос, и проверяет базу данных, чтобы узнать, какой идентификатор сайта тоже отображается. Затем я загружаю объект сайта в HttpContext, используя HttpModule. Я включу код ниже, но, возможно, он не понятен вне контекста:

private static void AuthenticateRequestHandler(object sender, EventArgs e)
{
    HttpApplication app = sender as HttpApplication;

    if(app == null) return;

    Uri url = app.Request.Url;
    string domain = url.Host;
    string path = url.AbsolutePath.ToLower().Replace("default.aspx", "");

    IInjectionWrapper wrapper = new WindsorWrapper();
    ISiteProvider provider = wrapper.Resolve<ISiteProvider>();
    Site site = provider.FindSiteByDomain(domain);

    if (site == null)
        return;

    ActiveContext.Current.Site = site;
}

Система атрибутов позволяет вам прикреплять любые произвольные данные к вашему сайту, что приятно, но она опирается на «Волшебные строки», которые некоторым могут не нравиться, но в этом случае это меня не слишком беспокоит.

Пример того, как я использую это, в базовом классе для каждого объекта Page, я задаю тему так:

protected override void OnPreInit(EventArgs e)
{
    Page.Theme = ActiveContext.Current.Site.Theme;

    base.OnPreInit(e);
}

Свойство Theme заключает вызов одного из методов в интерфейсе IPropertyContainer.

public string Theme
{
    get { return FindPropertyValue("Theme") ?? "default"; }
}

Надеюсь, этот длинный пример дает вам отправную точку.

UPDATE

Я понимаю, что вы, возможно, не знакомы с HttpContext или с тем, что я делаю с классом ActiveContext. В основном я использую класс ActiveContext, чтобы обеспечить строго типизированную оболочку для коллекций HttpContext.Items и HttpContext.Sessio n.

Данные сеанса сохраняются от одного вызова к другому, но могут вызвать проблемы в ситуациях с балансировкой нагрузки. HttpContext.Items существует только на время текущего запроса. Вот код для моего ActiveContext класса, который можно было бы получить с любой страницы aspx, вызвав статический метод ActiveContext.Current

открытый класс ActiveContext: IActiveContext { частный сайт _site;

public static IActiveContext Current
{
    get
    {
        IActiveContext activeContext;

        activeContext = Context.Items["ActiveContext"] as ActiveContext;
        if (activeContext == null)
        {
            activeContext = new ActiveContext();
            Context.Items["ActiveContext"] = activeContext;
        }

        return activeContext;
    }
}

public Person AuthenticatedUser
{
    get
    {
        Person person = Context.Session["AuthenticatedUser"] as Person;
        return person;
    }
    set { Context.Session["AuthenticatedUser"] = value; }
}

public Site Site
{
    get { return Context.Items["CurrentSite"] as Site; }
    set { Context.Items["CurrentSite"] = value; }
}

private static HttpContext Context
{
    get
    {
        HttpContext context = HttpContext.Current;
        if (context == null)
            throw new Exception("HttpContext is null");

        return context;
    }
}

}

2 голосов
/ 30 июля 2009

Почему бы вам не создать подкласс Page или MasterPage, чтобы затем выставить свои свойства?

В файле C # ...

class MyPage : System.Web.UI.Page
{
    string PropertyName { get; set; }
}

Во всех файлах ASPX ...

<%@ Page Language="C#" Inherits="MyNamespace.MyPage" %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...