p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   BOOK: ASP.NET 2.0 Website Programming Problem Design Solution ISBN: 978-0-7645-8464-0 (http://p2p.wrox.com/forumdisplay.php?f=264)
-   -   Additional page to my store (http://p2p.wrox.com/showthread.php?t=63309)

retroviz November 1st, 2007 09:07 AM

Hi John,

I imagine your asp:GridView (or datalist) control that shows your departments will have an ojbect datasource that uses a GetDepartments method (or something named similar).

You probably have a stored procedure named GetProductsByDepartment. You basically need to have a similar stored proc and related method in your departments class called GetDepartmentsByCategory where you pass the Category ID.
If you imagine you have the stored proc:
SELECT * FROM Departments
WHERE CategoryID=@CategoryID

You then just need to pass your @CategoryID parameter. So if you create a new method in your departments class that accepts such a value, you just need to add a QueryString parameter to the select parameters for your object datasource on the form.

Have a look at the way in which your products are filtered by dept. It should give you the info you need.

d-print November 1st, 2007 04:41 PM


ok, here goes.
you have been absolutely brilliant with all of the help that you have given me, however if i could be so bold as to ask you for a BIG favour and allow me to email you some files to help me finish this absolute headmess out as i am going round in error circles all the time.

i have completed the following:-

made my table for categories
created the same stored procedures for categories as departments with the inclusion of get department by cat id.
managed to retrieve a list to my ShowCategories page and also link through to the departments page and then onto the products list.
create my DAL & BLL for categories.

however i (think) i need to do the following but i am still learning about the DAL & BLL layers of this architecture. this is where i am struggling the most.
i havent added the procedures or the amendments to the department section to include my categoryID as this is really troubling me.
and i have tried & tried to pass the cat ID through to the Department page.

so, pls pls would you help me and allow me to email you some files so i can get this going with a little help?


retroviz November 2nd, 2007 06:02 AM


Could be interesting as I havent even looked at the Store section of TBH...

I will look at TBH C# version later on and write down the necessary changes to implement such functionality.
Should have a response for you some time this weekend.

d-print November 2nd, 2007 07:59 AM

thats great, thank-you.
if you need any additional information from me then i can provide it for you.

i have called my additional pages/table "StCategories" i.e store categories)

id in the departments table is called StCategoryID.
i am storing all the same details in the cats section as the dept section i.e DateAdded, AddedBy etc etc.


retroviz November 2nd, 2007 06:14 PM


Hope the following helps, I can't really go into much more details without actually implementing this within TBH (and I dont even need a store :))

Lets forget about the Category table and related classes and just look at the Departments table/classes as this is the where the problem is at the moment. Basically we need to pull out all the departments for a particular category.

1 > Create a new field CategoryID (int) within your TBH_Departments table.

2 > Next we need a stored procedure to extract all Departments for a specific category. I would use something like:


CREATE PROCEDURE dbo.tbh_Store_GetDepartmentsByCategoryID
    @CategoryID int

SELECT DepartmentID, CategoryID, AddedDate, AddedBy, Title, Importance, Description, ImageUrl
FROM dbo.tbh_Departments
WHERE CategoryID = @CategoryID
ORDER BY Importance DESC, Title ASC

3 > Now we have created our Stored Procedure we need to add a function in our SQLClient/SqlStoreProvider class to pass the required paramaters and return the results as a list (of DepartmentDetails):


        Public Overrides Function GetDepartmentByCategoryID(ByVal categoryID As Integer) As System.Collections.Generic.List(Of DepartmentDetails)
         Using cn As New SqlConnection(Me.ConnectionString)
                Dim cmd As New SqlCommand("tbh_Store_GetDepartments", cn)
                cmd.CommandType = CommandType.StoredProcedure
                cmd.Parameters.Add("@CategoryID", SqlDbType.Int).Value = categoryID
                Return GetDepartmentCollectionFromReader(ExecuteReader(cmd))
            End Using
        End Function

4 > Now we need to add a new method to our DAL StoreProvider class:


Public MustOverride Function GetDepartments(ByVal categoryID As Integer) As List(Of DepartmentDetails)
5 > Modify Function GetDepartmentFromReader(ByVal reader As IDataReader) As DepartmentDetails (in storeprovider class) to include additional CategoryID field

6 > Make the following changes to your DAL DepartmentDetails class:

    1 > Add new private variable _categoryID
    2 > Modify your New(ByVal ID as Integer....) constructor to include categoryID
    3 > Add new public property CategoryID

7 > Make the following changes to your BLL Department class:

    1 > Add new private variable _categoryID
    2 > Add new public property CategoryID
    3 > Modify New Constructor to include CategoryID
    4 > Add new public shared function (method) GetDepartmentsByCategoryID(ByVal categoryID as integer) - returns list (of department)

The code is in vb.net (cause thats what I know) but you should be able to adapt. I may have missed something out as have not looked at in too much details but essentially the steps are simple.

> You need a new field in your departments table
> You need a stored proc to get departments where the categoryID = value
> You need to create a new method in your sqlstoresprovider class that uses this new stored proc and passes the correct parameter returning a list of departmentdetails (just like your normal GetDepartments() method)
> Now you obviously need to add the new field to your departmentdetails class - so will need to create a new property for it. You will also need to add it to the new() constructor
> Then you need to create similar methods for your BLL

Once this is done you should be able to create a new page. Add a DataGridView control. Add a ObjectDataSource control using the GetDepartmentsByCategoryID(byVal CategoryID as Integer) method. Bind your gridview to this. Add a querystring paramater to your object datasource for CategoryID.

Finally test your work. Call: WhatEverYourPageIsCalled.aspx?CategoryID=#

passing a categoryID that you added to one of your department records and see if the correct data is returned.

One final point to mention is that I am still learning myself so invite anyone else to point out any errors I have made. I have been developing apps off and on for some time but only started working with ASP.net (and .net in general) about 1 year ago.

The great thing about this book (and TBH in general) is that all the different components of the site i.e. Articles, Store, Forum are developed using the same methodology. I recently added a resources section to my site allowing administrators to add "related downloads" to an article so that when users view an article they can download additional resources (but only if they're a member :D)

I achieved this by looking at the existing classes resulting in new functionality that ties in with the existing base classes taking full advantage of things like caching and membership that are already implemented in the site.


d-print November 4th, 2007 06:43 AM

Hi there Retroviz,

thanks for your last post, i have amended all the relevant files and tables and procedure and my site builds successfully now, however i keep getting the following error on my 'ShowDepartments.aspx' file:

Property accessor 'SelectedValue' on object 'System.Web.UI.WebControls.DataList' threw the following exception:'Data keys must be specified on DataList 'dlstDepartments' before the selected data key can be retrieved. Use the DataKeyField property to specify data keys.'

can you help?


retroviz November 4th, 2007 08:09 AM

Have you specified the DataKeyField for your DataList control i.e:

<asp:DataList ID="DataList1" runat="server" CellPadding="4" DataSourceID="ObjectDataSource1" DataKeyField="ID" ForeColor="#333333">

d-print November 4th, 2007 09:28 AM

had a look but i cannot see what the problem is in showing the data. i have posted my ShowDepartments page below to see if you can spot where i am going wrong:

<%@ Page Language="C#" MasterPageFile="~/Template.master" AutoEventWireup="true" CodeFile="ShowDepartments.aspx.cs" Inherits="MB.TheBeerHouse.UI.ShowDepartments" Title="KM Alarms Limited - Store Departments" %>
<%@ MasterType VirtualPath="~/Template.master" %>

<asp:Content ID="MainContent" ContentPlaceHolderID="MainContent" Runat="Server">
   <div class="sectiontitle">Store departments</div>
    Click on the title of the department for which you want to browse the products:
   <asp:DataList ID="dlstDepartments" EnableTheming="False" runat="server"
      DataSourceID="ObjectDataSource1" Width="100%" RepeatColumns="2">
          <asp:Label ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' />
          <br />
          <asp:Label ID="StCategoryIDLabel" runat="server"
              Text='<%# Eval("StCategoryID") %>' />
          <br />
          <asp:Label ID="ImportanceLabel" runat="server"
              Text='<%# Eval("Importance") %>' />
          <br />
          <asp:Label ID="DescriptionLabel" runat="server"
              Text='<%# Eval("Description") %>' />
          <br />
          <asp:Label ID="ImageUrlLabel" runat="server" Text='<%# Eval("ImageUrl") %>' />
          <br />
          <asp:Label ID="AllProductsLabel" runat="server"
              Text='<%# Eval("AllProducts") %>' />
          <br />
          <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' />
          <br />
          <asp:Label ID="AddedDateLabel" runat="server" Text='<%# Eval("AddedDate") %>' />
          <br />
          <asp:Label ID="AddedByLabel" runat="server" Text='<%# Eval("AddedBy") %>' />
          <br />
          <br />

   <asp:ObjectDataSource ID="objAllDepartments" runat="server" SelectMethod="GetDepartmentByStCategoryID"
           <asp:controlparameter ControlID="dlstDepartments" Name="stCategoryID"
               PropertyName="SelectedValue" Type="Int32" DefaultValue="1" />

the product list section is still in here so do you think i should also remove that from this page?


retroviz November 5th, 2007 08:33 AM


Have you missed some of the page off??

Your DataList control has a DataSourceID of ObjectDataSource1 but the ObjectDatasource control you have on your page has an ID of objAllDepartments.

Also your objectdatasource has an <asp:controlparameter>. I thought you were passing CategoryID from a querystring in which case you need: <asp:QueryStringParameter>
You should also set the DataKeyField property of your DataList control to stCategoryID

d-print November 5th, 2007 04:43 PM

Brilliant, brilliant, brilliant - it works.... the Categories page links through and displays the correct department!! brilliant. however...... i now get an error going through to my products page :( i am sure it is 1 tiny little error but i am absolutely sore eyed from looking... i get this error now.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IndexOutOfRangeException: StCategoryID

Source Error:

Line 135: protected virtual DepartmentDetails GetDepartmentFromReader(IDataReader reader)
Line 136: {
Line 137: return new DepartmentDetails(
Line 138: (int)reader["DepartmentID"],
Line 139: (int)reader["StCategoryID"],

Source File: c:\Users\KM Alarms Limited\Documents\Visual Studio 2008\WebSites\KM Alarms Limited\KM_Web\App_Code\DAL\StoreProvider.cs Line: 137

Stack Trace:

[IndexOutOfRangeException: StCategoryID]
   System.Data.ProviderBase.FieldNameLookup.GetOrdina l(String fieldName) +1427579
   System.Data.SqlClient.SqlDataReader.GetOrdinal(Str ing name) +102
   System.Data.SqlClient.SqlDataReader.get_Item(Strin g name) +12
   MB.TheBeerHouse.DAL.StoreProvider.GetDepartmentFro mReader(IDataReader reader) in c:\Users\KM Alarms Limited\Documents\Visual Studio 2008\WebSites\KM Alarms Limited\KM_Web\App_Code\DAL\StoreProvider.cs:137
   MB.TheBeerHouse.DAL.StoreProvider.GetDepartmentCol lectionFromReader(IDataReader reader) in c:\Users\KM Alarms Limited\Documents\Visual Studio 2008\WebSites\KM Alarms Limited\KM_Web\App_Code\DAL\StoreProvider.cs:166
   MB.TheBeerHouse.DAL.SqlClient.SqlStoreProvider.Get Departments() in c:\Users\KM Alarms Limited\Documents\Visual Studio 2008\WebSites\KM Alarms Limited\KM_Web\App_Code\DAL\SqlClient\SqlStoreProv ider.cs:28
   MB.TheBeerHouse.BLL.Store.Department.GetDepartment s() in c:\Users\KM Alarms Limited\Documents\Visual Studio 2008\WebSites\KM Alarms Limited\KM_Web\App_Code\BLL\Store\Department.cs:10 6

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle._InvokeMethodFast(Objec t target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +0
   System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +72
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) +308
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +29
   System.Web.UI.WebControls.ObjectDataSourceView.Inv okeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance) +480
   System.Web.UI.WebControls.ObjectDataSourceView.Exe cuteSelect(DataSourceSelectArguments arguments) +1960
   System.Web.UI.WebControls.ListControl.OnDataBindin g(EventArgs e) +92
   System.Web.UI.WebControls.ListControl.PerformSelec t() +31
   System.Web.UI.WebControls.BaseDataBoundControl.Dat aBind() +70
   MB.TheBeerHouse.UI.Controls.ProductListing.Page_Lo ad(Object sender, EventArgs e) in c:\Users\KM Alarms Limited\Documents\Visual Studio 2008\WebSites\KM Alarms Limited\KM_Web\Controls\ProductListing.ascx.cs:93
   System.Web.Util.CalliHelper.EventArgFunctionCaller (IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Cal lback(Object sender, EventArgs e) +33
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Control.LoadRecursive() +131
   System.Web.UI.Control.LoadRecursive() +131
   System.Web.UI.Control.LoadRecursive() +131
   System.Web.UI.Control.LoadRecursive() +131
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436

absolutely lost now......


All times are GMT -4. The time now is 05:15 AM.

Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.