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)

d-print October 29th, 2007 04:46 AM

Additional page to my store
 
Hi there,
Was just wondering if any of you could help me. I am trying to create an additional page in my store.

I am trying to add a 'storeCategories' section before i get to departments.

so the store goes: StCategories > Departments > Products
instead of Departments > Products

I have created an extra table called StCategories and i have also create the stored procedures.

how hard is this to do and has anyone actually completed it in their Project?

Regards
John

retroviz October 29th, 2007 06:38 PM

Hi John,
I havent needed to implement the store but I expect this could be accomplished in the same way most category based databased applications are. One method (as you have already done) is to create an additional table and create a relationship between this an the existing Departments table. If you have already created the Stored Procedures you must already know the data you need from this table so creating the new classes should not be that difficult (you will fine that you could probably copy the existing Departments classes). Another method is to have just one categories table that has an additional field (parentCategory). The advantage of this method is that you can have unlimited levels of categories, and this in my experience normally ends up being the requirement of most e-tailers.

Essentially all you are changing is the way in which you filter the current departments so you should not have to make any changes to the existing products table or classes.

I would suggest checking out the "Customer Support Site" example in Wrox's ASP.net 2.0 Instant Results as this uses the latter method of categorizing db records. You could probably download the app from here if you don't have the book.


d-print October 30th, 2007 05:26 AM

Thank you very much for you reply.
It is good to know that you are thinking along the same lines as me with this one.
I like the parent category idea as well so i might try it both ways.
I have been struggling trying to re-create the Departments CS to my new Category functions but i should over come this.

once again thanks for your reply, would it be possible to call on you again if i struggle?

Regards
John



d-print October 30th, 2007 06:47 AM

Just a quick one.
So i am right in thinking that the items i need to edit are the following:-

'SqlStore Provider' (copy all Department info to my Category info)
'Department' (copy this file and amend to categories)
'StoreProvider' (copy all Department info to my Category info)

would you be able to have a look at the resulting files when i have completed them for me :)

regards
John


d-print October 30th, 2007 09:01 AM

retroviz,

i have implemented all the extra additions that i need to do this but i cannot get my ShowStCategories page to load with out a exception error.

Would it be possible for me to email you my project for you to have a look at the coding to see if you can spot my error?

The database is already online and all stored procedures are in place as well as the table.

I have decided to create the extra table and just have a relationship with my departments table.

can you please please help?

Kind Regards
John Whiting


retroviz October 31st, 2007 04:06 AM

John,

May be worth checking your stored procedures for errors first. Can you post the details of the error you are getting?


d-print October 31st, 2007 04:16 AM

the error i am receiving is below.

Server Error in '/KM_Web' Application.
The method or operation is not implemented.
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.Exception: The method or operation is not implemented.

Source Error:

Line 105: private static List<StCategories> GetStCategoriesListFromStCategoriesDetailsList(Lis t<StCategoryDetails> recordset)
Line 106: {
Line 107: throw new Exception("The method or operation is not implemented.");
Line 108: }
Line 109:


Source File: c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\BLL\Store\StCategories.cs Line: 107

Stack Trace:

