简体   繁体   English

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

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

I have a problem in asp.net. 我在asp.net中有问题。 In shopping cart I use Cookies If I add a product 1st time to cart it will create a row of that product so if I click again on that button of same product I want that it only increases a quantity of that product and don't create a new row in cookies Here is my code 在购物车中,我使用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);
}
}

You have several severe issues with this code. 此代码有几个严重的问题。

First, your code is vulnerable to a SQL Injection attack. 首先,您的代码容易受到SQL Injection攻击。 Your are concatenating strings to form your SQL query. 您正在串联字符串以形成SQL查询。 What if someone manipulated the command argument on the button so that its value is 1; update products set price = 0; 如果有人操纵按钮上的命令参数以使其值为1; update products set price = 0;怎样? 1; update products set price = 0; ? They just managed to execute code on your system! 他们只是设法在您的系统上执行代码! The way we fix that is by using parameterized queries. 我们修复该问题的方法是使用参数化查询。

Another issue is that you are storing product pricing information in the client's cookie. 另一个问题是您将产品定价信息存储在客户的cookie中。 Doesn't that sound dangerous? 听起来不危险吗? Any client with just a little know-how can modify their cookie so that all products cost $0. 任何仅有一点专业知识的客户都可以修改其Cookie,以便所有产品的价格均为0美元。 Instead, only store product ID and quantity in the cookie, then retrieve the product name and price yourself. 相反,仅将产品ID和数量存储在cookie中,然后自己检索产品名称和价格。

You've got a magic string in your code, "Addtocart". 您的代码“ Addtocart”中有一个魔术字符串。 If you ever wanted to update that, you've got to change it in multiple places. 如果您想更新它,则必须在多个位置进行更改。 Instead, create a constant for it, then reference that constant everywhere you need it. 而是为其创建一个常量,然后在需要它的任何地方引用该常量。 Then you'll only have one place where you need to update it. 这样,您只有一个地方需要更新它。

DataTables are bad to use. DataTables不好用。 They use up a lot of memory, they're difficult to work with, and just slower than using POCO's (Plain Old C# Objects) or "model" classes. 它们占用大量内存,难以使用,并且比使用POCO(普通C#对象)或“模型”类要慢。

You're storing your data in the cookie in a custom format. 您正在以自定义格式将数据存储在Cookie中。 That's going to be a pain in the ass to parse when you want to get the data back out of the cookie. 当您想从cookie中获取数据时,要进行解析很麻烦。 Instead, use JSON or some other simple format. 相反,请使用JSON或其他一些简单格式。

You're storing product prices as strings. 您将产品价格存储为字符串。 Don't do that! 不要那样做! You can't do math with strings. 您不能使用字符串进行数学运算。 When you work with money, use the decimal type. 使用货币时,请使用decimal类型。

Indent your code! 缩进您的代码! It makes reading it much easier. 它使阅读变得容易得多。

Here's your updated code fixing these issues: 这是您解决这些问题的更新代码:

First, we'll create a class that represents our product. 首先,我们将创建一个代表我们产品的类。 Notice the price is of type decimal . 注意价格是decimal类型。

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

    public string Name { get; set; }

    public decimal Price { get; set; }
}

This class will serve as a centralized location for retrieving data from our database about products. 此类将用作从我们的数据库中检索有关产品的数据的集中位置。

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;
        }
    }
}

These two classes will represent a particular product and quantity of that product that a user wants to purchase. 这两个类别将代表用户想要购买的特定产品和该产品的数量。 This can be safely stored with the user as it doesn't contain price information. 由于它不包含价格信息,因此可以安全地与用户一起存储。

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>();
    }
}

This constant should be put in some central location. 该常数应放在中央位置。

public constant string ShoppingCartCookieName = "Cart";

Now for the actual logic of our page: 现在了解页面的实际逻辑:

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;
    }
}

Notice that by the time I got done refactoring your add to cart logic, I didn't actually need to make a database call to obtain information about the product. 请注意,当我完成重构添加到购物车逻辑的时间时,实际上并不需要进行数据库调用来获取有关产品的信息。 So now it will run faster and be more efficient. 因此,现在它将运行得更快,效率更高。

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

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