Link to home
Start Free TrialLog in
Avatar of Jay
Jay

asked on

Dont allow user to select amt greater than given 'qty'

If user selects 5 on ddl and only 4 event participants are displayed, there will be a label asking user to select qty that is lower!! Now, when I click the button nothing changes and there is also a line underlining eventParticipants.
- The end of the cookies line are red too, and I think there is a problem with the image.url part?
code behind for the button
  protected void btnAdd_Click(object sender, EventArgs e)
    {
        var id = Convert.ToInt32(lblItemNr.Text);
        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }
        con.Open();
        SqlCommand cmd1 = con.CreateCommand();
        cmd1.CommandType = CommandType.Text;
        cmd1.CommandText = "update EventDetail set eventParticipants=eventParticipants-" + ddlAmount.Text + " where EventDetail_ID=" + id;
        cmd1.ExecuteNonQuery();
        Response.Redirect("Detail.aspx?id=" + id.ToString());
        //below are the codes with problems (eventParticipants)...
        if(Convert.ToInt32(ddlAmount.Text) > Convert.ToInt32(eventParticipants))
        {
            l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "";

            if (Request.Cookies["aa"] == null)
            {
                Response.Cookies["aa"].Value = lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ImageUrl.ToString());
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
            else
            {
                Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|" + lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ImageUrl.ToString());
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
        }
    }

Open in new window

Here are some codes that may be useful
  private void FillPage()
    {
        if (Request.QueryString["id"] == null)
        {
            Response.Redirect("Events.aspx");
        }
        else
        {
            //get selected event's data
            if (!String.IsNullOrWhiteSpace(Request.QueryString["id"]))
            {
                int id = Convert.ToInt32(Request.QueryString["id"]);
                EventDetail Detail = new EventDetail();
                EventDetail detail = Detail.getEventDetail(id);
                if (detail == null)
                {
                    Response.Write("<script>alert('No event found');</script>");
                    return;
                }
                //fill pg w data
                lblDate.Text = detail.eventDate;
                lblLocation.Text = detail.eventLocation;
                lblStartTime.Text = detail.startTime;
                lblEndTime.Text = detail.endTime;
                lblParticipants.Text = detail.eventParticipants.ToString();
                lblPrice.Text = "$" + detail.eventPrice;
                lblTitle.Text = detail.eventDetailName;
                lblDescription.Text = detail.eventDesc;
                lblItemNr.Text = id.ToString();
                imgEvent.ImageUrl = "~/EventImages/Events/" + detail.eventImage;
                //fill amt ddl w numbers 1-20
                int[] amount = Enumerable.Range(1, 20).ToArray();
                ddlAmount.DataSource = amount;
                ddlAmount.AppendDataBoundItems = true;
                ddlAmount.DataBind();
            }
        }
    }

Open in new window

Avatar of ste5an
ste5an
Flag of Germany image

You haven't declared eventParticipants in your method.. you also don't read any value from your SqlCommand into this variable.
Avatar of Jay
Jay

ASKER

