Value cannot be null in querystring - asp.net

I have 2 link buttons on my page for each product.1 of them is delete that product and the other is redirect it by query string to the other page to Edit that product.
hereprotected void dlMusic_ItemCommand(object source, DataListCommandEventArgs e)
{
int id = Convert.ToInt32(e.CommandArgument);
if (e.CommandName == "EditItem")
{
Response.Redirect("~/Admin/EditMusic.aspx?id=" + id);
}
else if (e.CommandName == "DeleteItem")
{
SqlCommand cmd = new SqlCommand("", Connection);
cmd.CommandText = "DELETE FROM MusicTable WHERE MusicId=#id";
cmd.Parameters.AddWithValue("#id", id);
Connection.Open();
cmd.ExecuteNonQuery();
Connection.Close();
LoadData();
}
}
Delete button worked correctly but on edit I have problem.
protected void Page_Load(object sender, EventArgs e)
{
int id = int.Parse(Request.QueryString["id"]);
SqlDataAdapter da = new SqlDataAdapter("", Connection);
DataTable dt = new DataTable();
da.SelectCommand.CommandText = "SELECT * FROM MusicTable WHERE MusicId=#id";
da.SelectCommand.Parameters.AddWithValue("#id", id);
da.Fill(dt);
string name = dt.Rows[0]["MusicName"].ToString();
string signame = dt.Rows[0]["SingerName"].ToString();
string prodname = dt.Rows[0]["ProducerName"].ToString();
string albname = dt.Rows[0]["AlbumeName"].ToString();
string des = dt.Rows[0]["Description"].ToString();
string cover = dt.Rows[0]["Cover"].ToString();
txtMusicName.Text = name;
txtSingerName.Text = signame;
txtProducerName.Text = prodname;
txtAlbumeName.Text = albname;
coverImg.ImageUrl = "~/images/" + cover;
txtDes.InnerText = des;
}
It works correctly until requested by query string and the error come is
Additional information: Value cannot be null.
Thanks in advance

From your comment, it is apparent that field "id" is not part of your QueryString.
Please check your URL when the Edit Page is loaded by the browser (you can see it if you put a breakpoint and switch to the browser window).
If you think your URL is correct, please post a screenshot of your loading browser.
Another idea (quite desperate, though), change "id" in whatever else (i.e. "myid")
Response.Redirect("~/Admin/EditMusic.aspx?myid=" + id);
and
int id = int.Parse(Request.QueryString["myid"]);

Related

Displaying Windows Active Directory thumbnailPhoto in asp:net Search App

