我正在检索用户特定的数据,例如ViewData["CartItems"] = Session["CartItems"];
,每个请求都包含字符串文字。我应该使用常量吗?
如果是,我应该如何实施经常使用的字符串文字,是否会显着影响高流量网站的性能?
Related question无法解决ASP.NET MVC或Session
。
答案 0 :(得分:3)
使用常量,因为如果输入错误,编译器会给你一个错误,而错误输入的字符串只会给你带来错误的错误。
性能差异可能很小,很难衡量。
答案 1 :(得分:3)
使用常量的原因与可维护性有关,而与性能无关。无论哪种方式,表现都差不多。
使用字符串文字,你永远不能故意或巧合地判断它是否与另一个字符串文字相同,所以当需要更改一个时,你不知道要改变哪些字符。但是如果你有常量值,你只需在一个地方进行更改。
为:
ViewData["username"] = Session["username"];
好:
const UserNameSessionKey = "username";
const UserNameViewDataKey = "username";
ViewData[UserNameViewDataKey] = Session[UserNameSessionkey];
现在想象一下,将会话密钥的值更改为“userName”,而不想为任何viewdata密钥更改它...
答案 2 :(得分:1)
让我们进一步了解可维护性。我将引用关于使用Session的其他答案:
让我们说我们想要存储购物车是我们的ASP.NET MVC应用程序的Session。它将存储在Session["ShoppingCart"]
中,但我们需要简单,强类型的访问和高可测试性:
首先我们定义接口:
public interface ISessionWrapper
{
List<CartItem> ShoppingCart { get; set; }
}
然后我们进行HttpContext实现:
public class HttpContextSessionWrapper : ISessionWrapper
{
private T GetFromSession<T>(string key)
{
return (T) HttpContext.Current.Session[key];
}
private void SetInSession(string key, object value)
{
HttpContext.Current.Session[key] = value;
}
public List<CartItem> ShoppingCart
{
get { return GetFromSession<List<CartItem>>("ShoppingCart"); }
set { SetInSession("ShoppingCart", value); }
}
}
GetFromSession和SetInSession是辅助方法,可以更轻松地在Session中获取和设置数据。它们可以很容易地重用来访问Session中的其他字段。
然后我们定义我们的基本控制器(适用于ASP.NET MVC):
public class BaseController : Controller
{
public ISessionWrapper SessionWrapper { get; set; }
public BaseController()
{
SessionWrapper = new HttpContextSessionWrapper();
}
}
如果你想使用Session outside controller,你只需创建或注入新的HttpContextSessionWrapper()。
您可以在Controller测试中将SessionWrapper替换为ISessionWrapper mock,因此它不再依赖于HttpContext。会话也更容易使用,因为您拨打(List<CartItem>)Session["ShoppingCart"]
而不是致电SessionWrapper.ShoppingCart
。它看起来更好,不是吗?
如果你没有使用模型类进行视图,我认为使用模型类更好,你可以对ViewData做同样的事情:
public interface IViewDataWrapper
{
List<CartItem> ShoppingCart { get; set; }
}
public class ViewDataWrapper : IViewDataWrapper
{
}
public class BaseController : Controller
{
public IViewDataWrapper ViewDataWrapper { get; set; }
public BaseController()
{
IViewDataWrapper = new ViewDataWrapper();
}
}
然后只是在控制器中:
ViewDataWrapper.ShoppingCart = SessionWrapper.ShoppingCart
或者如果您决定不使用ViewData和特定型号:
Model.ShoppingCart = SessionWrapper.ShoppingCart
简单地在视图中(如果为视图定义基类并引入此接口):
<%= ViewDataWrapper.ShoppingCart %>
或
<%= Model.ShoppingCart %>
没有错误输入的字符串,强类型,外观漂亮。
答案 3 :(得分:0)
只是一个简单的注释,但很多更好的例子都有一类包含字符串常量的SessionKeys。这也有助于单元测试,因为您可以在必要时调用单元测试中的常量。
E.g。 (只有一个键,但显然你可以添加更多
public class SessionKeys
{
public const string UserDto = "UserDto";
}
这样使用(我使用SessionStateWrapper)
UserDto userDto = _sessionStateWrapper.GetItem(SessionKeys.UserDto) as UserDto;
答案 4 :(得分:0)
根据this benchmark字典键的长度,较短的键更快。引用这里:
更短的查找键是否明显更快?随着密钥越来越短,查找时间越来越快:
其中: