tldr>一旦选择了客户,所有其他控制器如何始终在该客户的“上下文”中执行其操作,而无需手动传递ID?
我正在试图找出“正确”的方法来处理整个控制器(或更多)都依赖于前一个控制器的想法的情况。例如,假设您正在构建某种客户管理系统。可能有各种客户功能,可能位于CustomerController上。但是当你进入订单管理时,你可能想要一个OrderController。
如果您只有一个OrderController,您的方法可能如下所示:
public ActionResult Edit(string id){...}
id是订单的ID,对吧?在我需要回到客户的时候,我有点失落。这就像发生的所有行为的“背景”都在客户中。您可以通过始终将客户ID添加到操作(URL)来执行此操作:
http://site.com/Orders/Edit/1234?customerId=abc
但是,抓住这个价值并将其干扰到每一个行动似乎都变得相当繁琐。有像Session这样的选项,但这看起来很草率。
这样做的正确方法是什么?
答案 0 :(得分:3)
您可以通过在会话周围编写一个包装器来减少一般会话的不稳定性,这会暴露强类型的属性。
//Sloppy weak typing:
int userId = (int)HttpContext.Current.Session["UserId"];
//Strongly typed goodness
int userId = SessionWrapper.UserId;
答案 1 :(得分:0)
会话是一个存储这类东西的地方。
您还可以使用可扩展的分布式缓存(http://msdn.microsoft.com/library/cc645013.aspx)。来自上面链接的示例代码
// CacheFactory class provides methods to return cache objects
// Create instance of CacheFactory (reads appconfig)
DataCacheFactory fac = new DataCacheFactory();
// Get a named cache from the factory
DataCache catalog = fac.GetCache("catalogcache");
//-------------------------------------------------------
// Simple Get/Put
catalog.Put("toy-101", new Toy("thomas", .,.));
// From the same or a different client
Toy toyObj = (Toy)catalog.Get("toy-101");
// ------------------------------------------------------
// Region based Get/Put
catalog.CreateRegion("toyRegion", true);
// Both toy and toyparts are put in the same region
catalog.Put("toy-101", new Toy( .,.), "toyRegion");
catalog.Put("toypart-100", new ToyParts(…), "toyRegion");
Toy toyObj = (Toy)catalog.Get("toy-101", "toyRegion");
答案 2 :(得分:0)
将会话信息序列化为加密会话cookie是另一种解决方案。好处是能够避免消耗服务器资源并实现相同的目标:
private void setSessionCookie() {
HttpCookie ck = new HttpCookie(XConstants.X_SESSION_COOKIE_KEY) {
Expires = DateTime.Now.AddMinutes(_sessionInfo.SessionTimeoutMinutes)
};
DateTime now = DateTime.UtcNow;
_sessionInfo.SessionLastValidatedAt = now;
ck.HttpOnly = true; // server-only cookie
ck["LastCheck"] = now.ToString(XConstants.XDATEFORMAT);
ck["Content"] = new Cipher().Encrypt(Serializer.Serialize(_sessionInfo).OuterXml,
ConfigurationManager.AppSettings[XConstants.X_APPKEY_KEY]);
System.Web.HttpContext.Current.Response.Cookies.Add(ck);
}
答案 3 :(得分:0)
如果您确实希望避免将值存储到会话中,则可以使用处理该值的操作过滤器。我曾经使用过这种方法,它是这样的:
现在您的客户ID很容易保留在URL中,即使您没有手动将其添加到所有链接。如果需要在操作方法中使用customer id,只需添加具有正确名称的参数即可。即使您不将其作为参数,它也会保留在动作方法调用上。
如果您想更进一步,在新的操作过滤器中,您可以从数据库中获取数据并将其添加到操作参数,而不是仅添加ID。这样您就可以进一步简化操作方法。