I've set up a WebApplication to search the Active Directory of our organization. The Query (dynamic SQL wrapping OpenQuery) returns also the hexadecimal data for the thumpnailPhoto.
When I'm displaying the image I get a 40% success on all pictures displayed. The "bad" ones are usually fine in the first 15% starting from the top and then stop with black stripes. Sometimes there is picture data repeated in stripes... Some profile pictures are not displayed at all, while others are perfect. There must be different image formats, but not having access to the storage positions of these images I do not get any further.
This is what I do:
I bind the data from the query to a GridView.
protected void FillGrid(Object sender, EventArgs e)
{
SqlConnection objConn = new SqlConnection("Data Source=XXXXXXXXXX");
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand objCommand = new SqlCommand(#"declare #SQL nvarchar(4000)
declare #Asterisc nvarchar(1)
declare #Sub nvarchar(12)
set #SearchName = CASE WHEN #SearchName = '' THEN '*' ELSE #SearchName END
set #SearchSurename = CASE WHEN #SearchSurename = '' THEN '*' ELSE #SearchSurename END
set #Asterisc = '*'
set #Sub = CASE WHEN #Subsidiary = '*' THEN '' ELSE (#Subsidiary+', OU=') END
set #SQL ='SELECT TOP (100) PERCENT samAccountName AS UserAccount, givenName AS FirstName, sn AS LastName, department, title AS Position,
physicaldeliveryofficename AS Office, extensionAttribute1 AS PersonnelID, initials, mail AS email, telephonenumber AS Phone, extensionattribute5 AS Extension,
mobile, extensionattribute3 AS MobileExt, thumbnailPhoto
FROM OPENQUERY(ADSI, ''SELECT samAccountName, givenName, sn, legacyExchangeDN, department, title, physicaldeliveryofficename, extensionAttribute1, distinguishedName, initials,
mail, telephonenumber, extensionattribute5, mobile, extensionattribute3, thumbnailPhoto
FROM ''''LDAP://OU=' + #Sub + 'XXXX, DC=XXXX,DC=XXXX,DC=XXXX''''
WHERE objectClass=''''Person'''' AND objectClass = ''''User'''' AND givenName = ''''' + #SearchName + ''''' AND samAccountName = ''''' + #SearchSurename + ''''' AND extensionAttribute1 = ''''' + #Asterisc + ''''' '') AS AD_Users
ORDER BY UserAccount'
exec (#SQL)", objConn);
objCommand.Parameters.Add("#SearchName", SqlDbType.NVarChar).Value = TextBoxSearchName.Text;
objCommand.Parameters.Add("#SearchSurename", SqlDbType.NVarChar).Value = TextBoxSearchSureName.Text;
objCommand.Parameters.Add("#Subsidiary", SqlDbType.NVarChar).Value = DDSubsidiary.Text;
DataTable t = new DataTable();
adapter.SelectCommand = objCommand;
objConn.Open();
adapter.Fill(t);
objConn.Close();
GridView.DataSource = t;
GridView.DataBind();
}
Then during the RowDataBound event I encode the data like this and bind that data to an asp:image control:
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dr = (DataRowView)e.Row.DataItem;
if(!String.IsNullOrEmpty(Convert.ToString(dr["thumbnailPhoto"])))
{
string imageUrl = "data:image/jpg;base64," + Convert.ToBase64String((byte[])dr["thumbnailPhoto"]);
(e.Row.FindControl("Image1") as Image).ImageUrl = imageUrl;
}
}
}
What problem am I facing here and how to deal with it?
I just discovered that those pictures that are displayed partially or with stripes are all pictures that are stored in a bigger 600x600 format, while the good ones have a 96x96 format. That leads me to my suspicion that something is going wrong when retrieving the thumbprintPhoto in it's hexacecimal format through SQL.
As Gabriel suggested, I tried to use the DirectorySearcher. The thumbprintPhoto was displayed correctly but it took me more than 10 seconds to retrieve 44 AD entries: Here is my code
protected void SearchAD(object sender, EventArgs e)
{
string Name = TextBoxSearchFirstName.Text;
Name = Name.Replace("*", "") + "*";
DirectorySearcher dsSearcher = new DirectorySearcher();
dsSearcher.Filter = "(&(objectClass=user) (sn=" + Name + "))";
results = dsSearcher.FindAll();
DataTable t = new DataTable("ActiveDir");
t.Columns.Add(new DataColumn("SecondName", System.Type.GetType("System.String")));
t.Columns.Add(new DataColumn("FirstName", System.Type.GetType("System.String")));
t.Columns.Add(new DataColumn("UserID", System.Type.GetType("System.String")));
t.Columns.Add(new DataColumn("data", System.Type.GetType("System.Byte[]")));
if (results != null)
{
foreach (SearchResult searchResult in results)
{
DataRow myRow;
myRow = t.NewRow();
myRow[0] = searchResult.GetDirectoryEntry().Properties["sn"].Value;
myRow[1] = searchResult.GetDirectoryEntry().Properties["givenName"].Value;
myRow[2] = searchResult.GetDirectoryEntry().Properties["samAccountName"].Value;
myRow[3] = searchResult.GetDirectoryEntry().Properties["thumbnailPhoto"].Value;
t.Rows.Add(myRow);
}
}
GridView1.DataSource = t;
GridView1.DataBind();
}
Solved: Gabriel tuned the AD Search code and now it's faster than the SQL Query.
In order to display the AD Thumnail Profil pictures without using a handler do the decoding during the GridViews OnRowDataBound Event:
protected void OnRowDataBoundAdUser(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dr = (DataRowView)e.Row.DataItem;
if (!String.IsNullOrEmpty(Convert.ToString(dr["data"])))
{
byte[] data = dr["data"] as byte[];
MemoryStream s = new MemoryStream(data);
byte[] imageBytes = s.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
string imageUrl = "data:image/jpg;base64," + base64String;
(e.Row.FindControl("Image1") as System.Web.UI.WebControls.Image).ImageUrl = imageUrl;
}
}
}
I see why it's taking so long. DirectorySearcher and DirectoryEntry can be a little sneaky with how many times it reaches out to AD. You have a lot more network requests going on there than you need.
In your code, you're going out to AD once for the search. Then for each result, you're using GetDirectoryEntry(). Then DirectoryEntry is going out to AD again the first time you use Properties. Worse still, as soon as you use Properties, it downloads every single attribute that has a value, even though you're only actually using 4 of them. That's a whole lot of useless network traffic.
You can avoid this by using Properties collection in the search results, which already has all the attributes (by default it gets every attribute that has a value).
But you can do even better: If you set the PropertiesToLoad property of DirectorySearcher then it will only return the values you want to use. This way, you have one network request for everything you want, and only what you want.
protected void SearchAD(object sender, EventArgs e)
{
string Name = TextBoxSearchFirstName.Text;
Name = Name.Replace("*", "") + "*";
var dsSearcher = new DirectorySearcher {
Filter = "(&(objectClass=user) (sn=" + Name + "))"
};
dsSearcher.PropertiesToLoad.Add("sn");
dsSearcher.PropertiesToLoad.Add("givenName");
dsSearcher.PropertiesToLoad.Add("samAccountName");
dsSearcher.PropertiesToLoad.Add("thumbnailPhoto");
using (var results = dsSearcher.FindAll()) {
var t = new DataTable("ActiveDir");
t.Columns.Add(new DataColumn("SecondName", typeof(string)));
t.Columns.Add(new DataColumn("FirstName", typeof(string)));
t.Columns.Add(new DataColumn("UserID", typeof(string)));
t.Columns.Add(new DataColumn("data", typeof(byte[])));
foreach (SearchResult searchResult in results) {
var myRow = t.NewRow();
myRow[0] = searchResult.Properties.Contains("sn") ? searchResult.Properties["sn"][0] : null;
myRow[1] = searchResult.Properties.Contains("givenName") ? searchResult.Properties["givenName"][0] : null;
myRow[2] = searchResult.Properties.Contains("samAccountName") ? searchResult.Properties["samAccountName"][0] : null;
myRow[3] = searchResult.Properties.Contains("thumbnailPhoto") ? searchResult.Properties["thumbnailPhoto"][0] : null;
t.Rows.Add(myRow);
}
}
GridView1.DataSource = t;
GridView1.DataBind();
}
A few notes:
The calls to Contains are needed because if the attribute is empty, then it doesn't exist in the Properties collection at all.
The search results returns everything as an array, regardless of whether it is or not in AD. Thus, the [0] is needed for every attribute.
You'll notice I put a using statement around the search results. This is needed to prevent memory leaks, according to the documentation of FindAll().