I changed to
 if(Convert.ToInt32(ddlAmount.Text) > Convert.ToInt32(lblParticipants.Text))
        {
            l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "";
            if (Request.Cookies["aa"] == null)
            {
                Response.Cookies["aa"].Value = lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ToString();
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
            else
            {
                Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|" + lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ToString();
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
        } 

Open in new window


However after using the drop down list to select a bigger qty than the available qty, there is still no label to tell me to select a lower qty !!
Avatar of Jay

ASKER

is it because I used cookies?? if so, how do I modify the codes so that the label comes out ??
1 - You also do not need to use .ToString() on the .Text property. Simplify these lblTitle.Text.ToString() to just lblTitle.Text

2 - It might be cleaner to use string interpolation. So instead of this:
Response.Cookies["aa"].Value = lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ToString();

Open in new window

You can just have this:
Response.Cookies["aa"].Value = $"{lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}"

Open in new window


3 - Just put a breakpoint (put cursor on the line and press F9) here if(Convert.ToInt32(ddlAmount.Text) > Convert.ToInt32(lblParticipants.Text)) and then execute/run/build your project, and carry out the actions that should cause the code to be reached, the debugger will bring you to this line when execution gets there step through the code (hover your mouse over the ddlAmount.Text and lblParticipants.Text to inspect the values, and F10 to proceed line by line so you see where you are going wrong).

4 - For now, I don't think your cookies are a problem as yet.

5 - When Visual Studio sees a syntax error, it highlights the section with an error and gives you lots of information on how to "correct" the issue.
Avatar of Jay

ASKER

I think its bc of this code 'if(Convert.ToInt32(ddlAmount.Text) > Convert.ToInt32(lblParticipants.Text))' nothing is being executed here? I changed my codes to this!!
  if(Convert.ToInt32(ddlAmount.Text) > Convert.ToInt32(lblParticipants.Text))
        {
            l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "";
            if (Request.Cookies["aa"] == null)
            {
                Response.Cookies["aa"].Value = "{lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.Text}";
            //    Response.Cookies["aa"].Value = lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ToString();
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
            else
            {
                Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|" + "{lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.Text}";
                //  Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|" + lblTitle.Text.ToString() + "," + lblPrice.Text.ToString() + "," + lblDate.Text.ToString() + "," + lblLocation.Text.ToString() + "," + lblStartTime.Text.ToString() + "," + lblEndTime.Text.ToString() + "," + lblParticipants.Text.ToString() + "," + lblDescription.Text.ToString() + "," + lblItemNr.Text.ToString() + "," + imgEvent.ToString();
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
        } 

Open in new window

Flaw in program flow logic
If you are not reaching that line of code (after setting a breakpoint), then we cannot say that there is anything wrong with the line. We cannot troubleshoot it unless we are reaching it. On looking at your earlier code sample, I noticed that you will not get to that line of code with the IF statement because you are redirecting to another page BEFORE that IF statement is executed. Once you issue a Response.Redirect, then execution immediately stops and switches to that new
page.Response.Redirect("Detail.aspx?id=" + id.ToString());

Open in new window

You probably need to re-evaluate your logic to make sure that your program flow logic/algorithm is sound and that you have implemented it correctly.

String Interpolation
Please note that your code modifications for string interpolation are slightly incorrect. You need to prefix that string with a $ as in my example. See these for more information and for the reasoning behind string interpolation:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interpolated-strings
http://www.informit.com/articles/article.aspx?p=2422807
Avatar of Jay

ASKER

Now, the text is being hit!!! but  label isn't being made visible... I'm guessing i have to add the label into a div and set that to hidden or visible?
this is now my code !!
 protected void btnAdd_Click(object sender, EventArgs e)
    {
        if (Convert.ToInt32(ddlAmount.Text) > Convert.ToInt32(lblParticipants.Text))
        {
            l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "";
            if (Request.Cookies["aa"] == null)
            {
                Response.Cookies["aa"].Value = "${lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
            else
            {
                Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|" + "${lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
        }
        var id = Convert.ToInt32(lblItemNr.Text);
        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }
        con.Open();
        SqlCommand cmd1 = con.CreateCommand();
        cmd1.CommandType = CommandType.Text;
        cmd1.CommandText = "update EventDetail set eventParticipants=eventParticipants-" + ddlAmount.Text + " where EventDetail_ID=" + id;
        cmd1.ExecuteNonQuery();
        Response.Redirect("Detail.aspx?id=" + id.ToString());
    }    

Open in new window

and the label ..
<asp:Label ID="l1" class="no" runat="server"></asp:Label> 

Open in new window


I doubt the label has a style applied to hide it
You have some serious issues in this single piece of code..

1. You don't validate your input. This may lead to SQL injection. Or the code failing with exceptions.

protected void btnAdd_Click(object sender, EventArgs e)
{
    int ddlAmount;
    int participants;
    int itemNr;
    bool validInput = int.TryParse(this.ddlAmount.Text, ddlAmount) &&
        int.TryParse(this.lblParticipants.Text, participants) &&
        int.TryParse(this.lblItemNr.Text, itemNr);

    if (validInput)
    {
        if (ddlAmount > participants)
        {
            l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "";
            if (Request.Cookies["aa"] == null)
            {
                Response.Cookies["aa"].Value = "${lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
            else
            {
                Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|" + "${lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
                Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
            }
        }

        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }

        con.Open();
        SqlCommand cmd1 = con.CreateCommand();
        cmd1.CommandType = CommandType.Text;
        cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
        cmd1.ExecuteNonQuery();
        Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr);
    }
}

Open in new window


2. Decouple different aspects, use refactorings. Mark the entire block about SQL or the validation block:

User generated image
3. And streamline your logic, this will also imho remove a flaw:

protected void btnAdd_Click(object sender, EventArgs e)
{
    int ddlAmount, participants, itemNr;
    if (ValidateInput(out ddlAmount, out participants, out itemNr))
    {
        l1.Text = "";
        if (Request.Cookies["aa"] != null)
        {
            Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|";
        }

        Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "${lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
        Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
        UpdateEventParticipantes(ddlAmount, itemNr);
        Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr);
    }
}

private bool ValidateInput(out int ddlAmount, out int participants, out int itemNr)
{
    bool isValid = int.TryParse(this.ddlAmount.Text, ddlAmount) &&
        int.TryParse(this.lblParticipants.Text, participants) &&
        int.TryParse(this.lblItemNr.Text, itemNr);
    if (isValid)
    {
        isValid = ddlAmount > participants;
        if (!isValid)
            l1.Text = "please enter lower quantity";
    }
    else
    {
        l1.Text = "please enter numbers";
    }

    return isValid;
}

private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
{
    SqlConnection con = new SqlConnection(_connStr);
    if (con.State == ConnectionState.Open)
    {
        con.Close();
    }

    con.Open();
    SqlCommand cmd1 = con.CreateCommand();
    cmd1.CommandType = CommandType.Text;
    cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
    cmd1.ExecuteNonQuery();
}

Open in new window


In your original snippet, you're updating the EventDetail, even when ddlAmount is greater then participants.
Avatar of Jay

ASKER

@ Stefan: ive tried your codes but there are errors like
- An object reference is required for the non-static field, method, or property 'Detail._connStr'      
-Argument 2 must be passed with the 'out' keyword AND The best overloaded method match for 'int.TryParse(string, out int)' has some invalid arguments AND Use of unassigned out parameter for :  
 
bool isValid = int.TryParse(this.ddlAmount.Text, ddlAmount) &&
  int.TryParse(this.lblParticipants.Text, participants) &&
  int.TryParse(this.lblItemNr.Text, itemNr);

Open in new window

- The out parameter 'ddlAmount' 'itemNr' 'participants' must be assigned to before control leaves the current method for :
        return isValid;
@stefan makes great comments about the code structure. I also think the validation might also best be done client side (to show/hide the error message) as well as on the server side for robustness.

Just add OUT: int.TryParse(this.ddlAmount.Text, out ddlAmount)
- An object reference is required for the non-static field, method, or property 'Detail._connStr'  
This is an error you must have had already in your code snippet. How and where is _connStr declared? btw, here you should consider using a factory class for creating SQL connection opjects.

-Argument 2 must be passed with the 'out' keyword AND The best overloaded method match for 'int.TryParse(string, out int)' has some invalid arguments AND Use of unassigned out parameter for :  
Well, just do it:
ddlAmount = 0;
participants = 0;
itemNr = 0;
bool validInput = int.TryParse(this.ddlAmount.Text, out ddlAmount) &&
    int.TryParse(this.lblParticipants.Text, out participants) &&
    int.TryParse(this.lblItemNr.Text, out itemNr);

Open in new window


This will also solve the last point.
The input validation must happen in client-side and server-side.

Doing it client-side will reduce server roundtrips and enables better and finer structured error messages and user guidance.

Doing it server-side is necessary to stop evil users.
However, I think we could perhaps try to make it work for now, and then refactor later. Coz I find refactoring code that isn't working to begin with to be a bit more error prone as you cannot test whether your refactorings have not killed the application.

I would take out the class="no" on the label for now. So that we reduce the number of issues we are trying to resolve at a time.
<asp:Label ID="l1" runat="server"></asp:Label>

Open in new window


I would not introduce a DIV or anything for now. I would say get the current version to work, then take a good look at what ste5an is proposing because it adds soooo much value and really improves the quality of the code and makes it easier to track what the different pieces of the code are doing.
btw, you should even refactor the cookie handling:

protected void btnAdd_Click(object sender, EventArgs e)
{
    int ddlAmount, participants, itemNr;
    if (ValidateInput(out ddlAmount, out participants, out itemNr))
    {
        l1.Text = "";
        SetCookie();
        UpdateEventParticipantes(ddlAmount, itemNr);
        Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr);
    }
}

protected void SetCookie()
{
    if (Request.Cookies["aa"] != null)
    {
        Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|";
    }

    Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "${lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
    Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
}

Open in new window


Now you have clean code in the btnAdd method, which tells at one glance what is happening.
Avatar of Jay

ASKER

there is still error for this part though!! :(
-The out parameter 'itemNr' and 'participants' must be assigned to before control leaves the current method for :
        return isValid;
-Use of unassigned out parameter 'participants'      for:
            isValid = ddlAmount > participants;
Small typo in code:

"${lblTitle.Text}

should be

$"{lblTitle.Text}

The dollar sign should be outside.
SOLUTION
Avatar of Mlanda T
Mlanda T
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jay

ASKER

it says feature interpolated strings is not available in c# 5
Avatar of Jay

ASKER

The participants = 0;
itemNr = 0;

solved the errors!! but I cant use the interpolated strings...
Then use string.Format().

protected void btnAdd_Click(object sender, EventArgs e)
{
    int ddlAmount, participants, itemNr;
    if (ValidateInput(out ddlAmount, out participants, out itemNr))
    {
        l1.Text = "";
        SetCookie();
        UpdateEventParticipantes(ddlAmount, itemNr);
        Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr);
    }
}

protected void SetCookie()
{
    if (Request.Cookies["aa"] != null)
    {
        Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|";
    }

    Response.Cookies["aa"].Value = Request.Cookies["aa"].Value +
        string.Format(
            "{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
            lblTitle.Text,
            lblPrice.Text,
            lblDate.Text,
            lblLocation.Text,
            lblStartTime.Text,
            lblEndTime.Text,
            lblParticipants.Text,
            lblDescription.Text,
            lblItemNr.Text,
            imgEvent.ToString()
        );
    Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
}

private bool ValidateInput(out int ddlAmount, out int participants, out int itemNr)
{
    ddlAmount = 0;
    participants = 0;
    itemNr = 0;
    bool validInput = int.TryParse(this.ddlAmount.Text, out ddlAmount) &&
        int.TryParse(this.lblParticipants.Text, out participants) &&
        int.TryParse(this.lblItemNr.Text, out itemNr);
    if (isValid)
    {
        isValid = ddlAmount <= participants;
        if (!isValid)
            l1.Text = "please enter lower quantity";
    }
    else
    {
        l1.Text = "please enter numbers";
    }

    return isValid;
}

private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
{
    SqlConnection con = new SqlConnection(_connStr);
    if (con.State == ConnectionState.Open)
    {
        con.Close();
    }

    con.Open();
    SqlCommand cmd1 = con.CreateCommand();
    cmd1.CommandType = CommandType.Text;
    cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
    cmd1.ExecuteNonQuery();
}

Open in new window


btw, I've used the wrong condition in my validation code. Now it should be correct.
Avatar of Jay

ASKER

and I don't get why the  _connStr in
 private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
    {
        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }
        con.Open();
        SqlCommand cmd1 = con.CreateCommand();
        cmd1.CommandType = CommandType.Text;
        cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
        cmd1.ExecuteNonQuery();
    }

Open in new window

cant work when it works fine in
  public int get_qty(int id)
    {
        id = Convert.ToInt32(lblItemNr.Text);
        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }
        con.Open();
        SqlCommand cmd = con.CreateCommand();
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "select * from EventDetail where EventDetail_ID=" + id + "";
        cmd.ExecuteNonQuery();
        DataTable dt = new DataTable();
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(dt);
        foreach (DataRow dr in dt.Rows)
        {
            qty = Convert.ToInt32(dr["eventParticipants"].ToString());
        }
        return qty;
    }  

Open in new window

it is from my EventDetail class : string _connStr = ConfigurationManager.ConnectionStrings["EventContext"].ConnectionString;
Please post the entire class. I guess its hiding else where..

btw, take a look at the SetCookie method: there are some more input values, which are not validated.  Where and how is this cookie used later on?
Avatar of Jay

ASKER

this is the whole code for my codebehind!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

public partial class Detail : System.Web.UI.Page
{
    string _connStr = ConfigurationManager.ConnectionStrings["EventContext"].ConnectionString;
    int qty;
    int id;
    protected void Page_Load(object sender, EventArgs e)
    {
        FillPage();
        qty = get_qty(id);
        if (qty == 0)
        {
            lblQuantity.Visible = false;
            ddlAmount.Visible = false;
            btnAdd.Visible = false;
            l2.Text = "No available participants for this event!";          
        }
    }
    private void FillPage()
    {
        if (Request.QueryString["id"] == null)
        {
            Response.Redirect("Events.aspx");
        }
        else
        {
            //get selected event's data
            if (!String.IsNullOrWhiteSpace(Request.QueryString["id"]))
            {
                int id = Convert.ToInt32(Request.QueryString["id"]);
                EventDetail Detail = new EventDetail();
                EventDetail detail = Detail.getEventDetail(id);
                if (detail == null)
                {
                    Response.Write("<script>alert('No event found');</script>");
                    return;
                }
                //fill pg w data
                lblDate.Text = detail.eventDate;
                lblLocation.Text = detail.eventLocation;
                lblStartTime.Text = detail.startTime;
                lblEndTime.Text = detail.endTime;
                lblParticipants.Text = detail.eventParticipants.ToString();
                lblPrice.Text = "$" + detail.eventPrice;
                lblTitle.Text = detail.eventDetailName;
                lblDescription.Text = detail.eventDesc;
                lblItemNr.Text = id.ToString();
                imgEvent.ImageUrl = "~/EventImages/Events/" + detail.eventImage;
                //fill amt ddl w numbers 1-20
                int[] amount = Enumerable.Range(1, 20).ToArray();
                ddlAmount.DataSource = amount;
                ddlAmount.AppendDataBoundItems = true;
                ddlAmount.DataBind();
            }
        }
    }
    protected void btnAdd_Click(object sender, EventArgs e)
    {
        int ddlAmount, participants, itemNr;
        if (ValidateInput(out ddlAmount, out participants, out itemNr))
        {
            l1.Text = "";
            SetCookie();
            UpdateEventParticipantes(ddlAmount, itemNr);
            Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr));
        }
    }
    protected void SetCookie()
    {
        if (Request.Cookies["aa"] != null)
        {
            Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|";
        }

        Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + $"{lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
        Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
    }
    private bool ValidateInput(out int ddlAmount, out int participants, out int itemNr)
    {
        participants = 0;
        itemNr = 0;
        bool isValid = int.TryParse(this.ddlAmount.Text, out ddlAmount) &&
         int.TryParse(this.lblParticipants.Text, out participants) &&
         int.TryParse(this.lblItemNr.Text, out itemNr);

        if (isValid)
        {
            isValid = ddlAmount > participants;
            if (!isValid)
                l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "please enter numbers";
        }

        return isValid;
    }

    private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
    {
        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }
        con.Open();
        SqlCommand cmd1 = con.CreateCommand();
        cmd1.CommandType = CommandType.Text;
        cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
        cmd1.ExecuteNonQuery();
    }
    public int get_qty(int id)
    {
        id = Convert.ToInt32(lblItemNr.Text);
        SqlConnection con = new SqlConnection(_connStr);
        if (con.State == ConnectionState.Open)
        {
            con.Close();
        }
        con.Open();
        SqlCommand cmd = con.CreateCommand();
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "select * from EventDetail where EventDetail_ID=" + id + "";
        cmd.ExecuteNonQuery();
        DataTable dt = new DataTable();
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(dt);
        foreach (DataRow dr in dt.Rows)
        {
            qty = Convert.ToInt32(dr["eventParticipants"].ToString());
        }
        return qty;
    }  
}

