I'm trying to add parameters to an objectDataSource at runtime like this:
Parameter objCustomerParameter = new Parameter("CustomerID", DbType.String, customerID);
Parameter objGPDatabaseParameter = new Parameter("Database", DbType.String, gpDatabase);
//set up object data source parameters
objCustomer.SelectParameters["CustomerID"] = objCustomerParameter;
objCustomer.SelectParameters["Database"] = objGPDatabaseParameter;
At what point in the objectDataSource lifecycle should these parameters be added (what event)? Also, some values are coming from a master page property (which loads after the page_load of the page containing the objectDataSource).
Add them to the event for the operation you are trying to use. For example, if these parameters are part of the SELECT command then add them to the Selecting event, if they need to go with the UPDATE command then add them on the Updating event.
The ObjectDataSource raises an event before it performs each operation, that's when you can insert parameters (or validate/alter existing parameters).
Also, don't try and modify the parameters collection of the ODS itself. You want to add your parameters to the ObjectDataSourceSelectingEventArgs that is passed to the event handler.
Something like:
e.InputParameters["CustomerID"] = customerId;
e.InputParameters["database"] = dbName;
Add as early as possible; at the PreInit event. This is part of initialization so should be done there.
See the ASP.NET Page Life Cycle Overview for more information.
Related
I've created a control inheriting from gridview:
Partial Public Class nullGridView
Inherits System.Web.UI.WebControls.GridView
Protected Overrides Function CreateAutoGeneratedColumn(ByVal fieldProperties As AutoGeneratedFieldProperties) As AutoGeneratedField
' Create an AutoGeneratedField object.
Dim field As New AutoGeneratedField(fieldProperties.DataField)
' Set the properties of the AutoGeneratedField using
' the values from the AutoGeneratedFieldProperties
' object contained in the fieldProperties parameter.
CType(field, IStateManager).TrackViewState()
field.HeaderText = fieldProperties.Name
field.SortExpression = fieldProperties.Name
field.ReadOnly = fieldProperties.IsReadOnly
field.DataType = fieldProperties.Type
field.NullDisplayText = "NULL"
Return field
End Function
End Class
I can then create instances of the class in codebehind and put them into placeholders. However, the function I'm trying to override never fires. I checked its signature against both Microsoft documentation and other sources, and it appears to be identical to the documented signature, but it never gets invoked. Any suggestions on why it doesn't work, or how to go about debugging this kind of problem?
(Note I also put a constructor into the class, and that got called OK - it is only the above that isn't getting called).
From the GridView.AutoGenerateColumns documentation:
When the AutoGenerateColumns property is set to true, an
AutoGeneratedField object is automatically created for each field in
the data source. Each field is then displayed as a column in the
GridView control in the order that the fields appear in the data
source. This option provides a convenient way to display every field
in the data source; however, you have limited control of how an
automatically generated column field is displayed or behaves.
Are you setting AutoGenerateColumns to true somewhere? You'll also need to give the Grid a data source. What kind of datasource are you using?
If you have set up everything according to the link above, you shouldn't have to override the function to get the behavior in your code because it will automatically create those instances. Further, take a look at the documentation for that function: it's obsolete-- so it's difficult for me to know what it does today.
If you look at the property's documentation it gives some options on how you might control what get's generated, like using a ColumnsGenerator.
I have login page, once logged in I create a session variable to store the UserName.
I've used this variable to retrieve info for this User from Account table with AccountID, name etc and I return the AccountID on the page using a label (lblAccountID).
I have a button to "Add Funds" to this account, which redirects to the AddFunds.aspx page
How can I pass the AccountID into the AddFunds.aspx page which will be used to insert details into Funds table which has the AccountID.
I don't want the AccountID to be visible on the AddFunds.aspx page.
there are multiple ways to achieve this. i can explain you in brief about the 4 types which we use in our daily programming life cycle.
Please go through the below points.
1 Query String.
FirstForm.aspx.cs
Response.Redirect(“SecondForm.aspx?Parameter=” + TextBox1.Text);
SecondForm.aspx.cs
TextBox1.Text = Request. QueryString["Parameter"].ToString();
This is the most reliable way when you are passing integer kind of value or other short parameters.More advance in this method if you are using any special characters in the value while passing it through query string, you must encode the value before passing it to next page. So our code snippet of will be something like this:
FirstForm.aspx.cs
Response.Redirect(“SecondForm.aspx?Parameter=” + Server.UrlEncode(TextBox1.Text));
SecondForm.aspx.cs
TextBox1.Text = Server.UrlDecode(Request.QueryString["Parameter"].ToString());
2. Passing value through context object
Passing value through context object is another widely used method.
FirstForm.aspx.cs
TextBox1.Text = this.Context.Items["Parameter"].ToString();
SecondForm.aspx.cs
this.Context.Items["Parameter"] = TextBox1.Text;
Server.Transfer(“SecondForm.aspx”, true);
Note that we are navigating to another page using Server.Transfer instead of Response.Redirect.Some of us also use Session object to pass values. In that method, value is store in Session object and then later pulled out from Session object in Second page.
3. Posting form to another page instead of PostBack
Third method of passing value by posting page to another form. Here is the example of that:
FirstForm.aspx.cs
private void Page_Load(object sender, System.EventArgs e)
{
buttonSubmit.Attributes.Add(“onclick”, “return PostPage();”);
}
And we create a javascript function to post the form.
SecondForm.aspx.cs
function PostPage()
{
document.Form1.action = “SecondForm.aspx”;
document.Form1.method = “POST”;
document.Form1.submit();
}
TextBox1.Text = Request.Form["TextBox1"].ToString();
Here we are posting the form to another page instead of itself. You might get viewstate invalid or error in second page using this method. To handle this error is to put EnableViewStateMac=false
4. Another method is by adding PostBackURL property of control for cross page post back
In ASP.NET 2.0, Microsoft has solved this problem by adding PostBackURL property of control for cross page post back. Implementation is a matter of setting one property of control and you are done.
FirstForm.aspx.cs
<asp:Button id=buttonPassValue style=”Z-INDEX: 102″ runat=”server” Text=”Button” PostBackUrl=”~/SecondForm.aspx”></asp:Button>
SecondForm.aspx.cs
TextBox1.Text = Request.Form["TextBox1"].ToString();
In above example, we are assigning PostBackUrl property of the button we can determine the page to which it will post instead of itself. In next page, we can access all controls of the previous page using Request object.
You can also use PreviousPage class to access controls of previous page instead of using classic Request object.
SecondForm.aspx
TextBox textBoxTemp = (TextBox) PreviousPage.FindControl(“TextBox1″);
TextBox1.Text = textBoxTemp.Text;
As you have noticed, this is also a simple and clean implementation of passing value between pages.
Reference: "How to: Pass Values Between ASP.NET Web Pages"
You need to store it in a session variable:
int AccountIdVar;
Session["AccountID"] = AccountIdVar;
then you can retrieve later by
int AccountIdVar = (int)Session["AccountID"];
You can either use the session variable you stored in the previous page as it should still be accessible or another way is to pass the id over via a querystring such as www.foofoofoo.com?Id=23456.
As the others said, you can use Session or Querystring values. You can also just POST to the new page
The How To Pass Values Between Pages page is worth looking at too.
The MSDN article about Pass Values Between ASP.NET Web Pages is the best place to look for.
For this we can also use Global variable, create a module class in that declare all variables with public data type, then assign the values. Once the value is assigned it can be accessed from anywhere.
Take for example a DetailsView control with an ObjectDataSource as its datasource.
Normally in the DetailsView.ItemUpdated event I would grab a reference to the details view by casting the sender:
DetailsView dv = (DetailsView)sender;
In certain situations it becomes necessary to handle the event inside the ObjectDataSource.ItemUpdated event. In this case sender is now of type ObjectDataSource. What I want to be able to do is write clean code that isnt hardcoded like
Label label1 = DetailsView1.FindControl("Label1");
I looked over the documentation and also did some searches but couldnt find how I would write some code like the following:
protected void ObjectDataSource1_Inserted(object sender, ObjectDataSourceStatusEventArgs e)
{
ObjectDataSource ods = (ObjectDataSource)sender;
DetailsView dv = (DetailsView)ods.SOMETHING_HERE;
}
Does anyone know what I should be putting in the SOMETHING_HERE in the snippet above?
That's happen because the "OnInserted" event is suppose to be an event examine the values of a return value or output parameters, or to determine whether an exception was thrown after an Insert operation has completed. The return value, output parameters, and exception handling properties are available from the ObjectDataSourceStatusEventArgs object that is associated with the event.
What you can do here is just call ObjectDataSource.select() that returns the view in this case but I don't think it's a good choice.
You should review you business logic and try to manage it somewhere it makes more sense
Anyway your code should look like the below:
ObjectDataSource ods = YourDataSource.select();
DetailsView dv = (DetailsView)ods;
Considering the example you provided, I don't think there is anything you can replace for Something_Here. It is the ODS linked to DV and not the other way. Also one DataSource can be linked to several DataBound Controls.
So as far as I know it is simply not possible.
1) Suppose GridView1 is bound to ObjectDataSource and that GridView1.SelectedIndex is set to value 7. If we then rebind GridView1 by calling GridView1.DataBind(), GridView.SelectedIndex will still retain its initial value ( 7 ).
Are there any other properties which GridView remembers across rebinding operations?
2) Suppose GridView1 is bound to ObjectDataSource control. When GridView1’s row gets deleted, we can call GridView1.DataBind() inside GridView1.RowDeleted event handler to retrieve values from data source. If we don’t call Gridview1.DataBind inside that event handler, then DataBind() will automatically be called by Asp.Net and the result will be the same.
So are there any reasons why we should manually call GridView.DataBind( inside RowDeleted event handler ) instead of letting Asp.Net call it automatically?
Your answer lies in Page.DataBind and Control.DataBind methods.
The main difference is that all data sources are bound to their server controls after the Page.DataBind method is called. No data is rendered to the control until you explicitly call either the DataBind method of the Web server control or until you invoke the page-level Page.DataBind method. Typically, Page.DataBind (or DataBind) is called from the Page_Load event.
Source
Particular answer for 1) is there's no such property for GridView,but you can make your own one and add last changed control.(Ideal)
For 2)Your action here coming from a postback,because the default bound source is changed after all you deleted a row inside it,since default source cannot be bound again,you need to call DataBind manually.
I'm going to mention a bit about Hierarchical Data Binding for starters.
In order to bind a datasource to a server-side control (GridView,DetailsView,.. etc) , that control must support a property known as DataSource and a method known as DataBind() , and the datasource that control is bound implement IEnumerable interface.
There is an exception for DataSet and DataTable which can be both bound directly , which results in binding to the default DataView of default table.
To bind a data to a control , you assign the data source to the DataSource property of the control and call its DataBind() method.Source
Since in your case ,databinding situation is different as you mentioned earlier that you bind GridView with ObjectDataSource which executes a query in page load and in every SELECT,INSERT,UPDATE,DELETE operations,datasource is bound automatically (which means DataBind is also called automatically).
There is another case which you are looking for an answer in the first place is that if datasource is queried and bound in page events (i.e. you query something and get a result with DataTable and bind it into GridView --> this source is not in the page not a objectdatasource or something else stands on page as static source).Since this query is coming from an event,when you enable pageIndex you must query it again that leads to you must also bind it with DataBind.
DataTable sourceTable = GetDataFromServer();
gridView.DataSource = sourceTable;
gridView.DataBind();
I hope that you can understand this time.
I am using a FormView to update an existing SQL Server record. The rows from the sqldatasource display fine in the FormView and I can edit them. When I click Update, I get the ItemUpdating event but not the ItemUpdated event and the revisions are not written to the database.
Can anyone help me in this please.
In your ItemUpdating event handler, make sure of the following things:
-If you are not using optimistic concurrency checking, remove any old values the FormView may be placing in the OldValues collection.
-Make sure that all of the parameters required by your stored procedure, query, or data source have values and are named correctly in either the Keys or NewValues collections (and make sure that no duplicates exist).
In some cases (usually when an ObjectDataSource is involved), I've had to override the values set by the FormView control, by doing something like this:
protected void myFormView_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
// remove the old values
e.Keys.Clear();
e.OldValues.Clear();
e.NewValues.Clear();
// set the parameter for the key
e.Keys.Add("#key", valueGoesHere);
// set other parameters
e.NewValues.Add("#param1", aValue);
e.NewValues.Add("#param2", anotherValue);
}
It's not pretty, but it give you absolute control over what gets passed to the DataSource. Generally you should not have to do this if the controls in your FormView are all bound using Bind() for two-way databinding (instead of Eval), but at the very least you could put a break point in ItemUpdating and open up the e.Keys, e.OldValues, and e.NewValues collections to see if the contents are what you expected.
A next step would be to launch SQL Server Profiler to run a trace and examine the actual query being performed.
If you take out the ItemUpdating event and the ItemUpdated event, does your SQL statement execute without errors?
If so, why don't you post some of the code you are using?
Can we see what the sqldatasource looks like? Did you remember to put all the parameters in the sqldatasource under the insert and update parameters list?
Oh also are you setting the cancel property at all in the itemupdating event?