Not running query even tho Im sending the values in ASP

Im running an update query, it says it is not finding the second parameter (status), although I am clearly sending it. They are in different classes and are being called by a button which sends a mail and then changes the value of a variable (statusRef) in the main table (this field is new).
protected void sendMail(object sender, EventArgs e)
{
BO.Messages mail = new BO.Messages();
string body = "Cuerpo Mensaje";
string title = "Titulo";
string script = "alert(\"An email has been sent to the candidate! \");";
mail.refEmail(emailCandi.Text,title,body);
ScriptManager.RegisterStartupScript(this, GetType(),
"ServerControlScript", script, true);
Email_Sent.Visible = true;
changeRefStatus(Int32.Parse(idCand.Text), "1");
}
protected void changeRefStatus(int id, string status)
{
ASF.HC.JobApplication.BO.User u = new ASF.HC.JobApplication.BO.User();
u.saveStatusRef(id,status);
}
public int saveStatusRef(int id, string status)
{
Entity.User u = new Entity.User();
SqlCommand comando = new SqlCommand("dbo.[user_saveStatusRef]", base.Db);
SqlParameter spSearch = new SqlParameter("#id", System.Data.SqlDbType.Int);
SqlParameter spSearch2 = new SqlParameter("#status", System.Data.SqlDbType.VarChar);
spSearch.Value = id;
spSearch.Value = status;
comando.Parameters.Add(spSearch);
comando.Parameters.Add(spSearch2);
return base.ExecuteScalar(comando);
}
The stored procedure...
ALTER PROCEDURE dbo.user_saveStatusRef
#id int,
#status varchar(5)
AS
UPDATE tbl_user
set statusRef = #status
WHERE id = #id
Maybe a typo but you dont assign Value to spSearch2
spSearch.Value = id;
spSearch.Value = status;

how to auto login after registration in asp.net

I want to login automatically after registration by using a session like Session["ud"] , but I don't know where should I put it.
public partial class index : System.Web.UI.Page
{
SqlConnection cnn = new SqlConnection(ConfigurationManager.AppSettings["dbpath"]);
protected void btnSave_Click(object sender, EventArgs e)
{
long idx;
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandText = "Insert into tblUser (UInfo,UEmail,UName,UPass, UGender) Values (#P1,#P2,#P3,#P4,#P5) select ##Identity";
cmd.Parameters.AddWithValue("#P1", txtInfo.Text);
cmd.Parameters.AddWithValue("#P2", txtEmail.Text);
cmd.Parameters.AddWithValue("#P3", txtUserName.Text);
cmd.Parameters.AddWithValue("#P4", txtPass.Text);
cmd.Parameters.AddWithValue("#P5", rdbMale.Checked);
cnn.Open();
idx = Convert.ToInt64(cmd.ExecuteScalar()); // i think here we can do something
cnn.Close();
here we want to upload the image of user and it works correctly
string fn = "";
if (FileUpload1.HasFile == true)
{
fn = FileUpload1.FileName;
string des = Server.MapPath("\\UserImg\\") + idx.ToString() + ".jpg";
FileUpload1.PostedFile.SaveAs(des);
SqlCommand cmdUpdate = new SqlCommand();
cmdUpdate.Connection = cnn;
cmdUpdate.CommandText = "Update tblUser Set UImg=#P5 where UId=#P0";
cmdUpdate.Parameters.AddWithValue("#P5", idx.ToString() + ".jpg");
cmdUpdate.Parameters.AddWithValue("#P0", idx);
cnn.Open();
cmdUpdate.ExecuteNonQuery();
cnn.Close();
}
Response.Redirect("Profile.aspx");
}
}
once you have entered data into in sql database you will get id of new user here
idx = Convert.ToInt64(cmd.ExecuteScalar()); // i think here we can do something
Once you get the id assign it to your session
idx = Convert.ToInt64(cmd.ExecuteScalar()); // i think here we can do something
cnn.Close();
Session["ud"]=idx;
once you have assigned session ,you just have to redirect to required page and validate Session variable if it's null or not.
i hope on Profile.aspx page you are checking for same session variable.
Profile.aspx.cs--on page load
if (Session["ud"] != null)
{
//successfull login
}
else
{
//redirect to login page
}