Open in new window

I see. It's the static modifier of the method. Thus you cannot access a normal field.  _connStr looked like a constant, thus I made the method static.

e.g.

namespace WebApplication1
{
    using System;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;

    public partial class Detail : System.Web.UI.Page
    {
        private static string ConnectionString = ConfigurationManager.ConnectionStrings["EventContext"].ConnectionString;
        private int qty;
        private int id;
        protected void Page_Load(object sender, EventArgs e)
        {
            FillPage();
            qty = get_qty(id);
            if (qty == 0)
            {
                //lblQuantity.Visible = false;
                ddlAmount.Visible = false;
                btnAdd.Visible = false;
                //l2.Text = "No available participants for this event!";
            }
        }
        private void FillPage()
        {
            if (Request.QueryString["id"] == null)
            {
                Response.Redirect("Events.aspx");
            }
            else
            {
                //get selected event's data
                if (!String.IsNullOrWhiteSpace(Request.QueryString["id"]))
                {
                    int id = Convert.ToInt32(Request.QueryString["id"]);
                    //EventDetail Detail = new EventDetail();
                    //EventDetail detail = Detail.getEventDetail(id);
                    //if (detail == null)
                    //{
                    //    Response.Write("<script>alert('No event found');</script>");
                    //    return;
                    //}
                    //fill pg w data
                    //lblDate.Text = detail.eventDate;
                    //lblLocation.Text = detail.eventLocation;
                    //lblStartTime.Text = detail.startTime;
                    //lblEndTime.Text = detail.endTime;
                    //lblParticipants.Text = detail.eventParticipants.ToString();
                    //lblPrice.Text = "$" + detail.eventPrice;
                    //lblTitle.Text = detail.eventDetailName;
                    //lblDescription.Text = detail.eventDesc;
                    lblItemNr.Text = id.ToString();
                    //imgEvent.ImageUrl = "~/EventImages/Events/" + detail.eventImage;
                    //fill amt ddl w numbers 1-20
                    int[] amount = Enumerable.Range(1, 20).ToArray();
                    ddlAmount.DataSource = amount;
                    ddlAmount.AppendDataBoundItems = true;
                    ddlAmount.DataBind();
                }
            }
        }
        protected void btnAdd_Click(object sender, EventArgs e)
        {
            int ddlAmount, participants, itemNr;
            if (ValidateInput(out ddlAmount, out participants, out itemNr))
            {
                l1.Text = "";
                SetCookie();
                UpdateEventParticipantes(ddlAmount, itemNr);
                Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr));
            }
        }
        protected void SetCookie()
        {
            if (Request.Cookies["aa"] != null)
            {
                Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|";
            }

            //Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + $"{lblTitle.Text},{lblPrice.Text},{lblDate.Text},{lblLocation.Text},{lblStartTime.Text},{lblEndTime.Text},{lblParticipants.Text},{lblDescription.Text},{lblItemNr.Text},{imgEvent.ToString()}";
            Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
        }
        private bool ValidateInput(out int ddlAmount, out int participants, out int itemNr)
        {
            participants = 0;
            itemNr = 0;
            bool isValid = int.TryParse(this.ddlAmount.Text, out ddlAmount) &&
             int.TryParse(this.lblParticipants.Text, out participants) &&
             int.TryParse(this.lblItemNr.Text, out itemNr);

            if (isValid)
            {
                isValid = ddlAmount > participants;
                if (!isValid)
                    l1.Text = "please enter lower quantity";
            }
            else
            {
                l1.Text = "please enter numbers";
            }

            return isValid;
        }

        private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
        {
            SqlConnection con = new SqlConnection(ConnectionString);
            if (con.State == ConnectionState.Open)
                con.Open();
            SqlCommand cmd1 = con.CreateCommand();
            cmd1.CommandType = CommandType.Text;
            cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
            cmd1.ExecuteNonQuery();
        }
        public int get_qty(int id)
        {
            id = Convert.ToInt32(lblItemNr.Text);
            SqlConnection con = new SqlConnection(ConnectionString);
            con.Open();
            SqlCommand cmd = con.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "select * from EventDetail where EventDetail_ID=" + id + "";
            cmd.ExecuteNonQuery();
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            foreach (DataRow dr in dt.Rows)
            {
                qty = Convert.ToInt32(dr["eventParticipants"].ToString());
            }
            return qty;
        }
    }
}

