So my code brings across the searched for userID of a lecturer and the ModuleID previously selected by the user. However it breaks on this line;
myCommand.ExecuteNonQuery();
The error is;
An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll but was not handled in user code
Additional information: Incorrect syntax near '('.
I don't know why it does it but I can see that my stuff is being pulled across when I use a break point.
Front end code:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DefaultConnection %>"
SelectCommand="SELECT Lecturer_Records.UserID, Lecturer_Records.FirstName, Lecturer_Records.Surname, Lecturer_Records.PhoneNumber, Users.Email
FROM Lecturer_Records
INNER JOIN Users ON Lecturer_Records.UserID = Users.UserID
WHERE (Users.Email = #email)">
<SelectParameters>
<asp:QueryStringParameter Name="email" QueryStringField="searchlects" />
<asp:SessionParameter Name="ModuleID" SessionField="ModuleID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="SearchResult" runat="server" AutoGenerateColumns="False" AutoGenerateSelectButton="True" DataSourceID="SqlDataSource1" OnSelectedIndexChanged="SearchResult_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="Surname" HeaderText="Surname" SortExpression="Surname" />
<asp:BoundField DataField="PhoneNumber" HeaderText="PhoneNumber" SortExpression="PhoneNumber" />
<asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
</Columns>
</asp:GridView>
And my C# code
protected void SearchResult_SelectedIndexChanged(object sender, EventArgs e)
{
// open new connection
SqlConnection connection1 = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
connection1.Open();
string SearchUser = SearchResult.SelectedRow.Cells[1].Text;
string Module = (string)Session["ModuleID"];
SqlCommand myCommand = new SqlCommand("UPDATE [Modules] SET (UserID = '" + SearchUser + "') WHERE (ModuleID = '" + Module + "')", connection1);
myCommand.ExecuteNonQuery();
// move on to home page
Response.Redirect("APMDefault.aspx");
}
You don't need any ( or ) in your command. They breaks your sql syntax. Just delete them.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Based on your column names, they seems as a numerical types. That means, you might need to delete single quotes as well. If you use prepared statements, you will not need this of course.
And use using statement to dispose your connection and command.
using(var connection1 = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
using(var myCommand = connection1.CreateCommand())
{
myCommand.CommandText = #"UPDATE Modules SET UserID = #userid
WHERE ModuleID = #moduleid";
myCommand.Parameters.Add("#userid", SqlDbType.NVarChar).Value = SearchUser;
myCommand.Parameters.Add("#moduleid", SqlDbType.NVarChar).Value = Module;
// I assumed your column types are nvarchar
connection1.Open();
myCommand.ExecutenonQuery();
// move on to home page
Response.Redirect("APMDefault.aspx");
}
But really, those columns are seem as numerical types. Either you can their type or change their name that points their types as character.
Related
This is the table I have created:
CREATE TABLE Product
(ID INTEGER IDENTITY(1,1) NOT NULL ,
Product_No AS RIGHT ('PDT0000' + CAST(ID AS VARCHAR(10)),10) PERSISTED PRIMARY KEY CLUSTERED,
Product_Image VARBINARY (MAX) NOT NULL,
Product_Name VARCHAR(50) NOT NULL,
Product_Category_No INTEGER NOT NULL FOREIGN KEY REFERENCES Product_Category(Product_Category_No),
Product_Price MONEY NOT NULL,
Product_Quantity INTEGER NOT NULL,
Grocery_Branch_No INTEGER NOT NULL FOREIGN KEY REFERENCES Grocery_Branch(Grocery_Branch_No)
)
When I insert a value like 10.50 or 100.45 or 11.05 in Product_Price column and then run SELECT * FROM Product in both SQL Server and Visual Studio, the Product_Price column value gets displayed as 10.50 or 100.45 or 11.05.
However, when I see the result of SELECT * FROM Product in a gridview from aspx page, then it shows 10.5000 or 100.4500 or 11.0500.
In other words, the results for Product_Price column value in SQL Server and Visual Studio is showing 2 numbers after the decimal (because in INSERT Statement I have added 2 numbers after decimal).
But, while running the aspx page, in the Product_Price column value in Grid View, it is showing 4 numbers after the decimal.
I made sure to add the Regular Expression Validator for Product_Price column in AddProducts.aspx
p>
Price:
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" runat="server" ControlToValidate="TextBox2" ErrorMessage="This field is required"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator7" runat="server" ControlToValidate="TextBox2" ErrorMessage="After decimal only 2 numbers" ValidationExpression="^\d{1,9}\.\d{1,2}$"></asp:RegularExpressionValidator>
</p>
Then this is what I have done in my AddProducts.cs
Stream stream = postedfile.InputStream;
BinaryReader binaryreader = new BinaryReader(stream);
byte[] bytes = binaryreader.ReadBytes((int)stream.Length);
string branch = Session["BranchAdmin"].ToString();
string CS;
CS = "data source=LAPTOP-ODS96MIK\\MSSQL2014; database = Grocery_Demo; integrated security=SSPI";
SqlConnection con = new SqlConnection(CS);
SqlCommand cmd = new SqlCommand("AddProducts", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
con.Open();
cmd.Parameters.AddWithValue("#ProductImage", FileUpload1.FileBytes);
cmd.Parameters.AddWithValue("#ProductName", TextBox1.Text);
cmd.Parameters.AddWithValue("#ProductCategoryName", DropDownList1.SelectedValue);
cmd.Parameters.AddWithValue("#ProductPrice", TextBox2.Text);
cmd.Parameters.AddWithValue("#ProductQuantity", TextBox3.Text);
cmd.Parameters.AddWithValue("#GroceryBranchName", branch);
cmd.ExecuteNonQuery();
con.Close();
MessageBox("New Product has been added");
Then this is what I have done in ViewProducts.aspx
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" HorizontalAlign="Center">
<Columns>
<asp:TemplateField HeaderText="Image">
<ItemTemplate>
<asp:Image ID="Image1" runat="server" Height="100px" Width="150px"
ImageUrl='<%#"data:Image/png/jpg/jpeg/gif/bmp;base64," + Convert.ToBase64String((byte[])Eval("Product_Image")) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Product_Name" HeaderText="Product" />
<asp:BoundField DataField="Product_Category_Name" HeaderText="Category" />
<asp:BoundField DataField="Product_Price" HeaderText="Price" DataFormatString="{0} AUD" />
<asp:BoundField DataField="Product_Quantity" HeaderText="Quantity" />
<asp:BoundField DataField="Grocery_Branch_Name" HeaderText="Branch" />
</Columns>
</asp:GridView>
And this is what I have done in ViewProducts.cs
private void DisplayProducts()
{
string CS;
CS = "data source=LAPTOP-ODS96MIK\\MSSQL2014; database = Grocery_Demo; integrated security=SSPI";
SqlConnection con = new SqlConnection(CS);
SqlCommand cmd = new SqlCommand("ViewProducts", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
con.Open();
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
con.Close();
}
I still could not figure out why the ViewProducts.aspx page is showing 4 numbers after the decimal for Product_Price column value in Grid View.
It would be helpful if the recommended syntax solution is provided to display 2 numbers after the decimal for Product_Price column value in Grid View.
This code should work:
<asp:BoundField DataField="Product_Price" HeaderText="Price" DataFormatString="{0:0.00} AUD" />
net devexpress controls. First i tried to implement this edit command on gridview. Everything seems fine but only one problem i got is when i tried to click edit link a popup forms comes out in which i can not type inside the box. Finally, when i click on "Update" button an error comes out says "Object reference not set to an instance of an object." Please help me out this situation where did i make mistake. Thanking you.
<%# Register assembly="DevExpress.Web.v17.1, Version=17.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Web" tagprefix="dx" %>
<asp:Content runat="server" ID="BodyContent1" ContentPlaceHolderID="ContentPlaceHolder1">
<dx:ASPxGridView ID="GridView1" runat="server" ClientInstanceName="GridView1"
KeyFieldName="TestConfigId" AutoGenerateColumns="False" Width="850px"
OnRowUpdating="Gridview1_RowUpdating" >
<Columns>
<dx:GridViewDataTextColumn Caption="TestConfigId" FieldName="TestConfigId" Name="TestConfigId" Visible="true" VisibleIndex="0">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn Caption="Main Test" FieldName="MainTest" Name="MainTest" Settings-AllowSort="False" VisibleIndex="1" >
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn Caption="Sub Test" FieldName="SubTest" Name="SubTest" Settings-AllowSort="False" VisibleIndex="2" >
</dx:GridViewDataTextColumn>
<dx:GridViewCommandColumn ShowEditButton="true" VisibleIndex="3" Width="100" FixedStyle="Left">
</dx:GridViewCommandColumn>
</Columns>
<Settings HorizontalScrollBarMode="Visible"/>
<SettingsBehavior AutoExpandAllGroups="true"/>
<SettingsBehavior AllowFocusedRow="True"/>
<SettingsResizing ColumnResizeMode="NextColumn"/>
<Styles>
<FixedColumn BackColor="LightYellow"></FixedColumn>
</Styles>
<Settings ShowStatusBar="Visible" />
<SettingsEditing Mode="PopupEditForm" />
</dx:ASPxGridView>
<dx:ASPxPopupControl ID="popupSample" runat="server" ShowCloseButton="true" ShowHeader="true"
PopupHorizontalAlign="WindowCenter" PopupVerticalAlign="WindowCenter">
</dx:ASPxPopupControl>
</asp:Content>
Code Behind file
protected void Gridview1_RowUpdating(object sender, ASPxDataUpdatingEventArgs e)
{
SqlConnection con = new SqlConnection(constr);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "update_test_configuration";
cmd.Parameters.Add("#TestConfigId", SqlDbType.Int).Value = Convert.ToInt32(e.NewValues["TestConfigId"]);
cmd.Parameters.Add("#MainTest", SqlDbType.NVarChar).Value = e.NewValues["MainTest"].ToString();
cmd.Parameters.Add("#SubTest", SqlDbType.NVarChar).Value = e.NewValues["SubTest"].ToString();
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
}
Stored Procedure
CREATE PROCEDURE [dbo].[update_test_configuration]
#TestConfigId int = 0,
#MainTest nvarchar(100),
#SubTest nvarchar(100)
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.TestConfigMaster
SET MainTest = #MainTest,
SubTest =#SubTest
WHERE TestConfigId = #TestConfigId
END
If e.NewValues["MainTest"] is null, then e.NewValues["MainTest"].ToString() will generate an error because you cannot call ToString() on a null reference. i.e., you cannot say "null.ToString()."
Same will apply the rest of the fields, i.e. TestConfigId and SubTest.
Maybe you could try this way:
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter { SqlDbType = System.Data.SqlDbType.NVarChar, ParameterName = "#MainTest", Value = $"{ e.NewValues["MainTest"] }" });
etc.
Still a complete beginner with Asp.Net, and a google search didn't turn up the right results I have anticipated. I apologize if there is already a duplicate question.
The problem I have is that I have a editable gridview below:
<asp:GridView ID="gvCodes" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" DataSourceID="CodesDataSource" CellPadding="3" Width="474px" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" OnRowDataBound="gvCodes_RowDataBound">
<Columns>
<asp:BoundField DataField="Id" HeaderText="Id" ReadOnly="True" Visible="false" InsertVisible="False" SortExpression="Id"></asp:BoundField>
<asp:BoundField DataField="Code" HeaderText="Code" ReadOnly="True" SortExpression="Code"></asp:BoundField>
<asp:BoundField DataField="Manager_Name" HeaderText="Manager Name" SortExpression="Manager_Name"></asp:BoundField>
<asp:BoundField DataField="Created_Date" HeaderText="Created Date" ReadOnly="True" SortExpression="Created_Date" DataFormatString="{0:MM/d/yyyy}"></asp:BoundField>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
</Columns>
</asp:GridView>
Here is my SQLDataSource:
<asp:SqlDataSource runat="server" ID="CodesDataSource" DeleteCommand="DELETE FROM [Codes] WHERE [Id] = #Id" InsertCommand="INSERT INTO [Codes] ([Manager_Name]) VALUES (#Manager_Name, #Created_Date)" SelectCommand="SELECT * FROM [Codes] WHERE [ProjProjectID] = 'DynamicValue'" UpdateCommand="UPDATE [Codes] SET [Manager_Name] = #Manager_Name, [Created_Date] = GETDATE() WHERE [Id] = #Id AND [ProjProjectID] = 'DynamicValue'" OnSelected="CodesDataSource_Selected">
<DeleteParameters>
<asp:Parameter Name="Id" Type="Int32"></asp:Parameter>
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="Manager_Name" Type="String"></asp:Parameter>
<asp:Parameter DbType="Date" Name="Created_Date"></asp:Parameter>
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="Manager_Name" Type="String"></asp:Parameter>
<asp:Parameter DbType="Date" Name="Created_Date"></asp:Parameter>
<asp:Parameter Name="Id" Type="Int32"></asp:Parameter>
</UpdateParameters>
</asp:SqlDataSource>
I want to be able to move the SqlDataSource all to BackEnd, at least the parameters so that I could change the projProjectID in the where. This is what I have tried:
projProjectID = Request.QueryString["ProjProjectID"].ToString();
private void LoadSqlDataSource()
{
CodesDataSource.ConnectionString = ba.connection;
CodesDataSource.SelectCommand = "SELECT * FROM Codes WHERE ProjProjectID = '" + projProjectID + "'";
CodesDataSource.UpdateCommand = "UPDATE Codes SET Manager_Name = #Manager_Name, Created_Date = GETDATE() WHERE Id = #Id AND ProjProjectID = '" + projProjectID + "'";
//CodesDataSource.UpdateParameters.Add("Manager_Name", TypeCode.String, ___);
//CodesDataSource.UpdateParameters.Add("Created_Date", TypeCode.String, ___);
//CodesDataSource.UpdateParameters.Add("Id", TypeCode.String, ___);
}
The ____ is where the error occurs. It is expecting a string value. What I don't know how to do is get that specific value edited by the user in the gridview to go into that ___. I only need the Manager_Name to work.
Thanks a lot
In the event gvCodes_RowUpdating, handle the functionality of updating like this.
protected void gvCodes_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = (GridViewRow)gvCodes.Rows[e.RowIndex];
TextBox textID = (TextBox)row.Cells[0].Controls[0];
TextBox textDate = (TextBox)row.Cells[0].Controls[0];
TextBox textManagerName = (TextBox)row.Cells[0].Controls[0];
CodesDataSource.ConnectionString = ba.connection;
CodesDataSource.SelectCommand = "SELECT * FROM Codes WHERE ProjProjectID = '" + projProjectID + "'";
CodesDataSource.UpdateCommand = "UPDATE Codes SET Manager_Name = #Manager_Name, Created_Date = GETDATE() WHERE Id = #Id AND ProjProjectID = '" + projProjectID + "'";
CodesDataSource.UpdateParameters.Add("Manager_Name", TypeCode.String, textManagerName.Text);
CodesDataSource.UpdateParameters.Add("Created_Date", TypeCode.String, textDate.Text);
CodesDataSource.UpdateParameters.Add("Id", TypeCode.String, textID.Text);
}
Advice:
Using parameters helps prevent SQL Injection attacks and hence you should include all as parameters like projProjectID also. Also, You should use SqlCommand instead of SqlDataSource at the backend:
string updateStatement = "UPDATE Codes SET Manager_Name = #Manager_Name, Created_Date = GETDATE() WHERE Id = #Id AND ProjProjectID = #projectID";
using (SqlConnection connection = new SqlConnection(ConnectionString())
using (SqlCommand cmd = new SqlCommand(updateStatement, connection)) {
connection.Open();
cmd.Parameters.Add(new SqlParameter("#Manager_Name", textManagerName.Text));
cmd.Parameters.Add(new SqlParameter("#Created_Date", textDate.Text));
cmd.Parameters.Add(new SqlParameter("#Id", textID.Text));
cmd.Parameters.Add(new SqlParameter("#projectID", projProjectID));
cmd.ExecuteNonQuery();
I need to display some data from a view in a SQL Server database on several pages of my website. I've done it by using SqlDataSource within my web.config and then used a GridView control within my .aspx page to display the data.
Now, this works but I read in some forum that it is bad practice to do use SqlDataSource? I will probably need to have the ability for the admin/user to filter the data in the future, so I'm not sure how this would work with my current implementation.
My code so far looks like this :
In the web.config file:
<connectionStrings>
<add name="Test1.ConnectionString"
connectionString="Data Source=...."
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
And something like this in my aspx
<body id="wrap" >
<form runat="server">
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False"
BackColor="White" BorderColor="#CCCCCC"
BorderStyle="None" BorderWidth="1px" CellPadding="3"
DataSourceID="SqlDataSource1" Height="500px" Width="408px">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" ReadOnly="True" SortExpression="Title">
<ItemStyle Width="400px" HorizontalAlign="Center" Height="100px" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px" />
</asp:BoundField>
<asp:BoundField DataField="Result" HeaderText="Result" ReadOnly="True" SortExpression="Result" >
<ItemStyle HorizontalAlign="Center" Height="100px" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px" />
</asp:BoundField>
</Columns>
<FooterStyle BackColor="White" ForeColor="#002756" />
<HeaderStyle BackColor="#003466" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="#002756" HorizontalAlign="Left" />
<RowStyle ForeColor="#002756" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings: Test1.ConnectionString %>"
SelectCommand="SELECT * FROM [Test1.ConnectionString]">
</asp:SqlDataSource>
</form>
</body>
So my question is is there a better way to implement this, keeping in mind that I will probably need a function for the user/admin to filter the data by certain criteria?
It's not necessarily bad practice to use SqlDataSource... but it does tend to mingle your data access code with your presentation code. Additionally, you can often do better with an ObjectDataSource that wraps your view. There's a little more code involved (you'll have to create a new class somewhere to select from your view), but you end up with methods that can be easily updated or replaced in the future to handle whatever changes you may need.
As mentioned in my comment I would recommend you use the code behind to achieve this as it's much easier to make changes if required in the future. I'm assuming you've got a table in your database named Test1. We'll first create a class to represent this in C# and add a few properties which we'll use later on.
public class Test
{
public string Title { get; set; }
public int Result { get; set; }
}
Now let's create a method which returns a collection of values from your database.
public List<Test> GetData()
{
List<Test> myList = new List<Test>();
string sqlQuery = "Select Title, Result From Test";
string connectionString = ConfigurationManager.ConnectionStrings["Test1.ConnectionString"].ConnectionString; //Read connection string from config file
using (var con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(sqlQuery, con))
{
//Add param here if required.
con.Open(); //Open connection
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Test t = new Test();
t.Title = reader["Title"].ToString();
t.Result = Convert.ToInt32(reader["Result"]);
myList.Add(t);
}
}
}
}
return myList;
}
Finally, you want to set the datasource for the GridView. I'm going to assume you have a page called MyGridPage.aspx open up the MyGridPage.asps.cs and in your Page_Load event you can set the DataSource for your grid as:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Test t = new Test();
GridView1.DataSource = t.GetData();
GridView1.DataBind();
}
}
If you wanted to filter your Sql query by for example username you'll change it as:
string sqlQuery = "Select Title, Result From Test Where username = #username";
Then you can pass in the #username parameter as:
cmd.Parameters.Add("#username", SqlDbType.NVarChar).Value = myUsername;
myUsername can be of someone who's logged into your app. You will pass the parameter(s) before you open the connection. Passing parameters will also prevent sql injection which I suggest you read up on in case you're not aware.
Note: it is recomenned to make use of using block to ensure the connection object is closed and disposed correctly.
You can programmatically set the data source of the grid view.
protected void Page_Load(object sender, EventArts e)
{
using(SqlConnection conn = new SqlConnection(connectionString))
{
string query = "SELECT * FROM Test"; //your SQL query goes here
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable table = new DataTable();
da.Fill(table);
GridView1.DataSource = table;
GridView1.DataBind();
cmd.Dispose();
da.Dispose();
}
}
I am using a SqlDataSource to bind DetailsView for userprofile, which allows users to view their information and at the same time change their particulars. (select, retrieve and update)
however, this error occured-- A field or property with the name 'Username' was not found on the selected data source when I click the hyperlink to direct to the "userprofile" page.
Exception Details: System.Web.HttpException: A field or property with the name 'Username' was not found on the selected data source.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
this is the code inside userprofile.aspx file:
<asp:DetailsView ID="UserProfile" runat="server"
AutoGenerateRows="False" DataKeyNames="UserId"
DataSourceID="UserProfileDataSource" DefaultMode="Edit"
onitemupdated="UserProfile_ItemUpdated">
<Fields>
<asp:BoundField DataField="Username" HeaderText="Username"
SortExpression="Username" />
<asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
SortExpression="HomeTown" />
<asp:BoundField DataField="HomepageUrl" HeaderText="HomepageUrl"
SortExpression="HomepageUrl" />
<asp:BoundField DataField="Signature" HeaderText="Signature"
SortExpression="Signature" />
<asp:CommandField ShowEditButton="True" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="UserProfileDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:SecurityTutorialsConnectionString %>"
SelectCommand="SELECT * FROM [UserProfiles] WHERE ([UserId] = #UserId)"
onselecting="UserProfileDataSource_Selecting"
UpdateCommand="UPDATE UserProfiles SET
Username = #Username,
HomeTown = #HomeTown,
HomepageUrl = #HomepageUrl,
Signature = #Signature WHERE UserId = #UserId ">
<SelectParameters>
<asp:Parameter Name="UserId" Type="Object" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="HomeTown" />
<asp:Parameter Name="HomepageUrl" />
<asp:Parameter Name="Signature" />
<asp:Parameter Name="UserId" />
</UpdateParameters>
</asp:SqlDataSource>
this is the code behind userprofile.aspx.cs :
protected void UserProfileDataSource_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
// Get a reference to the currently logged on user
MembershipUser currentUser = Membership.GetUser();
// Determine the currently logged on user's UserId value
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
// Assign the currently logged on user's UserId to the #UserId parameter
e.Command.Parameters["#UserId"].Value = currentUserId;
}
EDIT
I had change the SQL query to:
SelectCommand= "SELECT [aspnet_Membership].UserId, [HomeTown], [HomepageUrl], [Signature] FROM [UserProfiles] INNER JOIN [aspnet_Membership] ON aspnet_Membership.UserId = UserProfiles.UserId WHERE aspnet_Membership.UserId=#UserId"
onselecting="UserProfileDataSource_Selecting"
UpdateCommand="UPDATE UserProfiles SET
Username = #Username,
HomeTown = #HomeTown,
HomepageUrl = #HomepageUrl,
Signature = #Signature WHERE UserId = #UserId ">
But the error still appear:
A field or property with the name 'Username' was not found on the selected data source
Check the field names in the UserProfiles table. It appears you don't have a Username field. It is good practice to explicitly state the fields you want to SELECT rather than using the SELECT * FROM .. syntax.
<asp:BoundField DataField="Username" HeaderText="Username"
SortExpression="Username" />
Can you try reordering the fields to see if it is only a problem with username? i.e.,
<asp:BoundField DataField="HomeTown" HeaderText="HomeTown"
SortExpression="HomeTown" />
<asp:BoundField DataField="Username" HeaderText="Username"
SortExpression="Username" />
If there is a problem with the datasource, you should get the exception on 'HomeTown' now. If you do, one thing to try would be removing the # from the Parameter assignment:
e.Command.Parameters["UserId"].Value = currentUserId;
EDIT: After seeing your modified SQL, two things:
In your SelectCommand, you don't seem to select Username. If [aspnet_Membership].UserId is your Username, you can SELECT [aspnet_Membership].UserId AS Username
In your UpdateCommand, you are assigning a value to Username even though it does not exist in the UserProfiles table. You need to use a JOIN there as well.