I have been tasked with sifting through the worst classic asp spaghetti i've ever come across.
The script runs a series of recordsets in sequence, getting 1 record at a time. As the record is built it takes the id and passes it to the next loop, which gets data, and passes on the id to the next loop. It then continues in this manner and builds an unordered list, kicking out the required html as it goes.
Here are my efforts so far:
have a class delivering data via sqldatareaders and output these to nested repeaters (this failed due to not being able to loop and get the id)
Have a datatable populated with all the required data, then datatable.select to filter it out.
have 4 datareaders looping and building the ul arraylists (I
couldnt get the id's to match up)
Please can you suggest the best method
Yes of course it can be rewritten in ASP.NET - note that i said rewritten, not just refactored, there is no saving that code (which is okay for what it does, but things are different with ASP.NET).
To be honest, i didn't even check the code, it hurt my eyes. A lot. But in general you can use a nice SQLConnection object, and a SQLCommand, call a stored procedure and get a nice SqlDataReader full of data from which you can build a DataTable or an IEnumerable list of data objects. You then have a repeater type control (ListView, GridView etc) in the UI, simply by binding your datatable or list to that control will render the results.
With the ListView, you specify a template for each data item that is rendered. For a GridView you specify the columns (or column templates) and which properties on each data item the columns should bind to.
When you retrieve the data, you can leave it as a DataTable, or translate it into something else like a list (or array) of data objects. As long as your list/array implements IEnumerable you should be able to just assign the list to the ItemsSource property of the aforementioned repeater control and it will perform its magic.
You don't even have to use a SQLCommand and DataTable object - you could even use Linq to SQL and bind the results straight to your repeater control.
This is just a high level overview of how you could do it, there are a couple of different ways. Once done, your code is going to be way cleaner and more maintainable than the classic ASP code.
Edit: your main issue is how to produce an ordered list, which is what the current code is doing with its nested loops supplying IDs for the detail items.
I would suggest you take a step back, and rethink the sql. In fact, throw the current sql away, it is incredibly inefficient with the tools you have today. It takes literally tenths of a second, and just one database call to return a flat table of data. Your first instinct may be "but i don't want to return too much data!" - relax, even returning several thousand data rows can be a sub 1 second operation if done correctly. You can also restrict the returned data by passing parameters in to the stored proc, or appending them to the dynamic sql statement that you construct (although it pains me hugely to mention dynamic sql, i think it is evil, but some people still use it - i would not recommend it unless it was your only option). To sum up what i am saying, how your data is returned from the database and how it looks on screen are two different things, don't let one guide the other. You can get the data from the database, then manipulate it before rendering it to the UI.
If you still want to show the data as an ordered list, then use a ListView, define a template for each data item, then you can use LINQ to group or filter the data you like (the data item template can contain whatever HTML or ASP.NET controls you like, and that template gets rendered for each data item in the list of data). Alternatively, you could use a GridView, and then use the grouping capability of the GridView to do the work for you - just specify which column(s) you want to group on, and the GridView takes care of the rendering.
Related
I have a tbl_categories and a tbl_items. I want to display tbl_categories in a horizontal manner and list objects from tbl_items vertically below each category name. I am confused how to get all this data using TSQL stored procedures and displaying them using ASP.NET native controls.
Columns with headers of category names. rows of items keyed with category_id.
The db is set up correctly. It is the ASP.NET controls I have trouble with.
I would use a Repeater myself, and make it output an HTML Table. The categories row would be in the HeaderTemplate, the closing tags in the FooterTemplate, and the actual data inside the ItemTemplate
http://blogs.sitepoint.com/asp-net-repeater-control/
The best way to handle this is to setup business objects which support the data in a way you wish to present it, which may not always be the way it is handled by your database.
Then you can use those objects directly to bind or feed data into the UI.
You could use Pivot to do that. See this referece http://msdn.microsoft.com/en-us/library/ms177410.aspx
My goal is to load a row from db to a webform and let the user update it's value .
The user searches an id (i have a stored procedure for that), how i show that data from the
row nicely in the web page through the dal layer. After the data is shown on the page the user need to update a cell in the row and send it.(the part of updating is not the problem).
in other questions how should the dal method should look and how i integrate it's result in the presentation layer (the aspx webform).
thanks a lot.
p.s.
I've done a little reading but i don't know what exactly to use data object, data row , data table, object data source. i'm little confused by the data bind alternatives.
You have several options and one of them is using ObjectDataSource.
If it is going to be a single record you can use DetailsView or Formview else you use GridView.
Check the tutorials here:
Displaying Data with ObjectDataSource
Data Access Tutorials
I have a selection list that is generated dynamically, it lists a number of checkboxes that are based on an end-user editable table, as such I have no idea what data, or how much, might be contained in this table and how many checkboxes or what they might contain, other than the primary keys of the table.
The user will select the checks they wish to see, and then control is passed to another page via PostBackUrl. The second page has to figure out which records to show (build it's where clause) based on the checkboxes checked in the previous page.
So, my problem is several-fold. First, asp:CheckBoxes don't have values. This can be worked around by a number of methods. Right now, i'm using a placeholder and dynamically creating the checkboxes in the ItemDataBound event of the DataList. I set the ID to "CheckboxKey1Key2" (where Key1 and Key2 are the primary keys of the check items).
Second, I have to walk through the controls of the PreviousPage to dig out all these values. That in itself is also a pain, but doable.
Now, my thinking is to build the where clause of my Linq2Sql query based on the keys I got from decoding the checked checkbox names. This all seems like a lot of jumping through hoops for something that shouldn't be this difficult. Am I missing something? Does anyone have any better solutions?
Make a class with a structure for your values that will be useful and easy for you to use on the result page. Then when the user clicks whatever it is they click to go to the result page, loop through the DataList, create a collection from the checked items, and you will only need to grab one object instead of everything, when you need to format your query.
Then when you get to the result page, loop through the collection and build the query in the loop. Pretty easy and not much code.
I have a relatively simple Listview that suddenly needs (due to new requirements) to have it's 'layout' extracted to a DataTable so that a common routine can convert it to an Excel spreadsheet for export purposes.
The ItemTemplate is just a series of Table Rows with some text, data-bound labels and textboxes with validators in the cells.
Usually, when trying to pull out a particular value (like what was entered into a text box), I use the ListViewItem's .FindControl method.
For Each objItem As ListViewItem In lvwOptions.Items
Dim objTextHrsLabor As TextBox = CType(objItem.FindControl("txtHrsOptByLabor"), TextBox)
decHours = CDec(objTextHrsLabor.Text)
Next
In this case, however, I'm trying to take all the data displayed - all the 'rows and columns' of the table that was created.
Inside the ForEach / Next loop of ListViewItems, I started a ForEach/Next loop of Controls for each instance's controls but I got some really strange results returned (like controls that had a couple of table cells in them).
I get the sense I'm headed in the wrong direction. All I want is for the nicely-formatted 5-line, 6 column table to be converted to a 5-line, 6-column data table.
Is there another avenue I should be looking at?
I would look at the underlying data source for your ListView.
The data source must be a collection or an IEnumerable and you should be able to iterate through it to build your data table.
If you know that all elements are of the same type then you can use the first element and look at its properties using reflection to determine which columns your table should contain. Then you can add DataRows to your table and fill in the columns using the property names.
This will probably be faster than iterating through the generated html of the ListView.
I used this approach for exporting a ListView to Excel: http://aspalliance.com/771_CodeSnip_Exporting_GridView_to_Excel.
I know it deals with a GridView, but I adapted it to a ListView (as long as the underlying structure is a table) and it worked fine for me.
HTH.
you can use..
listView1.Items[0].SubItems[0].Text
this will be helpful , really simple and easy . You can extract info right on the basis of index & use anyway you want.
I have a GridView inside of a User Control populated from a List of IObject. I need to get the contents of this GridView so I can export the data to CSV. I was just passing the whole GridView to the procedure and looping through it to get the data I needed. I am using MVP though, and was told this was a bad approach.
I want to convert the GridView back to a List of IObject, and then pass it to the Presenter. Any suggestions besides doing it the brute force way (looping through all columns and rows).
Sounds daft, but why don't you get the data the same way that you originally bind the GridView to?
I recently changed some code that was written the way you describe (I didn't write it)- it actually broke the application as the huge ViewState was too big for a postback (Maximum Request length exceeded)!
I merely extracted the data from the DB, cached it and then got the cached version for the export to CSV (it was actually export to Excel but that's beside the point).
Of course I turned the ViewState on the GridView off, as it was no longer needed.