Open in new window


But you have still some issues. For example you have EventDetail class, which seems to provide the data. Thus your update event and get:qty methods belong to this class.

Also use using for class implementin IDisposable and you're mixing fields with parameters e.g.

namespace WebApplication1
{
    using System;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;

    public partial class Detail : System.Web.UI.Page
    {
        private static string ConnectionString = ConfigurationManager.ConnectionStrings["EventContext"].ConnectionString;

        protected void Page_Load(object sender, EventArgs e)
        {
            FillPage();
            int qty = get_qty();
            if (qty == 0)
            {
                //lblQuantity.Visible = false;
                ddlAmount.Visible = false;
                btnAdd.Visible = false;
                //l2.Text = "No available participants for this event!";
            }
        }

        //...

        private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
        {
            using (SqlConnection con = new SqlConnection(ConnectionString))
            {
                con.Open;
                using (SqlCommand cmd1 = con.CreateCommand())
                {
                    cmd1.CommandType = CommandType.Text;
                    cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
                    cmd1.ExecuteNonQuery();
                }
            }
        }
        public int get_qty()
        {
            int id = Convert.ToInt32(lblItemNr.Text);
            int qty = 0;
            using (SqlConnection con = new SqlConnection(ConnectionString))
            {
                con.Open();
                using (SqlCommand cmd = con.CreateCommand())
                {
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "select * from EventDetail where EventDetail_ID=" + id + "";
                    cmd.ExecuteNonQuery();
                    using (DataTable dt = new DataTable())
                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        da.Fill(dt);
                        foreach (DataRow dr in dt.Rows)
                        {
                            qty = Convert.ToInt32(dr["eventParticipants"].ToString());
                        }
                    }
                }
            }

            return qty;
        }
    }
}

Open in new window


Then use explicit visibility modifiers consequently. Prefer private over protected. Use protected only when you need to inherit from your classes. Use public only when you need to call methods from other classes.
Avatar of Jay

ASKER

This is my code!! It seems to be working fine now after I made some changes, but when 5qty is displayed and I select 5 from the ddl, it still tells me to select a lower qty.. do u know why? I have this code too->  l2.Text = "No available participants for this event!";          
       
public partial class Detail : System.Web.UI.Page
{
    private static string ConnectionString = ConfigurationManager.ConnectionStrings["EventContext"].ConnectionString;
    protected void Page_Load(object sender, EventArgs e)
    {
        FillPage();

        int qty = get_qty();
        if (qty == 0)
        {
            lblQuantity.Visible = false;
            ddlAmount.Visible = false;
            btnAdd.Visible = false;
            l2.Text = "No available participants for this event!";          
        }
    }
    private void FillPage()
    {
        if (Request.QueryString["id"] == null)
        {
            Response.Redirect("Events.aspx");
        }
        else
        {
            //get selected event's data
            if (!String.IsNullOrWhiteSpace(Request.QueryString["id"]))
            {
                int id = Convert.ToInt32(Request.QueryString["id"]);
                EventDetail Detail = new EventDetail();
                EventDetail detail = Detail.getEventDetail(id);
                if (detail == null)
                {
                    Response.Write("<script>alert('No event found');</script>");
                    return;
                }
                //fill pg w data
                lblDate.Text = detail.eventDate;
                lblLocation.Text = detail.eventLocation;
                lblStartTime.Text = detail.startTime;
                lblEndTime.Text = detail.endTime;
                lblParticipants.Text = detail.eventParticipants.ToString();
                lblPrice.Text = "$" + detail.eventPrice;
                lblTitle.Text = detail.eventDetailName;
                lblDescription.Text = detail.eventDesc;
                lblItemNr.Text = id.ToString();
                imgEvent.ImageUrl = "~/EventImages/Events/" + detail.eventImage;
                //fill amt ddl w numbers 1-20
                int[] amount = Enumerable.Range(1, 20).ToArray();
                ddlAmount.DataSource = amount;
                ddlAmount.AppendDataBoundItems = true;
                ddlAmount.DataBind();
            }
        }
    }
    protected void btnAdd_Click(object sender, EventArgs e)
    {
        int ddlAmount, participants, itemNr;
        if (ValidateInput(out ddlAmount, out participants, out itemNr))
        {
            l1.Text = "";
            SetCookie();
            UpdateEventParticipantes(ddlAmount, itemNr);
            Response.Redirect(string.Format("Detail.aspx?id={0}", itemNr));
        }
    }
    protected void SetCookie()
    {
        if (Request.Cookies["aa"] != null)
        {
            Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + "|";
        }
        Response.Cookies["aa"].Value = Request.Cookies["aa"].Value + String.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", lblTitle.Text, lblPrice.Text, lblDate.Text, lblLocation.Text, lblStartTime.Text, lblEndTime.Text, lblParticipants.Text, lblDescription.Text, lblItemNr.Text, imgEvent.ToString());
        Response.Cookies["aa"].Expires = DateTime.Now.AddDays(1);
    }
    private bool ValidateInput(out int ddlAmount, out int participants, out int itemNr)
    {
        participants = 0;
        itemNr = 0;
        bool isValid = int.TryParse(this.ddlAmount.Text, out ddlAmount) &&
         int.TryParse(this.lblParticipants.Text, out participants) &&
         int.TryParse(this.lblItemNr.Text, out itemNr);

        if (isValid)
        {
            isValid = ddlAmount < participants;
            if (!isValid)
                l1.Text = "please enter lower quantity";
        }
        else
        {
            l1.Text = "please enter numbers";
        }

        return isValid;
    }

