Data not being written to Database ASP.Net - asp.net

I am building a Forum in ASP.Net but have a small problem.
I have 1 user who creates a topic and can write a post to it fine, but if another user logs in, it won't insert the post into the database. It's returning that it does but nothing inserts. The original user can login and still post but no-one else can.
this is my code in behind
protected void addPostBtn_Click(object sender, EventArgs e)
{
//Define ADO.NET objects.
string insertSQL;
string topic = Request.QueryString["topicid"].ToString();
insertSQL = "INSERT INTO Posts (TopicID, PostBody, PUserID)"
+ "VALUES (#Topic, #NewPostText, #PUserID)";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(insertSQL, con);
// Try to open the database and execute the update
int added = 0;
try
{
cmd.Parameters.AddWithValue("#Topic", topic);
cmd.Parameters.AddWithValue("#NewPostText", newPostText.InnerText);
cmd.Parameters.AddWithValue("#PUserID", Session["User_ID"]);
con.Open();
added = cmd.ExecuteNonQuery();
lblResults.Text = "Your post has been added";
}
catch (Exception err)
{
lblResults.Text = "Error inserting record. " + err.Message;
}
finally
{
con.Close();
}
if (added > 0)
{
this.BindRepeater();
}
}
I don't get any errors at all. It says it submitted fine, but it's not in the database unless the original poster does it.
EDIT:
Just realized it's to do with my view. This is my current view that it's reading from
SELECT dbo.Posts.PostBody, dbo.Posts.PostDate, dbo.Posts.PostID, dbo.[User].username, dbo.Topic.TopicID
FROM dbo.Topic RIGHT OUTER JOIN
dbo.Posts ON dbo.Topic.TopicID = dbo.Posts.TopicID LEFT OUTER JOIN
dbo.[User] ON dbo.Topic.TUserID = dbo.[User].UserID AND dbo.Posts.PUserID = dbo.[User].UserID
But it's returning NULL now for the other users names

The view needs to be as follows
SELECT dbo.Posts.PostBody, dbo.Posts.PostDate, dbo.Posts.PostID, dbo.[User].username, dbo.Topic.TopicID
FROM dbo.Topic LEFT OUTER JOIN
dbo.Posts ON dbo.Topic.TopicID = dbo.Posts.TopicID LEFT OUTER JOIN
dbo.[User] ON dbo.Posts.PUserID = dbo.[User].UserID

Related

Update user profile in website

In my website made by asp.net, we can update the email address, password, place and about myself of a user given the old password is correct. Now what I do is, login, then use this code to update:
protected void update_profile(object sender, EventArgs e)
{
string constr = ConfigurationManager.ConnectionStrings["Khulna_website"].ConnectionString;
using (SqlConnection connection = new SqlConnection(constr))
{
string user_email = (string)(Session["User"]);
string pass = encrypt_pass(old_password.Text);
if (pass != (string)(Session["Password"]))
{
pass_err_message.Text = "Wrong password";
pass = (string)Session["Password"];
}
else
{
pass = encrypt_pass(new_password.Text);
}
string insertQuery = "update dbo.users set user_password=#new_password, user_place = #new_place, user_about=#new_about where user_email =" +user_email;
SqlCommand com = new SqlCommand(insertQuery, connection);
connection.Open();
com.Parameters.AddWithValue("#new_password", pass);
com.Parameters.AddWithValue("#new_about", new_about.Text);
com.Parameters.AddWithValue("#new_place", new_place.Text);
try
{
com.ExecuteNonQuery();
upload_err_message.Text = "Successfully uploaded";
connection.Close();
}
catch (Exception ex)
{
profile_settings_err_message.Text = "Update error: " + ex.Message;
}
}
}
But when I try to update it is saying: Update error: The multi-part identifier "abcde#gmail.com" could not be bound. And my session is gone! I thought maybe it was due to foreign key, so I removed all the foreign keys of the database, but it is still happening. What's wrong here?
EDIT: I have added back the foreign keys, since I need them to on delete cascade. I just deleted them to see if it works.
I am just taking a guess, but I believe your issue will be found right here:
"... user_email =" +user_email;
Try doing something like
"... user_email = #email";
com.Parameters.AddWithValue("#email", user_email);
That's the better way... however if you want to get lackadaisical you should be able to just surround the email in single quotes.
"... user_email = '" + user_email + "'";
I hope this helps!

How to get last incremented id in SQL with single query