[Exception: The method or operation is not implemented.]
   MB.TheBeerHouse.BLL.Store.StCategories.GetStCatego riesListFromStCategoriesDetailsList(List`1 recordset) in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\BLL\Store\StCategories.cs: 107
   MB.TheBeerHouse.BLL.Store.StCategories.GetStCatego ries() in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\BLL\Store\StCategories.cs: 99

[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) +296
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +29
   System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +17
   System.Web.UI.WebControls.ObjectDataSourceView.Inv okeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance) +676
   System.Web.UI.WebControls.ObjectDataSourceView.Exe cuteSelect(DataSourceSelectArguments arguments) +2655
   System.Web.UI.WebControls.BaseDataList.GetData() +55
   System.Web.UI.WebControls.DataList.CreateControlHi erarchy(Boolean useDataSource) +381
   System.Web.UI.WebControls.BaseDataList.OnDataBindi ng(EventArgs e) +75
   System.Web.UI.WebControls.BaseDataList.DataBind() +86
   System.Web.UI.WebControls.BaseDataList.EnsureDataB ound() +82
   System.Web.UI.WebControls.BaseDataList.CreateChild Controls() +91
   System.Web.UI.Control.EnsureChildControls() +134
   System.Web.UI.WebControls.BaseDataList.get_Control s() +27
   MB.TheBeerHouse.Helpers.SetInputControlsHighlight( Control container, String className, Boolean onlyTextBoxes) in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\Helpers.cs:130
   MB.TheBeerHouse.Helpers.SetInputControlsHighlight( Control container, String className, Boolean onlyTextBoxes) in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\Helpers.cs:131
   MB.TheBeerHouse.Helpers.SetInputControlsHighlight( Control container, String className, Boolean onlyTextBoxes) in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\Helpers.cs:131
   MB.TheBeerHouse.Helpers.SetInputControlsHighlight( Control container, String className, Boolean onlyTextBoxes) in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\Helpers.cs:131
   MB.TheBeerHouse.UI.BasePage.OnLoad(EventArgs e) in c:\Documents and Settings\J Whiting\My Documents\Visual Studio 2005\WebSites\KM Alarms Limited\KM_Web\App_Code\BasePage.cs:55
   System.Web.UI.Control.LoadRecursive() +74
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3034

P.S Thanks for the book advice, i bought it yesterday and it arrived today.

regards
John


d-print October 31st, 2007 09:25 AM

retroviz,

please ignore the error as i have now managed to apply the additional page - i now just need to tie it all in with my admin section etc.

The only problem i have got now is that i can go from my categories page to my department page and then onto products, however the list of departments from the category page is not listing the relevant departments under that catID - it is only returning the department with an ID of 1.....

can you help?

Regards
John


retroviz October 31st, 2007 02:10 PM

John,

I imagine your departments were already created prior to adding the categories table. I would check that each of the department records in your departments table have an associated CategoryID value (or whatever the PK of your category table is).

If all of your departments DO have an associated CategoryID try manually passing the Category ID in your querystring rather than clicking on a hyperlink from your categories page i.e. "ShowDepartments.aspx?CategoryID=2" (or whatever your page is called).

This will then determine whether it is your departments classes/methods failing to retrieve the correct data or just your categories page failing to pass the correct querystring.

Hope that helps

d-print October 31st, 2007 06:39 PM

retroviz,

thanks for yet another reply/answer.
I did mange to do this earlier.

I have set up a test cat & a test cat 2 which 'should' be linked to dept 1 & dept 2. when i click on cat 1 and ID of 1 is passed and when i click on cat 2 an ID of 2 is passed so that is fine.

the departments page just appears to be showing a list of everything in the dapartments table and not by the specific CatID i am passing.

you mentiontioned in your last post that i should look at the Class/method for the departments, where/what in particulr do you think i should have changed with these pages as it appears to me that i obviously havent......:(

regards
John


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

retroviz.

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?

Regards
John


retroviz November 2nd, 2007 06:02 AM

John,

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.

regards
John


retroviz November 2nd, 2007 06:14 PM

John,

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:

Code:

CREATE PROCEDURE dbo.tbh_Store_GetDepartmentsByCategoryID
{
    @CategoryID int
}
AS
SET NOCOUNT ON

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):

Code:

        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
                cn.Open()
                Return GetDepartmentCollectionFromReader(ExecuteReader(cmd))
            End Using
        End Function



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

Code:

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.

Thanks,

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?

regards
John


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>
   <p></p>
    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">
      <ItemTemplate>
          Title:
          <asp:Label ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' />
          <br />
          StCategoryID:
          <asp:Label ID="StCategoryIDLabel" runat="server"
              Text='<%# Eval("StCategoryID") %>' />
          <br />
          Importance:
          <asp:Label ID="ImportanceLabel" runat="server"
              Text='<%# Eval("Importance") %>' />
          <br />
          Description:
          <asp:Label ID="DescriptionLabel" runat="server"
              Text='<%# Eval("Description") %>' />
          <br />
          ImageUrl:
          <asp:Label ID="ImageUrlLabel" runat="server" Text='<%# Eval("ImageUrl") %>' />
          <br />
          AllProducts:
          <asp:Label ID="AllProductsLabel" runat="server"
              Text='<%# Eval("AllProducts") %>' />
          <br />
          ID:
          <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' />
          <br />
          AddedDate:
          <asp:Label ID="AddedDateLabel" runat="server" Text='<%# Eval("AddedDate") %>' />
          <br />
          AddedBy:
          <asp:Label ID="AddedByLabel" runat="server" Text='<%# Eval("AddedBy") %>' />
          <br />
          <br />
      </ItemTemplate>
   </asp:DataList>

   <asp:ObjectDataSource ID="objAllDepartments" runat="server" SelectMethod="GetDepartmentByStCategoryID"
      TypeName="MB.TheBeerHouse.BLL.Store.Department">
       <SelectParameters>
           <asp:controlparameter ControlID="dlstDepartments" Name="stCategoryID"
               PropertyName="SelectedValue" Type="Int32" DefaultValue="1" />
       </SelectParameters>
   </asp:ObjectDataSource>
</asp:Content>

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

regards
John


retroviz November 5th, 2007 08:33 AM

John,

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.

StCategoryID
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......

john


retroviz November 5th, 2007 07:28 PM

John,

I expect you have failed to update one of your department methods with the additional CategoryID field. I have done this quite a few times in the past where you may add a property to your class but then forget to pass the variable in your associated methods i.e. you either miss a value or try and cast as the wrong datatype.

I would just double check your departments methods and make sure you have included the value for CategoryID where appropriate.

Hope that helps.



d-print November 6th, 2007 05:29 AM

i have been looking through my methods now for about 4 hours but again to no avail, i just cannot see the problem. i have posted my StoreProvider below to see if anyone here can spot an error in my methods.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

namespace MB.TheBeerHouse.DAL
{
   public abstract class StoreProvider : DataAccess
   {
      static private StoreProvider _instance = null;
      /// <summary>
      /// Returns an instance of the provider type specified in the config file
      /// </summary>
      static public StoreProvider Instance
      {
         get
         {
            if (_instance == null)
               _instance = (StoreProvider)Activator.CreateInstance(
                  Type.GetType(Globals.Settings.Store.ProviderType)) ;
            return _instance;
         }
      }

      public StoreProvider()
      {
         this.ConnectionString = Globals.Settings.Store.ConnectionString;
         this.EnableCaching = Globals.Settings.Store.EnableCaching;
         this.CacheDuration = Globals.Settings.Store.CacheDuration;
      }

      // methods that work with stCategories
      public abstract List<StCategoryDetails> GetStCategories();
      public abstract StCategoryDetails GetStCategoriesByID(int stCategoryID);
      public abstract bool DeleteStCategories(int stCategoryID);
      public abstract bool UpdateStCategories(StCategoryDetails stCategories);
      public abstract int InsertStCategories(StCategoryDetails stCategories);

      // methods that work with departments
      public abstract List<DepartmentDetails> GetDepartments();
      public abstract DepartmentDetails GetDepartmentByID(int departmentID);
      public abstract DepartmentDetails GetDepartmentByStCategoryID(int stCategoryID);
      public abstract bool DeleteDepartment(int departmentID);
      public abstract bool UpdateDepartment(DepartmentDetails department);
      public abstract int InsertDepartment(DepartmentDetails department);

      // methods that work with order statuses
      public abstract List<OrderStatusDetails> GetOrderStatuses();
      public abstract OrderStatusDetails GetOrderStatusByID(int orderStatusID);
      public abstract bool DeleteOrderStatus(int orderStatusID);
      public abstract bool UpdateOrderStatus(OrderStatusDetails orderStatus);
      public abstract int InsertOrderStatus(OrderStatusDetails orderStatus);

      // methods that work with shipping methods
      public abstract List<ShippingMethodDetails> GetShippingMethods();
      public abstract ShippingMethodDetails GetShippingMethodByID(int orderStatusID);
      public abstract bool DeleteShippingMethod(int shippingMethodID);
      public abstract bool UpdateShippingMethod(ShippingMethodDetails shippingMethod);
      public abstract int InsertShippingMethod(ShippingMethodDetails shippingMethod);

      // methods that work with products
      public abstract List<ProductDetails> GetProducts(string sortExpression, int pageIndex, int pageSize);
      public abstract List<ProductDetails> GetProducts(int departmentID, string sortExpression, int pageIndex, int pageSize);
      public abstract int GetProductCount();
      public abstract int GetProductCount(int departmentID);
      public abstract ProductDetails GetProductByID(int productID);
      public abstract bool DeleteProduct(int productID);
      public abstract bool UpdateProduct(ProductDetails product);
      public abstract int InsertProduct(ProductDetails product);
      public abstract bool RateProduct(int productID, int rating);
      public abstract bool DecrementProductUnitsInStock(int productID, int quantity);
      public abstract string GetProductDescription(int productID);

      // methods that work with orders
      public abstract List<OrderDetails> GetOrders(int statusID, DateTime fromDate, DateTime toDate);
      public abstract List<OrderDetails> GetOrders(string addedBy);
      public abstract OrderDetails GetOrderByID(int orderID);
      public abstract bool DeleteOrder(int orderID);
      public abstract int InsertOrder(OrderDetails order);
      public abstract bool UpdateOrder(OrderDetails order);

      // methods that work with order items
      public abstract List<OrderItemDetails> GetOrderItems(int orderID);
      public abstract int InsertOrderItem(OrderItemDetails orderItem);

      /// <summary>
      /// Returns a valid sort expression for the products
      /// </summary>
      protected virtual string EnsureValidProductsSortExpression(string sortExpression)
      {
         if (string.IsNullOrEmpty(sortExpression))
            return "tbh_Products.Title ASC";

         string sortExpr = sortExpression.ToLower();
         if (!sortExpr.Equals("unitprice") && !sortExpr.Equals("unitprice asc") && !sortExpr.Equals("unitprice desc") &&
            !sortExpr.Equals("discountpercentage") && !sortExpr.Equals("discountpercentage asc") && !sortExpr.Equals("discountpercentage desc") &&
            !sortExpr.Equals("addeddate") && !sortExpr.Equals("addeddate asc") && !sortExpr.Equals("addeddate desc") &&
            !sortExpr.Equals("addedby") && !sortExpr.Equals("addedby asc") && !sortExpr.Equals("addedby desc") &&
            !sortExpr.Equals("unitsinstock") && !sortExpr.Equals("unitsinstock asc") && !sortExpr.Equals("unitsinstock desc") &&
            !sortExpr.Equals("title") && !sortExpr.Equals("title asc") && !sortExpr.Equals("title desc"))
         {
            sortExpr = "title asc";
         }
         if (!sortExpr.StartsWith("tbh_products"))
            sortExpr = "tbh_products." + sortExpr;
         if (!sortExpr.StartsWith("tbh_products.title"))
            sortExpr += ", tbh_products.title asc";
         return sortExpr;
      }

      /// <summary>
      /// Returns a new StCategoryDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual StCategoryDetails GetStCategoriesFromReader(IDataReader reader)
      {
          return new StCategoryDetails(
             (int)reader["StCategoryID"],
             (DateTime)reader["AddedDate"],
             reader["AddedBy"].ToString(),
             reader["Title"].ToString(),
             (int)reader["Importance"],
             reader["Description"].ToString(),
             reader["ImageUrl"].ToString());
      }

      /// <summary>
      /// Returns a new DepartmentDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual DepartmentDetails GetDepartmentFromReader(IDataReader reader)
      {
         return new DepartmentDetails(
            (int)reader["DepartmentID"],
            (DateTime)reader["AddedDate"],
            reader["AddedBy"].ToString(),
            reader["Title"].ToString(),
            (int)reader["Importance"],
            reader["Description"].ToString(),
            reader["ImageUrl"].ToString(),
            (int)reader["StCategoryID"]);
      }

      /// <summary>
      /// Returns a collection of StCategoryDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<StCategoryDetails> GetStCategoriesCollectionFromReader(IDataReader reader)
      {
          List<StCategoryDetails> stCategories = new List<StCategoryDetails>();
          while (reader.Read())
              stCategories.Add(GetStCategoriesFromReader(reader) );
          return stCategories;
      }

      /// <summary>
      /// Returns a collection of DepartmentDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<DepartmentDetails> GetDepartmentCollectionFromReader(IDataReader reader)
      {
         List<DepartmentDetails> departments = new List<DepartmentDetails>();
         while (reader.Read())
            departments.Add(GetDepartmentFromReader(reader));
         return departments;
      }

      /// <summary>
      /// Returns a new OrderStatusDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual OrderStatusDetails GetOrderStatusFromReader(IDataReader reader)
      {
         return new OrderStatusDetails(
            (int)reader["OrderStatusID"],
            (DateTime)reader["AddedDate"],
            reader["AddedBy"].ToString(),
            reader["Title"].ToString());
      }

      /// <summary>
      /// Returns a collection of OrderStatusDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<OrderStatusDetails> GetOrderStatusCollectionFromReader(IDataReader reader)
      {
         List<OrderStatusDetails> orderStatuses = new List<OrderStatusDetails>();
         while (reader.Read())
            orderStatuses.Add(GetOrderStatusFromReader(reader) );
         return orderStatuses;
      }

      /// <summary>
      /// Returns a new ShippingMethodDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual ShippingMethodDetails GetShippingMethodFromReader(IDataReader reader)
      {
         return new ShippingMethodDetails(
            (int)reader["ShippingMethodID"],
            (DateTime)reader["AddedDate"],
            reader["AddedBy"].ToString(),
            reader["Title"].ToString(),
            (decimal)reader["Price"]);
      }

      /// <summary>
      /// Returns a collection of ShippingMethodDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<ShippingMethodDetails> GetShippingMethodCollectionFromReader(IDataReader reader)
      {
         List<ShippingMethodDetails> shippingMethods = new List<ShippingMethodDetails>();
         while (reader.Read())
            shippingMethods.Add(GetShippingMethodFromReader(re ader));
         return shippingMethods;
      }

      /// <summary>
      /// Returns a new ProductDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual ProductDetails GetProductFromReader(IDataReader reader)
      {
         return GetProductFromReader(reader, true);
      }
      protected virtual ProductDetails GetProductFromReader(IDataReader reader, bool readDescription)
      {
         ProductDetails product = new ProductDetails(
            (int)reader["ProductID"],
            (DateTime)reader["AddedDate"],
            reader["AddedBy"].ToString(),
            (int)reader["DepartmentID"],
            reader["DepartmentTitle"].ToString(),
            reader["Title"].ToString(),
            null,
            reader["SKU"].ToString(),
            (decimal)reader["UnitPrice"],
            (int)reader["DiscountPercentage"],
            (int)reader["UnitsInStock"],
            reader["SmallImageUrl"].ToString(),
            reader["FullImageUrl"].ToString(),
            (int)reader["Votes"],
            (int)reader["TotalRating"]);

         if (readDescription)
            product.Description = reader["Description"].ToString();

         return product;
      }

      /// <summary>
      /// Returns a collection of ProductDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<ProductDetails> GetProductCollectionFromReader(IDataReader reader)
      {
         return GetProductCollectionFromReader(reader, true);
      }
      protected virtual List<ProductDetails> GetProductCollectionFromReader(IDataReader reader, bool readDescription)
      {
         List<ProductDetails> products = new List<ProductDetails>();
         while (reader.Read())
            products.Add(GetProductFromReader(reader, readDescription));
         return products;
      }

      /// <summary>
      /// Returns a new OrderItemDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual OrderItemDetails GetOrderItemFromReader(IDataReader reader)
      {
         return new OrderItemDetails(
            (int)reader["OrderItemID"],
            (DateTime)reader["AddedDate"],
            reader["AddedBy"].ToString(),
            (int)reader["OrderID"],
            (int)reader["ProductID"],
            reader["Title"].ToString(),
            reader["SKU"].ToString(),
            (decimal)reader["UnitPrice"],
            (int)reader["Quantity"]);
      }

      /// <summary>
      /// Returns a collection of OrderItemDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<OrderItemDetails> GetOrderItemCollectionFromReader(IDataReader reader)
      {
         List<OrderItemDetails> orderItems = new List<OrderItemDetails>();
         while (reader.Read())
            orderItems.Add(GetOrderItemFromReader(reader));
         return orderItems;
      }

      /// <summary>
      /// Returns a new OrderDetails instance filled with the DataReader's current record data
      /// </summary>
      protected virtual OrderDetails GetOrderFromReader(IDataReader reader)
      {
         return new OrderDetails(
            (int)reader["OrderID"],
            (DateTime)reader["AddedDate"],
            reader["AddedBy"].ToString(),
            (int)reader["StatusID"],
            reader["StatusTitle"].ToString(),
            reader["ShippingMethod"].ToString(),
            (decimal)reader["SubTotal"],
            (decimal)reader["Shipping"],
            reader["ShippingFirstName"].ToString(),
            reader["ShippingLastName"].ToString(),
            reader["ShippingStreet"].ToString(),
            reader["ShippingPostalCode"].ToString(),
            reader["ShippingCity"].ToString(),
            reader["ShippingState"].ToString(),
            reader["ShippingCountry"].ToString(),
            reader["CustomerEmail"].ToString(),
            reader["CustomerPhone"].ToString(),
            reader["CustomerFax"].ToString(),
            (reader["ShippedDate"] == DBNull.Value ? DateTime.MinValue : (DateTime)reader["ShippedDate"]),
            reader["TransactionID"].ToString(),
            reader["TrackingID"].ToString());
      }

      /// <summary>
      /// Returns a collection of OrderDetails objects with the data read from the input DataReader
      /// </summary>
      protected virtual List<OrderDetails> GetOrderCollectionFromReader(IDataReader reader)
      {
         List<OrderDetails> orders = new List<OrderDetails>();
         while (reader.Read())
            orders.Add(GetOrderFromReader(reader));
         return orders;
      }
   }
}


cheers
john


retroviz November 6th, 2007 06:01 AM

John,

The cause of this error may not be in your StoreProvider class. As previously said, it is more likely one of the methods from either your BLL or DAL classes causing this. I do not understand why you are having this problem when viewing products as this should not have changed. What happens when you manually enter the URL i.e. "products.aspx?DepartmentID=#" Do you still get the error. I suggest you put a pause/break in your code and Debug. You can step through by pressing F8 and this should show the method thats causing the problem.


d-print November 6th, 2007 07:10 AM

ok, i have passed the ID and i get the same error, i have tried tracing the error in the method but again i am struggling. your years experience far out strips my 3 months experience so i wondered if you could have a look at my methods? i have posted my Department.cs her and also my DepartmentDetails on another post.
Can you see the error?
i wondered if it was to do with having a DepartmentsDetails section twice in my StoreProvider?

DEPARTMENT.CS:-

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using MB.TheBeerHouse.DAL;

namespace MB.TheBeerHouse.BLL.Store
{
   public class Department : BaseStore
   {
      private string _title = "";
      public string Title
      {
         get { return _title; }
         set { _title = value; }
      }

      private int _stCategoryID = 0;
      public int StCategoryID
      {
          get { return _stCategoryID; }
          set { _stCategoryID = value; }
      }

      private int _importance = 0;
      public int Importance
      {
         get { return _importance; }
         private set { _importance = value; }
      }

      private string _description = "";
      public string Description
      {
         get { return _description; }
         set { _description = value; }
      }

      private string _imageUrl = "";
      public string ImageUrl
      {
         get { return _imageUrl; }
         set { _imageUrl = value; }
      }

      private List<Product> _allProducts = null;
      public List<Product> AllProducts
      {
         get
         {
            if (_allProducts == null)
               _allProducts = Product.GetProducts(this.ID, "", 0, BizObject.MAXROWS);
            return _allProducts;
         }
      }

      public Department(int id, int stCategoryid, DateTime addedDate, string addedBy, string title, int importance, string description, string imageUrl)
      {
         this.ID = id;
         this.StCategoryID = id;
         this.AddedDate = addedDate;
         this.AddedBy = addedBy;
         this.Title = title;
         this.Importance = importance;
         this.Description = description;
         this.ImageUrl = imageUrl;
      }

      public bool Delete()
      {
         bool success = Department.DeleteDepartment(this.ID);
         if (success)
            this.ID = 0;
         return success;
      }

      public bool Update()
      {
         return Department.UpdateDepartment(this.ID, this.StCategoryID, this.Title, this.Importance, this.Description, this.ImageUrl);
      }

      /***********************************
      * Static methods
      ************************************/

      /// <summary>
      /// Returns a collection with all the departments
      /// </summary>
      public static List<Department> GetDepartments()
      {
         List<Department> departments = null;
         string key = "Store_Departments";

         if (BaseStore.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            departments = (List<Department>)BizObject.Cache[key];
         }
         else
         {
            List<DepartmentDetails> recordset = SiteProvider.Store.GetDepartments();
            departments = GetDepartmentListFromDepartmentDetailsList(records et);
            BaseStore.CacheData(key, departments);
         }
         return departments;
      }

      /// <summary>
      /// Returns a Department object with the specified ID
      /// </summary>
      public static Department GetDepartmentByID(int departmentID)
      {
         Department department = null;
         string key = "Store_Department_" + departmentID.ToString();

         if (BaseStore.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            department = (Department)BizObject.Cache[key];
         }
         else
         {
            department = GetDepartmentFromDepartmentDetails(SiteProvider.St ore.GetDepartmentByID(departmentID));
            BaseStore.CacheData(key, department);
         }
         return department;
      }

      /// <summary>
      /// Updates an existing department
      /// </summary>
      public static bool UpdateDepartment(int id, int stCategoryID, string title, int importance, string description, string imageUrl)
      {
         DepartmentDetails record = new DepartmentDetails(id, DateTime.Now, "", title, importance, description, imageUrl, stCategoryID);
         bool ret = SiteProvider.Store.UpdateDepartment(record);
         BizObject.PurgeCacheItems("store_department");
         return ret;
      }

      /// <summary>
      /// Deletes an existing department
      /// </summary>
      public static bool DeleteDepartment(int id)
      {
         bool ret = SiteProvider.Store.DeleteDepartment(id);
         new RecordDeletedEvent("department", id, null).Raise();
         BizObject.PurgeCacheItems("store_department");
         return ret;
      }

      /// <summary>
      /// Creates a new department
      /// </summary>
      public static int InsertDepartment(string title, int importance, string description, string imageUrl, int stCategoryID)
      {
          DepartmentDetails record = new DepartmentDetails(0, DateTime.Now,
            BizObject.CurrentUserName, title, importance, description, imageUrl, stCategoryID);
         int ret = SiteProvider.Store.InsertDepartment(record);
         BizObject.PurgeCacheItems("store_department");
         return ret;
      }

      /// <summary>
      /// Returns a Department object filled with the data taken from the input DepartmentDetails
      /// </summary>
      private static Department GetDepartmentFromDepartmentDetails(DepartmentDetai ls record)
      {
         if (record == null)
            return null;
         else
         {
            return new Department(record.ID, record.StCategoryID, record.AddedDate, record.AddedBy, record.Title, record.Importance, record.Description, record.ImageUrl);
         }
      }

      /// <summary>
      /// Returns a list of Department objects filled with the data taken from the input list of DepartmentDetails
      /// </summary>
      private static List<Department> GetDepartmentListFromDepartmentDetailsList(List<De partmentDetails> recordset)
      {
         List<Department> departments = new List<Department>();
         foreach (DepartmentDetails record in recordset)
            departments.Add(GetDepartmentFromDepartmentDetails (record));
         return departments;
      }

      internal static List<Department> GetDepartments(int p, string p_2, int p_3, int p_4)
      {
          throw new Exception("The method or operation is not implemented.");
      }


      /// <summary>
      /// Returns a Department object with the specified StCategoryID
      /// </summary>
      public static Department GetDepartmentByStCategoryID(int stCategoryID)
      {
          Department department = null;
          string key = "Store_Department_" + stCategoryID.ToString();

          if (BaseStore.Settings.EnableCaching && BizObject.Cache[key] != null)
          {
              department = (Department)BizObject.Cache[key];
          }
          else
          {
              department = GetDepartmentFromDepartmentDetails(SiteProvider.St ore.GetDepartmentByStCategoryID(stCategoryID));
              BaseStore.CacheData(key, department);
          }
          return department;
      }


  }
}


JOHN


d-print November 6th, 2007 07:10 AM

DEPARTMENTDETAILS.CS:-

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace MB.TheBeerHouse.DAL
{
   public class DepartmentDetails
   {
      public DepartmentDetails() { }

      public DepartmentDetails(int id, DateTime addedDate, string addedBy, string title, int importance, string description, string imageUrl, int stCategoryID)
      {
         this.ID = id;
         this.AddedDate = addedDate;
         this.AddedBy = addedBy;
         this.Title = title;
         this.Importance = importance;
         this.Description = description;
         this.ImageUrl = imageUrl;
         this.StCategoryID = id;
      }

      private int _id = 0;
       public int ID
       {
           get { return _id;}
           set { _id = value;}
       }

      private DateTime _addedDate = DateTime.Now;
      public DateTime AddedDate
      {
         get { return _addedDate; }
         set { _addedDate = value; }
      }

      private string _addedBy = "";
      public string AddedBy
      {
         get { return _addedBy; }
         set { _addedBy = value; }
      }

      private string _title = "";
      public string Title
      {
         get { return _title; }
         set { _title = value; }
      }

      private int _importance = 0;
      public int Importance
      {
         get { return _importance; }
         set { _importance = value; }
      }

      private string _description = "";
      public string Description
      {
         get { return _description; }
         set { _description = value; }
      }

      private string _imageUrl = "";
      public string ImageUrl
      {
         get { return _imageUrl; }
         set { _imageUrl = value; }
      }

      private int _stCategoryid = 0;
      public int StCategoryID
      {
          get { return _stCategoryid; }
          set { _stCategoryid = value; }
      }
   }
}

JOHN


d-print November 6th, 2007 09:30 AM

I have gone through all of my coding for the deps page & all of the classes etc and it appears that the error is being thrown by the ProductListing Control, inparticular the Dropdown menu that allows you to have a list of all departments. 'GetDepartments'
there appears to be an error with the page trying to get the ID of both the department & category.

Does this sound likely to you?

John


retroviz November 6th, 2007 03:10 PM

Your GetDepartments method should not have changed so not sure why you it is requesting the CategoryID on your product listing page. If you create a new .aspx page and add a DropDownList control and bind it to an object datasource using that method, do you get the same error?


d-print November 7th, 2007 04:57 AM

Retroviz,

I Have to say a massive thank-you to you for all of your help on this one.

my pages work fine now and thanks to you last post i realised where i was going wrong.
Although i was able to F5 and debug my application, the database i have the web.config file pointed to is on a live server so i was missing an StCategoryID from one of my stored procedures.

doh!

anyhow, thank-you once again :)
Kind Regards
John

P.S thanks for the book info, i have now completed about half of it and some of the functions are really cool. cheers



retroviz November 7th, 2007 06:01 PM

Hi John,

No problem, glad to help. At least if I ever want to add a shop I will already know what to do ;)

Post the URL of your site once you have it up and running so we can all see.

Another book I would recommend is Professional ASP.net 2.0 (also by Wrox). This is more of a reference book but it does cover almost every aspect of ASP.net 2.0. I have certainly found this valuable learning tool in the past.

Cheers


leonardop November 23rd, 2007 11:32 AM

My first post !!!![^]
Could you share the procedures it completes and the files?

Regards
leonardo



All times are GMT -4. The time now is 06:17 AM.

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