繁体   English   中英

如何解决asp.net中的cookie问题

[英]How to Resolve cookies issue in asp.net

我在asp.net中有问题。 在购物车中,我使用Cookies。如果我第一次添加产品到购物车,它将创建该产品的一行,因此,如果我再次单击同一产品的该按钮,我希望它只会增加该产品的数量,而不创建Cookie中的新行这是我的代码

protected void btnAddtoCart_Click(object sender, EventArgs e)
{
Button obj = (Button)sender;
string id = obj.CommandArgument.ToString();
DataTable dt = d.select("select * from product where product_id="+id+"");
foreach (DataRow dr in dt.Rows)
{
product_id = Convert.ToInt32(dr["product_id"].ToString());
Product_name = dr["product_name"].ToString();
price = dr["price"].ToString();
image1 = dr["image1"].ToString();
}
quantity = 1;
if (Request.Cookies["Addtocart"] == null)
{
Response.Cookies["Addtocart"].Value = product_id.ToString() +" , "+ Product_name.ToString() + "," + price.ToString() + "," + quantity.ToString() + "," + image1.ToString();
Response.Cookies["Addtocart"].Expires = DateTime.Now.AddHours(1);
}
else
{
Response.Cookies["Addtocart"].Value = Request.Cookies["Addtocart"].Value +"|" + product_id.ToString() + " , " + Product_name.ToString() + "," + price.ToString() + "," + quantity.ToString() + "," + image1.ToString();
Response.Cookies["Addtocart"].Expires = DateTime.Now.AddHours(1);
}
}

此代码有几个严重的问题。

首先,您的代码容易受到SQL Injection攻击。 您正在串联字符串以形成SQL查询。 如果有人操纵按钮上的命令参数以使其值为1; update products set price = 0;怎样? 1; update products set price = 0; 他们只是设法在您的系统上执行代码! 我们修复该问题的方法是使用参数化查询。

另一个问题是您将产品定价信息存储在客户的cookie中。 听起来不危险吗? 任何仅有一点专业知识的客户都可以修改其Cookie,以便所有产品的价格均为0美元。 相反,仅将产品ID和数量存储在cookie中,然后自己检索产品名称和价格。

您的代码“ Addtocart”中有一个魔术字符串。 如果您想更新它,则必须在多个位置进行更改。 而是为其创建一个常量,然后在需要它的任何地方引用该常量。 这样,您只有一个地方需要更新它。

DataTables不好用。 它们占用大量内存,难以使用,并且比使用POCO(普通C#对象)或“模型”类要慢。

您正在以自定义格式将数据存储在Cookie中。 当您想从cookie中获取数据时,要进行解析很麻烦。 相反,请使用JSON或其他一些简单格式。

您将产品价格存储为字符串。 不要那样做! 您不能使用字符串进行数学运算。 使用货币时,请使用decimal类型。

缩进您的代码! 它使阅读变得容易得多。

这是您解决这些问题的更新代码:

首先,我们将创建一个代表我们产品的类。 注意价格是decimal类型。

public class Product
{
    public string Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }
}

此类将用作从我们的数据库中检索有关产品的数据的集中位置。

public class ProductRepository
{
    private readonly string _connectionString;

    public ProductRepository(string connectionString)
    {
        _connectionString = connectionString;
    }

    public Product GetProductById(string productId)
    {
        using(var connection = new SqlConnection(_connectionString))
        {
            // I'm going to use Dapper here because it's super handy
            // https://github.com/StackExchange/Dapper
            var product = connection.QueryOne<Product>(
                @"select
                      Id,
                      Name,
                      Price
                  from
                      products
                  where
                      Id = @ProductId",
                new { ProductId = productId });

            return product;
        }
    }
}

这两个类别将代表用户想要购买的特定产品和该产品的数量。 由于它不包含价格信息,因此可以安全地与用户一起存储。

public class CartItem
{
    public string ProductId { get; set; }

    public int Quantity {get; set; }
}

public class Cart
{
    public Dictionary<string, CartItem> Items { get; set; }

    public Cart()
    {
        Items = new Dictionary<string, CartItem>();
    }
}

该常数应放在中央位置。

public constant string ShoppingCartCookieName = "Cart";

现在了解页面的实际逻辑:

protected void btnAddtoCart_Click(object sender, EventArgs e)
{
    var addToCartButton = (Button)sender;
    // notice I don't call .ToString() below
    // because Button.CommandArgument is already a string
    var productId = addToCartButton.CommandArgument;            
    var cart = GetShoppingCartFromCookie();

    if(cart.Items.ContainsKey(productId)
    {
        //their cart already contained this product, so let's bump the quantity
        cart.Items[productId].Quantity += 1;
    }
    else
    {
        //their cart didn't contain this product, so we'll add it
        var cartItem = new CartItem { ProductId = productId, Quantity = 1 };
        cart.Items.Add(cartItem.ProductId, cartItem);                           
    }

    SaveShoppingCartToCookie(cart);
}

private void SaveShoppingCartToCookie(Cart cart)
{
    var cartJson = JsonConvert.SerializeObject(cart); //using Newtonsoft.Json
    Response.Cookies[ShoppingCartCookieName].Value = cartJson;
    Response.Cookies[ShoppingCartCookieName].Expires = DateTime.Now.AddHours(1);
}

private Cart GetShoppingCartFromCookie()
{
    if (Request.Cookies[ShoppingCartCookieName] == null)
    {
         return new Cart();
    }
    else
    {
        var existingCartJson = Response.Cookies[ShoppingCartCookieName].Value;
        // you may wish for some logic here to make sure the JSON can be converted
        // to a Cart since a user could have modified the cookie value.
        var cart = JsonConvert.DeserializeObject<Cart>(existingCartJson);            
        return cart;
    }
}

请注意,当我完成重构添加到购物车逻辑的时间时,实际上并不需要进行数据库调用来获取有关产品的信息。 因此,现在它将运行得更快,效率更高。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM