我有一个网站,提供基于伪子域的网站。每个子域都有一组我需要在所有页面上访问的设置(即String name,string css,string title)。存储它们以便于访问的最佳方法是什么?
我无法使用webconfig,因为不同的子域有自己的设置集合,所以我在sql server上存储设置。我想过用不同的缓存名称缓存所有设置,但我担心内存耗尽。无论使用缓存我理解我需要编写某种类,我将每个设置公开为属性。
有什么想法吗?
答案 0 :(得分:3)
我做了类似的事情,我写的是我在共享服务器上托管的软件。根据进入的域名,我最终得到了不同的皮肤和一些配置选项。
根目录是“站点”类,它具有站点标题,描述和一些其他基本信息。然后它还保留了属性列表。
表格如下:
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,因为我希望能够将属性附加到不同的对象,并能够通过对象ID查找它们。 OwnerMask用于确定不同属性对哪些对象有效。这对你来说是可选的。
每个可以拥有Attributes的类都实现了这个接口:
public interface IPropertyContainer
{
void AddProperty(Property property);
string FindPropertyValue(string name);
Property FindProperty(string name);
void SetPropertyValue(string name, string value);
}
我对名称差异(属性与属性)感到遗憾,但是处理Attribute也是.NET Framework中的预定义类这一事实变得很烦人。 Site类实现了这个接口。
然后我有一个服务来检查请求进入的域并检查数据库以查看映射的站点ID。然后我使用HttpModule将站点对象加载到HttpContext中。我将包含下面的代码,但它可能不完全脱离上下文:
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;
}
属性系统允许您将任意数据附加到您的站点,这很好,但它确实依赖于某些可能不喜欢的“魔术字符串”,但在这种情况下它并没有太多困扰我。 / p>
我如何使用它的示例是在每个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"; }
}
希望这个冗长的例子给你一个跳跃点。
我意识到您可能不熟悉HttpContext
或我正在使用ActiveContext
课程。基本上我使用ActiveContext
类在HttpContext.Items
和HttpContext.Sessio
n个集合周围提供强类型包装。
会话数据从一次调用持续到下一次调用,但在负载平衡情况下可能会导致问题。 HttpContext.Items
仅在当前请求期间存在。以下是我的ActiveContext
类的代码,可以通过调用静态方法ActiveContext.Current
public class 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;
}
}
}
答案 1 :(得分:2)
为什么不将Page
或MasterPage
作为子类,然后展示您的属性?
在C#文件中......
class MyPage : System.Web.UI.Page
{
string PropertyName { get; set; }
}
在所有ASPX文件中......
<%@ Page Language="C#" Inherits="MyNamespace.MyPage" %>