My requirement I inserted successfully I want to bind last increment id to the root folder file name.id was automatic incremented in SQL. I want to bind last incremented id on that bold part place.
This is my code please help me to solve this problem:
string insert = "insert into Articles values('" + html+ "','" + text + "')";
try
{
con.Open();
SqlCommand cmd = new SqlCommand(insert, con);
int i = cmd.ExecuteNonQuery();
if (i > 0)
{
using (StreamWriter file = new StreamWriter(System.Web.Hosting.HostingEnvironment.MapPath(#"~\Articles\**ID**.html"), true))
{
file.WriteLine(value.editor); // Write the file.
}
return msg;
}
else
{
return msg1;
}
}
catch (Exception ex)
{
}
finally
{
con.Close();
}
Please note that your code is a security risk as it's vulnerable to sql injection attacks as Sean Lange rightfully wrote in the comments.
Also, the empty catch is a problem as he pointed out. Do yourself a favor and never ever use empty catch blocks.
To get the last generated identity value in the current session you should use Sql Server's SCOPE_IDENTITY() function.
Note that if you have an instead of insert trigger on the table SCOPE_IDENTITY() will not give you the correct value.
Your code should look something like this:
string insert = "insert into Articles values(#html, #text); select scope_identity()";
using (var con = new SqlConnection("<YOUR CONNECTION STRING HERE>"))
{
using (var cmd = new SqlCommand(insert, con))
{
cmd.Parameters.Add("#html", SqlDbType.NVarChar).Value = html;
cmd.Parameters.Add("#text", SqlDbType.NVarChar).Value = text;
try
{
con.Open();
var databaseId = cmd.ExecuteScalar();
if (databaseId is int)
{
using (StreamWriter file = new StreamWriter(System.Web.Hosting.HostingEnvironment.MapPath(string.Format(#"~\Articles\{0}.html", databaseId)), true))
{
file.WriteLine(value.editor); // Write the file.
}
return msg;
}
else
{
return msg1;
}
}
catch (Exception ex)
{
// Write to log, show an error message to the user
}
}
}

My update query doesn't work on database

I wrote this code in my login page. My code doesn't any error but update query doesn't apply on my database.
Fist query works and I redirect to index.aspx but update query (second query) doesn't apply!!!!
protected void btnLogin_Click(object sender, EventArgs e)
{
Database db1 = new Database();
string query = "select * from Admins where UserName=#username and cast(Password as varbinary)=cast(#password as varbinary)";
SqlCommand smd = new SqlCommand(query, db1.sc);
smd.Parameters.AddWithValue("#username", txtUsername.Text);
smd.Parameters.AddWithValue("#password", General.CreatePasswordHash(txtPassword.Text));
SqlDataReader sdr = smd.ExecuteReader();
smd.Parameters.Clear();
if (sdr.Read())
{
Session.Add("username", sdr[0].ToString());
string nowEnter = sdr[5].ToString();
query = "update Admins set LastEnter=#lastEnter, NowEnter=#nowEnter where UserName=#username";
string now = General.getPersianDateNow() + " ساعت " + General.getPersianTimeNow();
smd.CommandText = query;
smd.Parameters.AddWithValue("#lastEnter", nowEnter);
smd.Parameters.AddWithValue("#nowEnter", now);
smd.Parameters.AddWithValue("#username", sdr[1].ToString());
sdr.Close();
smd.ExecuteNonQuery();
Response.Redirect("~/admin/Index.aspx", false);
}
else
{
lblError.Visible = true;
}
}
In my opinion the problem is with index of sdr. First one you invoke
Session.Add("username", sdr[0].ToString());
Two lines below you use
smd.Parameters.AddWithValue("#username", sdr[1].ToString());
Anyway the safest way is to create select statement with named colums instead of using *
Check that the value you are using for the username exists in the table.
You're also adding the same parameter twice. I don't know how the SqlCommand class will handle that and I can't test it right now, but I think it might be a good idea to clear your parameters (smd.Parameters.Clear()) between executions.

Why ComboBox items need to be reselected to obtain Value?

I am using ext.net 1.3 controls in my ASP.NET 4.0 application. I have several ComboBox controls on my Web Form. The page is supposed to perform two tasks, Insert and Update. There are no issues when a new record is saved, but when I try to fill the ComboBox controls with an existing database values, various issues pop up. The most troubling is this one:
The ComboBox displays the Text from the database, but it neither gets populated nor I am able to pick the ComboBox Value Member. This is because it is not populated. I have written code to populate ComboBox in the Page Load event.
I am using this code to pick a value from the database and show it on the ComboBox:
string Query = "SELECT CustName FROM CustomerMaster WHERE CustID = " + Session["CustomerID"];
var result = DB.Single<Customer>(Query);
CustomerComboBox.setValue = result.CustName;
This code successfully retrieves the Customer Name and displays in the ComboBox. What it is not doing is that it is not selecting from the ComboBox Item List and neither populating the ComboBox.
If I try to retrieve the Value Member of the Text using:
CustomerComboBox.SelectedItem.Value;
it gives error.
To make it work, I need to click on the ComboBox again to make it populate and than I manually select the same customer name from the list to pick the value.
How to get rid of this issue?
-- Edited --
The code to fill ext.net ComboBox is this:
public void FillExtComboList(string ParameterFlag, ComboBox DropDownName)
{
string Query = "";
using (TransactionScope transactionScope = new TransactionScope())
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["cncustomer"].ConnectionString.ToString()))
{
con.Open();
SqlDataReader dr;
try
{
if (ParameterFlag == "Customer")
{
Query = "SELECT CustName FROM CustomerMaster";
}
//Check whether the Drop Down has existing items. If YES, empty it.
if (DropDownName.Items.Count > 0)
DropDownName.Items.Clear();
SqlCommand cmd = new SqlCommand(Query, con);
dr = cmd.ExecuteReader();
while (dr.Read())
{
Ext.Net.ListItem extLI = new Ext.Net.ListItem();
extLI.Text = dr[0].ToString();
DropDownName.Items.Add(extLI);
}
dr.Close();
con.Close();
}
catch (Exception ex)
{
con.Close();
// RunCustomScript("alert('" + ex.Message.ToString() + "')", callingPageObjectName);
}
} /* End of SQL Connection */
transactionScope.Complete();
} /* End of Transaction Scope */
}
On Page Load event, the ComboBox control is filled with above method.
I don't see an instruction to fill the combo box, only to set its selected value. Arent you missing a CustomerComboBox.DataSource = someList or something like that?
<-- EDIT -->
Sorry, I thought the setValue was the code on your page load...
OK, this is not be the answer to your problem, but an important performance fix.
you should do this when loading the combo:
when executing the SQL Query:
Query = "SELECT CustID, CustName FROM CustomerMaster"
when filling the combo:
Ext.Net.ListItem extLI = new Ext.Net.ListItem();
extLI.Value = dr["CustId"].ToString();
extLI.Text = dr["CustName"].ToString();
DropDownName.Items.Add(extLI);
so when you want to select an item, you just do this:
CustomerComboBox.setValue = Session["CustomerID"];
and avoid going back to the database to get the customer name.
Now, could you share the code you have to handle the combobox click? Since it does fill the combo, it may throw some ligth to us. Also, try adding
CustomerComboBox.DataBind()
And, come to think of it, I see on Page_Load you use "DropDownName" and later on you use "CustomerComboBox". Could that be the problem?
If I understand you correctly try this code:
protected void Page_Load(object sender, EventArgs e) {
FillExtComboList(DropDownName);
// Set value that you want
DropDownName.SetValueAndFireSelect("Test 3");
}
public void FillExtComboList(ComboBox DropDownName) {
try {
//Check whether the Drop Down has existing items. If YES, empty it.
if (DropDownName.Items.Count > 0)
DropDownName.Items.Clear();
for (int i = 0; i < 10; i++) {
Ext.Net.ListItem extLI = new Ext.Net.ListItem();
extLI.Text = "Test " + i;
DropDownName.Items.Add(extLI);
}
} catch (Exception ex) {
// RunCustomScript("alert('" + ex.Message.ToString() + "')", callingPageObjectName);
} /* End of Transaction Scope */
}

Error binding DataAdapter->DataSet->LINQ->ASP.Net DataGrid

I have the following code:
using (SqlConnection cn = new SqlConnection(Connection.Instance.ConnectionString))
{
// Open the connection
using (SqlCommand cmd = new SqlCommand())
{
try
{
cmd.Connection = cn;
cmd.CommandText = "Select Customers.CustomerID, Addresses.AddressCode, Addresses.FirstName, Addresses.LastName, Addresses.Address1, Addresses.City, Addresses.State, " +
"Addresses.Zip, Addresses.Home AS HomePhone, Addresses.Phone AS WorkPhone, Addresses.EmailAddress From Customers " +
"LEFT OUTER JOIN Addresses ON Addresses.ID=Customers.AddressID " +
"Where CustomerType IN ('HomeOwner', 'Home Owner') AND Customers.ResellerID=#ResellerID ";
cmd.Parameters.AddWithValue("#ResellerID", base.UserID);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet dsCustomer = new DataSet();
da.Fill(dsCustomer);
var customers = from c in dsCustomer.Tables[0].AsEnumerable().AsQueryable()
where c.Field<string>("CustomerID") == txtSearchCriteria.Text
select c;
dgCustomers.CurrentPageIndex = 0;
dgCustomers.DataSource = customers;
dgCustomers.DataBind();
}
catch (Exception e)
{
throw new Exception(e.Message + e.StackTrace);
}
finally
{
if ((cn != null) && (cn.State != ConnectionState.Closed))
cn.Close();
}
}
}
Which is giving me the error
AllowCustomPaging must be true and VirtualItemCount must be set for a DataGrid with ID 'dgCustomers' when AllowPaging is set to true and the selected data source does not implement ICollection. at System.Web.UI.WebControls.DataGrid.CreateControlHierarchy(Boolean useDataSource)
How do I convert this LINQ query so that it can be pagable?
Note: This is a simplified version of what I'm trying to do. I know in this example I could simply modify the SQL statement to include "And CustomerID=#CustomerID" and bypass LINQ completely. But, in the bigger picture, I can't do that.
The error message is clear, you need to implement your paging logic to take advantage from paging. BTW, to make your code to work just use a ICollection as DataSource, changing this line:
dgCustomers.DataSource = customers.ToList();

Resources