我正在寻找查询字符串的安全替代方法,我将参数传递给同一控制器上的控制器方法并将其作为视图返回。
分类视图:
@foreach (Project.Framework.ModelClasses.productCategories productCategories in ViewBag.Categories)
{
@Html.ActionLink(productCategories.description, "Products", "Shop", new { id = "", categoryID = productCategories.categoryID, description = productCategories.description }, null)
}
控制器方法:
public ActionResult Products(string categoryID, string keyword, string description)
{
ViewBag.appPath = ConfigurationManager.AppSettings["appPath"].ToString();
Methods Methods = new Methods();
Methods.tokenHeader = (string)Session["token"];
Methods.cookieContainer = (CookieContainer)Session["cookies"];
Response shopnowProductsResponse = Methods.shopnowProductsGet(categoryID, keyword);
if (shopnowProductsResponse.Code == "000")
{
List<product> products = new List<product>();
products = (List<product>)shopnowProductsResponse.Data;
string FPRFlag = "0";
foreach (product product in products)
{
if (FPRFlag != "1")
{
if (product.FPRFlag == "1")
{
FPRFlag = product.FPRFlag;
}
}
else
{
goto nextState;
}
}
nextState:
ViewBag.FPRFlag = FPRFlag;
ViewBag.Description = description;
ViewBag.Products = products;
}
return View();
}
注意:关键字是可选的
答案 0 :(得分:1)
假设您只想以最终用户无法从URL中删除所有产品数据列表的方式对这些链接进行编码,您可以通过在链接中使用替代代码来实现此目的。我使用哈希值:
@foreach (Project.Framework.ModelClasses.productCategories category in ViewBag.Categories)
{
@Html.ActionLink(category.description, "Products", "Shop",
new {
hc = category.categoryID.GetHashCode()
})
}
然后在控制器上查找哈希码而不是categoryID
。
这还有两个问题:
可以使用中间操作修复第一个操作,该操作将哈希代码转换回categoryID
并将结果存储在Session
存储中,然后重定向到Products
页面:
public ActionResult SetCategory(int hc)
{
string catID = HashToCategoryID(hc);
Session["categoryID"] = catID;
return RedirectToAction("Products");
}
这不仅会将用户的浏览器返回到Products
页面,还会确保(在大多数情况下)SetCategory
URL甚至不会显示在浏览器历史记录中。通常情况下,浏览器历史记录甚至不会显示它首先离开Products
页面,因此点击Back
按钮会将它们从页面移到最初到达之前的任何位置英寸
另一个问题 - 哈希代码没有改变 - 可以通过以下两种方式修复:使用将从访问更改为访问的值(如会话ID)更新哈希,或者生成随机值并将其存储在{{存储用于查找。
例如:
Session
现在每次加载页面时,您都会获得一组不同的哈希值。您的链接生成将变为:
// after loading your products:
// something to salt the hash codes with:
string salt = (DateTime.Now - DateTime.Today).TotalMilliseconds.ToString();
// generate hash codes for all the product categories
var hashcodes = products.Select(p => new { h = (salt + p.categoryID).HashCode(), c = p.categoryID });
// create hash->categoryID dictionary and save in Session
var hashtocat = hashcodes.ToDictionary(hc => hc.h, hc => hc.c);
Session["HashToCategory"] = hashtocat;
// create categoryID->hash dictionary and save in ViewBag
var cattohash = hashcodes.ToDictionary(hc => hc.c, hc => hc.h);
ViewBag["CategoryToHash"] = cattohash;
实际上,您现在有一个一次性使用代码列表,每次用户重新访问@{ // grab hashcode dictionary from ViewBag
Dictionary<string, int> hashcodes = ViewBag["CategoryToHash"] as Dictionary<string, int>;
}
@foreach (Project.Framework.ModelClasses.productCategories category in ViewBag.Categories)
{
@Html.ActionLink(product.description, "SetCategory", new { hc = hashcodes[product.categoryID] })
}
页面时,该代码将过期并替换为新代码。对于同一类别,获得相同代码多次工作的几率是无穷小的,除非从同一会话中单击链接,否则它将失败。
说到失败......你需要在那里添加一堆错误处理。