Asp.net markup file

I have been given some c# code and have been asked to create a markup (.aspx) file that would go along with it.
I am not asking for help to write the code, but instead, how to go about it.
Here is the code:
public partial class search : Page
{
protected override void OnLoad(EventArgs e)
{
int defaultCategory;
try
{
defaultCategory = Int32.Parse(Request.QueryString["CategoryId"]);
}
catch (Exception ex)
{
defaultCategory = -1;
}
Results.DataSource = GetResults(defaultCategory);
Results.DataBind();
if (!Page.IsPostBack)
{
CategoryList.DataSource = GetCategories();
CategoryList.DataTextField = "Name";
CategoryList.DataValueField = "Id";
CategoryList.DataBind();
CategoryList.Items.Insert(0, new ListItem("All", "-1"));
CategoryList.SelectedIndex = CategoryList.Items.IndexOf(CategoryList.Items.FindByValue(defaultCategory.ToString()));
base.OnLoad(e);
}
}
private void Search_Click(object sender, EventArgs e)
{
Results.DataSource = GetResults(Convert.ToInt32(CategoryList.SelectedValue));
Results.DataBind();
}
private DataTable GetCategories()
{
if (Cache["AllCategories"] != null)
{
return (DataTable) Cache["AllCategories"];
}
SqlConnection connection = new SqlConnection("Data Source=DB;Initial Catalog=Store;User Id=User;Password=PW;");
string sql = string.Format("SELECT * From Categories");
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
Cache.Insert("AllCategories", dt, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration);
connection.Dispose();
return dt;
}
private DataTable GetResults(int categoryId)
{
SqlConnection connection = new SqlConnection("Data Source=DB;Initial Catalog=Store;User Id=User;Password=PW;");
string sql = string.Format("SELECT * FROM Products P INNER JOIN Categories C on P.CategoryId = C.Id WHERE C.Id = {0} OR {0} = -1", categoryId);
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
connection.Dispose();
return dt;
}
}
EDIT
In the above code, what is the Results object and is the CategoryList just a listbox?
As Nilesh said this seems like a search page, You can possibly try creating the a Webform using Visual studio which is just drag and drop controls into canvas and that will create the mark up for the controls in the code window.
This code behind seems to be doing the following,
On page load at Get request (when its !Page.IsPostBack) page is going to get categories using GetCategories() and fill the drop down list "CategoryList" with all category names (default selected one being the defaultcategory ID from query string).
The search button takes the dropdown's selected value and calls the GetResults() to get data table to fill the grid view "Results". So you need 3 controls (Dropdown list, Button, Gridview) in the webform with these names..

DetailsviewInside Linkbutton onclick it rediects and open newtab

I am working with Details view inside details view Itemtemplete i have link button when click that link button it need to redirect and open new tab for that i use this code
protected void lnkPost_Click(object sender, EventArgs e)
{
DetailsViewRow row= (DetailsViewRow)((LinkButton)sender).NamingContainer;
int postID = Convert.ToInt32((row.FindControl("lblPostID") as Label).Text);
if (postID != null)
{
string Query = "Select * from GigPost where GigPostID='" + postID + "'";
SqlCommand cmd = new SqlCommand(Query, cn);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
string Postsource = dr["PostSource"].ToString();
Response.Write("<script> window.open('"+ Postsource+"' ); </script>");
Response.End();
}
}
}
I am getting "Unable to cast object of type 'System.Web.UI.WebControls.DetailsView' to type 'System.Web.UI.WebControls.DetailsViewRow'." this error please help me how to resolve this issue
Regards,
Venkat
DetailsViewRow row = (DetailsViewRow)(((LinkButton)sender).NamingContainer);
may work - (untested)
But really - what's wrong with using the ItemCommand of the DetailsView and grab the current datakey?

Resources