Tuesday, March 13, 2012

The magical button? Declarative parameters tutorial

Hey folks,

Long time follower, first time poster.

I'm going through the"Working with Data in ASP.NET 2.0" tutorials, and this one bit has me mystified.

Page 4-6 (or about half way down, section "Setting the Parameter Value to the Property Value of a Web Control"

http://www.asp.net/learn/dataaccess/tutorial05cs.aspx?tabid=63

I've been through all the steps, and they all work - I just don't understand why. The mystery lies in the "Show suppliers" button. How does
my datagrid know I have clicked this button? How can it figure out, by this button click, to grab what's in the textfield, and send to the datagrid?

I haven't specified any code on the "on click" event for the button, and the markup source doesn't seem to reveal any kind of relationship between the textfield and the button.
If I put more buttons on the form, they all seem to behave in the same way - populating the datagrid.

Magic?

I believe you will find the answer to that question in this part of Scott's tutorial:

When visiting the page for the first time the CountryName TextBox is empty. The ObjectDataSource's Select method is still invoked by the GridView, but a value of null is passed into the GetSuppliersByCountry(country) method. The TableAdapter converts the null into a database NULL value (DBNull.Value), but the query used by the GetSuppliersByCountry(country) method is written such that it doesn't return any values when a NULL value is specified for the @.CategoryID parameter. In short, no suppliers are returned.

Once the visitor enters in a country, however, and clicks the Show Suppliers button to cause a postback, the ObjectDataSource's Select method is requeried, passing in the TextBox control's Text value as the country parameter.


tmorton:


Once the visitor enters in a country, however, and clicks the Show Suppliers button to cause a postback, the ObjectDataSource's Select method is requeried, passing in the TextBox control's Text value as the country parameter.

Thanks for the reply. I'm figuring the operative here is "postback" - the button causes a postback, but I still can't see the relationship between the button's postback, the textfield, and the datagrid.

My appoligies for newbie-ness, but I'm really trying to understand the workings of ASP.NET, coming from a Java Swing world, everything is new to me!Confused


mortdk:

Thanks for the reply. I'm figuring the operative here is "postback" - the button causes a postback, but I still can't see the relationship between the button's postback, the textfield, and the datagrid.


Hi there,

The relation is set when you configure the newly created ObjectDataSource, see in Figure 8, where the parameter source is set to a "control" and then you specify that the ID of the control to use is "CountryName". CountryName is the textbox and effectivly what you're doing is to tell the method the ObjectDataSource is calling (GetSuppliersByCountry()) to use the value from the "CountryName" text box as the value to pass along to the method.

You can physically see this in the markup (in the code view of your .aspx page) as shown in the code between Figure 8 and 9 of the article, in the ControlParameters tag inside the SelectParameters you can see that the ControlID is set to the ID of the text box and the type and property are set to string/text.

Hopefully this makes senseSmile


mortdk:

Thanks for the reply. I'm figuring the operative here is "postback" - the button causes a postback, but I still can't see the relationship between the button's postback, the textfield, and the datagrid.

Well, I doubt that I can do a better job at explaining things than Scott Mitchell can, but I'll give it a go. :-) For reference, here is the pertinent part of the DelcarativeParameters.aspx page:

<h3>View Suppliers By Country</h3>
<p>
Enter a country:
<asp:TextBox ID="CountryName" runat="server"></asp:TextBox> <asp:Button ID="Button1"
runat="server" Text="Show Suppliers" />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SupplierID"
DataSourceID="ObjectDataSource2" EnableViewState="False">
<Columns>
<asp:BoundField DataField="CompanyName" HeaderText="Company" SortExpression="CompanyName" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL" UpdateMethod="UpdateSupplierAddress">
<UpdateParameters>
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="address" Type="String" />
<asp:Parameter Name="city" Type="String" />
<asp:Parameter Name="country" Type="String" />
</UpdateParameters>
<SelectParameters>
<asp:ControlParameter ControlID="CountryName" Name="country" PropertyName="Text"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>

On that page you have 4 server controls coming into play for the "View Suppliers by Country" functionality:

Textbox (ID=CountryName)

Button (ID=Button1)

GridView (ID=GridView1)

ObjectDataSource (ID=ObjectDataSource2)

As you can see, GridView1's DataSource is ObjectDataSource2. That means that GridView1's data comes from the data supplied by ObjectDataSouce2's SelectMethod, which is method GetSuppliersByCountry. Any parameters needed by that method are passed into it from the ObjectDataSource's SelectParameters. In this case, there is one SelectParameter, and a ControlParameter is being used. This means that the value stored in a server control is used as the parameter value. The server control whose value is being passed is the CountryName Textbox.

So, the first time this page is accessed, the CountryName Textbox does not hold any value. The GridView asks the ObjectDataSource to load it up with data, the ObjectDataSource uses the CountryName value as a parameter to the GetSuppliersByCountry method, and since the CountryName is empty, the method returns no results. As a result, the GridView is empty.

Now, when the site visitor keys a value into the CountryName Textbox, and presses the button, the button causes a postback since it is a server control. So, once again, the GridView asks the ObjectDataSource to load it up with data, the ObjectDataSource uses the CountryName value as a parameter to the GetSuppliersByCountry method. This time, the CountryName is not empty, so the method returns results, and the GridView is populated.

Does this help at all?


Thanks for the excelent explanations. I understand the bindingbetween the textfield and the datagrid, this seems logical - take theCountryName.Text and use this as a parameter to look for data. Myproblem is understanding how the button1 can know anything about anytextfields or datagrids, when I haven't told it to do anything. All Idid was drop a button on the form, and it works "out of the box".

Now, when the site visitor keys a value into the CountryName Textbox,and presses the button, the button causes a postback since it is aserver control. So, once again, the GridView asks the ObjectDataSourceto load it up with data,

After fiddling a little with the tutorial, however odd I find the behavior, I think I might understand... please, correct me if I'm wrong:

The button only causes a postback. It's the postback that actually triggers the "reload" of the datasouce? I've tried with a LinkButton, a CheckBox (set to postback), and they all trigger a reload. Maybe it's just the tutorial's simplicity that caught me off guard. What if I have 3 other controls on the form that also need to perform postbacks, but must not change the contents of the mentioned gridview?

tmorton:

Now, when the site visitor keys a value into the CountryName Textbox, and presses the button, the button causes a postback since it is a server control. So, once again, the GridView asks the ObjectDataSource to load it up with data, the ObjectDataSource uses the CountryName value as a parameter to the GetSuppliersByCountry method.


Looks like I mucked up the quotes - sorry, hope you can decipher.

mortdk:

After fiddling a little with the tutorial, however odd I find the behavior, I think I might understand... please, correct me if I'm wrong:

The button only causes a postback. It's the postback that actually triggers the "reload" of the datasouce? I've tried with a LinkButton, a CheckBox (set to postback), and they all trigger a reload. Maybe it's just the tutorial's simplicity that caught me off guard. What if I have 3 other controls on the form that also need to perform postbacks, but must not change the contents of the mentioned gridview?

Sounds like you've got the hang of how the postback gets triggered and the data getting loaded.

In regards to having other controls that also trigger postbacks on a page, keeping the value of a control in ASP.NET is done with something called viewstate. If you enable viewstate on a control the values will get stored in a hidden field and then used to re-populate the control after the postback. I'm no expert on the use of viewstate but I guess in the example case, you could enable viewstate for the country textbox so that it keeps the value you input and therefore use that value as a parameter again after the postback. Or you could just enable viewstate on the gridview, I think both ways has positives and negatives.

More info on viewstate:

http://aspalliance.com/909

http://www.extremeexperts.com/Net/Articles/ViewState.aspx

0 comments:

Post a Comment