    private static void UpdateEventParticipantes(int ddlAmount, int itemNr)
    {
        using (SqlConnection con = new SqlConnection(ConnectionString))
        {
            con.Open();
            using (SqlCommand cmd1 = con.CreateCommand())
            {
                cmd1.CommandType = CommandType.Text;
                cmd1.CommandText = string.Format("UPDATE EventDetail SET eventParticipants=eventParticipants-{0} WHERE EventDetail_ID={1};", ddlAmount, itemNr);
                cmd1.ExecuteNonQuery();
            }
        }
    }
    public int get_qty()
    {
        int id = Convert.ToInt32(lblItemNr.Text);
        int qty = 0;
        using (SqlConnection con = new SqlConnection(ConnectionString))
        {
            con.Open();
            using (SqlCommand cmd = con.CreateCommand())
            {
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = "select * from EventDetail where EventDetail_ID=" + id + "";
                cmd.ExecuteNonQuery();
                using (DataTable dt = new DataTable())
                using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    da.Fill(dt);
                    foreach (DataRow dr in dt.Rows)
                    {
                        qty = Convert.ToInt32(dr["eventParticipants"].ToString());
                    }
                }
            }
        }

        return qty; 
    }
}

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jay

ASKER

Thank you !!! x You guys helped a lot :)