File Upload Option When Adding A New Record: Step 1: Adding An Method To The
File Upload Option When Adding A New Record: Step 1: Adding An Method To The
Step1:AddinganInsertWithPicture Methodtothe
CategoriesTableAdapter
WhenwecreatedtheCategoriesTableAdapter backintheCreatingaDataAccessLayer tutorial,weconfigured ittoautomaticallygenerateINSERT,UPDATE,andDELETE statementsbasedonthemainquery.Moreover,we instructedtheTableAdaptertoemploytheDBDirectapproach,whichcreatedthemethodsInsert,Update,and Delete.ThesemethodsexecutetheautogeneratedINSERT,UPDATE,andDELETE statementsand,consequently, acceptinputparametersbasedonthecolumnsreturnedbythemainquery.IntheUploadingFilestutorialwe augmentedtheCategoriesTableAdaptersmainquerytousetheBrochurePath column. SincetheCategoriesTableAdaptersmainquerydoesnotreferencethePicture column,wecanneitheradda newrecordnorupdateanexistingrecordwithavalueforthePicture column.Inordertocapturethisinformation, wecaneithercreateanewmethodintheTableAdapterthatisusedspecificallytoinsertarecordwithbinarydata orwecancustomizetheautogeneratedINSERT statement.Theproblemwithcustomizingtheautogenerated INSERT statementisthatweriskhavingourcustomizationsoverwrittenbythewizard.Forexample,imaginethat wecustomizedtheINSERT statementtoincludeuseofthePicture column.ThiswouldupdatetheTableAdapters Insert methodtoincludeanadditionalinputparameterforthecategoryspicturesbinarydata.Wecouldthen createamethodintheBusinessLogicLayertousethisDALmethodandinvokethisBLLmethodthroughthe PresentationLayer,andeverythingwouldworkwonderfully.Thatis,untilthenexttimeweconfiguredthe TableAdapterthroughtheTableAdapterConfigurationwizard.Assoonasthewizardcompleted,our customizationstotheINSERT statementwouldbeoverwritten,theInsert methodwouldreverttoitsoldform,and ourcodewouldnolongercompile! Note:ThisannoyanceisanonissuewhenusingstoredproceduresinsteadofadhocSQLstatements.A
1 of17
futuretutorialwillexploreusingstoredproceduresinlieuofadhocSQLstatementsintheDataAccess Layer. Toavoidthispotentialheadache,ratherthancustomizingtheautogeneratedSQLstatementsletsinsteadcreatea newmethodfortheTableAdapter.Thismethod,namedInsertWithPicture,willacceptvaluesforthe CategoryName,Description,BrochurePath,andPicture columnsandexecuteanINSERT statementthatstores allfourvaluesinanewrecord. OpentheTypedDataSetand,fromtheDesigner,rightclickontheCategoriesTableAdaptersheaderand chooseAddQueryfromthecontextmenu.ThislaunchestheTableAdapterQueryConfigurationWizard,which beginsbyaskingushowtheTableAdapterqueryshouldaccessthedatabase.ChooseUseSQLstatementsand clickNext.Thenextsteppromptsforthetypeofquerytobegenerated.Sincewerecreatingaquerytoaddanew recordtotheCategories table,chooseINSERTandclickNext.
Figure1:SelecttheINSERTOption
WenowneedtospecifytheINSERT SQLstatement.ThewizardautomaticallysuggestsanINSERT statement correspondingtotheTableAdaptersmainquery.Inthiscase,itsanINSERT statementthatinsertsthe CategoryName,Description,andBrochurePath values.UpdatethestatementsothatthePicture columnis includedalongwitha@Picture parameter,likeso:
INSERTINTO[Categories] ([CategoryName],[Description],[BrochurePath],[Picture]) VALUES (@CategoryName,@Description,@BrochurePath,@Picture)
2 of17
Figure2:NametheNewTableAdapterMethodInsertWithPicture
Step2:UpdatingtheBusinessLogicLayer
SincethePresentationLayershouldonlyinterfacewiththeBusinessLogicLayerratherthanbypassingittogo directlytotheDataAccessLayer,weneedtocreateaBLLmethodthatinvokestheDALmethodwejustcreated (InsertWithPicture).Forthistutorial,createamethodintheCategoriesBLL classnamedInsertWithPicture thatacceptsasinputthreeStringsandaByte array.TheString inputparametersareforthecategorysname, description,andbrochurefilepath,whiletheByte arrayisforthebinarycontentsofthecategoryspicture.Asthe followingcodeshows,thisBLLmethodinvokesthecorrespondingDALmethod:
<System.ComponentModel.DataObjectMethodAttribute_ (System.ComponentModel.DataObjectMethodType.Insert,False)>_ PublicSubInsertWithPicture(categoryNameAsString,descriptionAsString,_ brochurePathAsString,picture()AsByte) Adapter.InsertWithPicture(categoryName,description,brochurePath,picture) EndSub
3 of17
InsertWithPicture method.
Step3:ListingtheExistingCategoriesandtheirBinaryData
Inthistutorialwewillcreateapagethatallowsanendusertoaddanewcategorytothesystem,providinga pictureandbrochureforthenewcategory.Intheprecedingtutorial weusedaGridViewwithaTemplateFieldand ImageFieldtodisplayeachcategorysname,description,picture,andalinktodownloaditsbrochure.Lets replicatethatfunctionalityforthistutorial,creatingapagethatbothlistsallexistingcategoriesandallowsfornew onestobecreated. StartbyopeningtheDisplayOrDownload.aspx pagefromtheBinaryData folder.GototheSourceviewand copytheGridViewandObjectDataSourcesdeclarativesyntax,pastingitwithinthe<asp:Content> elementin UploadInDetailsView.aspx.Also,dontforgettocopyoverthe GenerateBrochureLink methodfromthecode behindclassofDisplayOrDownload.aspx toUploadInDetailsView.aspx.
Figure3:CopyandPastetheDeclarativeSyntaxfromDisplayOrDownload.aspx to
UploadInDetailsView.aspx
4 of17
Figure4:YouShouldNowSeeEachCategoryAlongwithItsBinaryData
Step4:ConfiguringtheCategoriesDataSource toSupportInserting
TheCategoriesDataSource ObjectDataSourceusedbytheCategories GridViewcurrentlydoesnotprovidethe abilitytoinsertdata.Inordertosupportinsertingthroughthisdatasourcecontrol,weneedtomapitsInsert methodtoamethodinitsunderlyingobject,CategoriesBLL.Inparticular,wewanttomapittothe CategoriesBLL methodweaddedbackinStep2,InsertWithPicture . StartbyclickingtheConfigureDataSourcelinkfromtheObjectDataSourcessmarttag.Thefirstscreenshowsthe objectthedatasourceisconfiguredtoworkwith,CategoriesBLL.LeavethissettingasisandclickNextto advancetotheDefineDataMethodsscreen.MovetotheINSERTtabandpicktheInsertWithPicture method fromthedropdownlist.ClickFinishtocompletethewizard.
5 of17
Figure5:ConfiguretheObjectDataSourcetousetheInsertWithPicture Method
Step5:CreatingtheInsertingInterface
AsfirstcoveredintheAnOverviewofInserting,Updating,andDeletingData,theDetailsViewcontrolprovidesa builtininsertinginterfacethatcanbeutilizedwhenworkingwithadatasourcecontrolthatsupportsinserting. LetsaddaDetailsViewcontroltothispageabovetheGridViewthatwillpermanentlyrenderitsinserting interface,allowingausertoquicklyaddanewcategory.UponaddinganewcategoryintheDetailsView,the 6 of17
Figure6:BindtheDetailsViewtotheCategoriesDataSource andEnableInserting
TopermanentlyrendertheDetailsViewinitsinsertinginterface,setitsDefaultMode propertytoInsert. NotethattheDetailsViewhasfiveBoundFieldsCategoryID,CategoryName,Description, NumberOfProducts,andBrochurePath althoughtheCategoryID BoundFieldisnotrenderedintheinserting interfacebecauseitsInsertVisible propertyissettoFalse.TheseBoundFieldsexistsbecausetheyarethe columnsreturnedbytheGetCategories() method,whichiswhattheObjectDataSourceinvokestoretrieveits data.Forinserting,however,wedontwanttolettheuserspecifyavalueforNumberOfProducts.Moreover,we needtoallowthemtouploadapictureforthenewcategoryaswellasuploadaPDFforthebrochure. RemovetheNumberOfProducts BoundFieldfromtheDetailsViewaltogetherandthenupdatetheHeaderText propertiesoftheCategoryName andBrochurePath BoundFieldstoCategoryand Brochure, respectively. Next,converttheBrochurePath BoundFieldintoaTemplateFieldandaddanewTemplateFieldforthepicture, givingthisnewTemplateFieldaHeaderText valueof Picture. MovethePicture TemplateFieldsothatitis betweentheBrochurePath TemplateFieldandCommandField.
7 of17
Figure7:BindtheDetailsViewtotheCategoriesDataSource andEnableInserting
8 of17
AddingFileUploadControlsfortheBrochureandPictureFields
Presently,theBrochurePath TemplateFieldsInsertItemTemplate containsaTextBox,whilethePicture TemplateFielddoesnotcontainanytemplates.WeneedtoupdatethesetwoTemplateFields InsertItemTemplatestouseFileUploadcontrols. FromtheDetailsViewssmarttag,choosetheEditTemplates optionandthenselecttheBrochurePath TemplateFieldsInsertItemTemplate fromthedropdownlist.RemovetheTextBoxandthendragaFileUpload controlfromtheToolboxintothetemplate.SettheFileUploadcontrolsID toBrochureUpload.Similarly,adda FileUploadcontroltothePicture TemplateFieldsInsertItemTemplate.SetthisFileUploadcontrolsID to PictureUpload.
Figure8:AddaFileUploadControltotheInsertItemTemplate
Aftermakingtheseadditions,thetwoTemplateFieldsdeclarativesyntaxwillbe:
<asp:TemplateFieldHeaderText="Brochure"SortExpression="BrochurePath"> <InsertItemTemplate> <asp:FileUploadID="BrochureUpload"runat="server"/> </InsertItemTemplate> </asp:TemplateField> <asp:TemplateFieldHeaderText="Picture"> <InsertItemTemplate> <asp:FileUploadID="PictureUpload"runat="server"/> </InsertItemTemplate> </asp:TemplateField>
Whenauseraddsanewcategory,wewanttoensurethatthebrochureandpictureareofthecorrectfiletype.For
9 of17
thebrochure,theusermustsupplyaPDF.Forthepicture,weneedtheusertouploadanimagefile,butdowe allow any imagefileoronlyimagefilesofaparticulartype,suchasGIFsorJPGs?Inordertoallowfordifferent filetypes,wedneedtoextendtheCategories schematoincludeacolumnthatcapturesthefiletypesothatthis typecanbesenttotheclientthroughResponse.ContentType inDisplayCategoryPicture.aspx.Sincewedont havesuchacolumn,itwouldbeprudenttorestrictuserstoonlyprovidingaspecificimagefiletype.The Categories tablesexistingimagesarebitmaps,butJPGsareamoreappropriatefileformatforimagesserved overtheweb. Ifauseruploadsanincorrectfiletype,weneedtocanceltheinsertanddisplayamessageindicatingtheproblem. AddaLabelWebcontrolbeneaththeDetailsView.SetitsID propertytoUploadWarning,clearoutits Text property,settheCssClass propertytoWarning, andtheVisible andEnableViewState propertiestoFalse. TheWarning CSSclassisdefinedinStyles.css andrendersthetextinalarge,red,italicized,boldfont. Note:Ideally,theCategoryName andDescription BoundFieldswouldbeconvertedtoTemplateFieldsand theirinsertinginterfacescustomized.TheDescription insertinginterface,forexample,wouldlikelybe bettersuitedthroughamultilinetextbox.AndsincetheCategoryName columndoesnotacceptNULL values, aRequiredFieldValidatorshouldbeaddedtoensuretheuserprovidesavalueforthenewcategorysname. Thesestepsareleftasanexercisetothereader.ReferbacktoCustomizingtheDataModificationInterface foranindepthlookataugmentingthedatamodificationinterfaces.
Step6:SavingtheUploadedBrochuretotheWebServersFileSystem
WhentheuserentersthevaluesforanewcategoryandclickstheInsertbutton,apostbackoccursandtheinserting workflowunfolds.First,theDetailsViewsItemInserting eventfires.Next,theObjectDataSourcesInsert() methodisinvoked,whichresultsinanewrecordbeingaddedtotheCategories table.Afterthat,the DetailsViewsItemInserted eventfires. BeforetheObjectDataSourcesInsert() methodisinvoked,wemustfirstensurethattheappropriatefiletypes wereuploadedbytheuserandthensavethebrochurePDFtothewebserversfilesystem.Createaneventhandler fortheDetailsViewsItemInserting eventandaddthefollowingcode:
'ReferencetheFileUploadcontrols DimBrochureUploadAsFileUpload=_ CType(NewCategory.FindControl("BrochureUpload"),FileUpload) IfBrochureUpload.HasFileThen 'MakesurethataPDFhasbeenuploaded IfString.Compare(System.IO.Path.GetExtension_ (BrochureUpload.FileName),".pdf",True)<>0Then UploadWarning.Text=_ "OnlyPDFdocumentsmaybeusedforacategory'sbrochure." UploadWarning.Visible=True e.Cancel=True ExitSub EndIf EndIf
10 of17
programmaticallyexaminedinordertomoreconclusivelyverifythefiletype.Suchthoroughapproaches, though,areoftenoverkillcheckingtheextensionissufficientformostscenarios. AsdiscussedintheUploadingFilestutorial,caremustbetakenwhensavingfilestothefilesystemsothatone usersuploaddoesnotoverwriteanothers.Forthistutorialwewillattempttousethesamenameastheuploaded file.Iftherealreadyexistsafileinthe~/Brochures directorywiththatsamefilename,however,wellappenda numberattheenduntilauniquenameisfound.Forexample,iftheuseruploadsabrochurefilenamedMeats.pdf, butthereisalreadyafilenamedMeats.pdf inthe~/Brochures folder,wellchangethesavedfilenameto Meats1.pdf.Ifthatexists,welltryMeats2.pdf,andsoon,untilauniquefilenameisfound. ThefollowingcodeusestheFile.Exists(path) methodtodetermineifafilealreadyexistswiththespecified filename.Ifso,itcontinuestotrynewfilenamesforthebrochureuntilnoconflictisfound.
ConstBrochureDirectoryAsString="~/Brochures/" DimbrochurePathAsString=BrochureDirectory&BrochureUpload.FileName DimfileNameWithoutExtensionAsString=_ System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName) DimiterationAsInteger=1 WhileSystem.IO.File.Exists(Server.MapPath(brochurePath)) brochurePath=String.Concat(BrochureDirectory,_ fileNameWithoutExtension,"",iteration,".pdf") iteration+=1 EndWhile
Step7:SavingtheUploadedPicturetotheDatabase
TostoretheuploadedpictureinthenewCategories record,weneedtoassigntheuploadedbinarycontenttothe ObjectDataSourcespicture parameterintheDetailsViewsItemInserting event.Beforewemakethis assignment,however,weneedtofirstmakesurethattheuploadedpictureisaJPGandnotsomeotherimagetype. AsinStep6,letsusetheuploadedpicturesfileextensiontoascertainitstype. WhiletheCategories tableallowsNULL valuesforthePicture column,allcategoriescurrentlyhaveapicture. Letsforcetheusertoprovideapicturewhenaddinganewcategorythroughthispage.Thefollowingcodechecks toensurethatapicturehasbeenuploadedandthatithasanappropriateextension.
'ReferencetheFileUploadcontrols DimPictureUploadAsFileUpload=_ CType(NewCategory.FindControl("PictureUpload"),FileUpload) IfPictureUpload.HasFileThen 'MakesurethataJPGhasbeenuploaded IfString.Compare(System.IO.Path.GetExtension(PictureUpload.FileName),_ ".jpg",True)<>0AndAlso_ String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName),_
11 of17
".jpeg",True)<>0Then UploadWarning.Text=_ "OnlyJPGdocumentsmaybeusedforacategory'spicture." UploadWarning.Visible=True e.Cancel=True ExitSub EndIf Else 'Nopictureuploaded! UploadWarning.Text=_ "Youmustprovideapictureforthenewcategory." UploadWarning.Visible=True e.Cancel=True ExitSub EndIf
TheCompleteItemInserting EventHandler
Forcompleteness,hereistheItemInserting eventhandlerinitsentirety:
ProtectedSubNewCategory_ItemInserting_ (senderAsObject,eAsDetailsViewInsertEventArgs)_ HandlesNewCategory.ItemInserting 'ReferencetheFileUploadcontrols DimPictureUploadAsFileUpload=_ CType(NewCategory.FindControl("PictureUpload"),FileUpload) IfPictureUpload.HasFileThen 'MakesurethataJPGhasbeenuploaded IfString.Compare(System.IO.Path.GetExtension(PictureUpload.FileName),_ ".jpg",True)<>0AndAlso_ String.Compare(System.IO.Path.GetExtension(PictureUpload.FileName),_ ".jpeg",True)<>0Then UploadWarning.Text=_ "OnlyJPGdocumentsmaybeusedforacategory'spicture." UploadWarning.Visible=True e.Cancel=True ExitSub EndIf Else 'Nopictureuploaded! UploadWarning.Text=_ "Youmustprovideapictureforthenewcategory." UploadWarning.Visible=True
12 of17
'ReferencetheFileUploadcontrols DimBrochureUploadAsFileUpload=_ CType(NewCategory.FindControl("BrochureUpload"),FileUpload) IfBrochureUpload.HasFileThen 'MakesurethataPDFhasbeenuploaded IfString.Compare(System.IO.Path.GetExtension(BrochureUpload.FileName),_ ".pdf",True)<>0Then UploadWarning.Text=_ "OnlyPDFdocumentsmaybeusedforacategory'sbrochure." UploadWarning.Visible=True e.Cancel=True ExitSub EndIf ConstBrochureDirectoryAsString="~/Brochures/" DimbrochurePathAsString=BrochureDirectory&BrochureUpload.FileName DimfileNameWithoutExtensionAsString=_ System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName) DimiterationAsInteger=1 WhileSystem.IO.File.Exists(Server.MapPath(brochurePath)) brochurePath=String.Concat(BrochureDirectory,_ fileNameWithoutExtension,"",iteration,".pdf") iteration+=1 EndWhile 'SavethefiletodiskandsetthevalueofthebrochurePathparameter BrochureUpload.SaveAs(Server.MapPath(brochurePath)) e.Values("brochurePath")=brochurePath EndIf EndSub
Step8:FixingtheDisplayCategoryPicture.aspx Page
LetstakeamomenttotestouttheinsertinginterfaceandItemInserting eventhandlerthatwascreatedoverthe lastfewsteps.VisittheUploadInDetailsView.aspx pagethroughabrowserandattempttoaddacategory,but omitthepicture,orspecifyanonJPGpictureoranonPDFbrochure.Inanyofthesecases,anerrormessagewill bedisplayedandtheinsertworkflowcancelled.
13 of17
Figure9:AWarningMessageisDisplayedIfanInvalidFileTypeisUploaded
Figure10:TheNewCategorysPictureisnotDisplayed
specifiedcategoryspictureisconfiguredtoprocessbitmapsthathaveanOLEheader.This78byteheaderis strippedfromthePicture columnsbinarycontentsbeforetheyaresentbacktotheclient.ButtheJPGfilewejust uploadedforthenewcategorydoesnothavethisOLEheadertherefore,valid,necessarybytesarebeingremoved fromtheimagesbinarydata. SincetherearenowbothbitmapswithOLEheadersandJPGsintheCategories table,weneedtoupdate DisplayCategoryPicture.aspx sothatitdoestheOLEheaderstrippingfortheoriginaleightcategoriesand bypassesthisstrippingforthenewercategoryrecords.Inournexttutorialwellexaminehowtoupdateanexisting recordsimage,andwellupdatealloftheoldcategorypicturessothattheyareJPGs.Fornow,though,usethe followingcodeinDisplayCategoryPicture.aspx tostriptheOLEheadersonlyforthoseoriginaleight categories:
ProtectedSubPage_Load(senderAsObject,eAsEventArgs)HandlesMe.Load DimcategoryIDAsInteger=Convert.ToInt32(Request.QueryString("CategoryID")) 'Getinformationaboutthespecifiedcategory DimcategoryAPIAsNewCategoriesBLL() DimcategoriesAsNorthwind.CategoriesDataTable=_ categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID) DimcategoryAsNorthwind.CategoriesRow=categories(0) IfcategoryID<=8Then 'OutputHTTPheadersprovidinginformationaboutthebinarydata Response.ContentType="image/bmp" 'Outputthebinarydata 'ButfirstweneedtostripouttheOLEheader ConstOleHeaderLengthAsInteger=78 DimstrippedImageLengthAsInteger=_ category.Picture.LengthOleHeaderLength DimstrippedImageData(strippedImageLength)AsByte Array.Copy(category.Picture,OleHeaderLength,_ strippedImageData,0,strippedImageLength) Response.BinaryWrite(strippedImageData) Else 'Fornewcategories,imagesareJPGs... 'OutputHTTPheadersprovidinginformationaboutthebinarydata Response.ContentType="image/jpeg" 'Outputthebinarydata Response.BinaryWrite(category.Picture) EndIf EndSub
Withthischange,theJPGimageisnowrenderedcorrectlyintheGridView.
15 of17
Figure11:TheJPGImagesforNewCategoriesareCorrectlyRendered
Step9:DeletingtheBrochureintheFaceofanException
Oneofthechallengesofstoringbinarydataonthewebserversfilesystemisthatitintroducesadisconnect betweenthedatamodelanditsbinarydata.Therefore,wheneverarecordisdeleted,thecorrespondingbinarydata onthefilesystemmustalsoberemoved.Thiscancomeintoplaywheninserting,aswell.Considerthefollowing scenario:auseraddsanewcategory,specifyingavalidpictureandbrochure.UponclickingtheInsertbutton,a postbackoccursandtheDetailsViewsItemInserting eventfires,savingthebrochuretothewebserversfile system.Next,theObjectDataSourcesInsert() methodisinvoked,whichcallstheCategoriesBLL classs InsertWithPicture method,whichcallstheCategoriesTableAdaptersInsertWithPicture method. Now,whathappensifthedatabaseisoffline,orifthereisanerrorintheINSERT SQLstatement?Clearlythe INSERTwillfail,sononewcategoryrowwillbeaddedtothedatabase.Butwestillhavetheuploadedbrochure filesittingonthewebserversfilesystem!Thisfileneedstobedeletedinthefaceofanexceptionduringthe insertingworkflow. AsdiscussedpreviouslyintheHandlingBLL andDALLevelExceptionsinanASP.NETPage tutorial,whenan exceptionisthrownfromwithinthedepthsofthearchitectureitisbubbledupthroughthevariouslayers.Atthe PresentationLayer,wecandetermineifanexceptionhasoccurredfromtheDetailsViewsItemInserted event. ThiseventhandleralsoprovidesthevaluesoftheObjectDataSourcesInsertParameters.Therefore,wecan createaneventhandlerfortheItemInserted eventthatchecksiftherewasanexceptionand,ifso,deletesthefile specifiedbytheObjectDataSourcesbrochurePath parameter:
ProtectedSubNewCategory_ItemInserted_ (senderAsObject,eAsDetailsViewInsertedEventArgs)_ HandlesNewCategory.ItemInserted Ife.ExceptionIsNotNothingThen 'Needtodeletebrochurefile,ifitexists Ife.Values("brochurePath")IsNotNothingThen System.IO.File.Delete(Server.MapPath_
16 of17
Summary
Thereareanumberofstepsthatmustbeperformedinordertoprovideawebbasedinterfaceforaddingrecords thatincludebinarydata.Ifthebinarydataisbeingstoreddirectlyintothedatabase,chancesareyoullneedto updatethearchitecture,addingspecificmethodstohandlethecasewherebinarydataisbeinginserted.Oncethe architecturehasbeenupdated,thenextstepiscreatingtheinsertinginterface,whichcanbeaccomplishedusinga DetailsViewthathasbeencustomizedtoincludeaFileUploadcontrolforeachbinarydatafield.Theuploadeddata canthenbesavedtothewebserversfilesystemorassignedtoadatasourceparameterintheDetailsViews ItemInserting eventhandler. Savingbinarydatatothefilesystemrequiresmoreplanningthansavingdatadirectlyintothedatabase.Anaming schememustbechoseninordertoavoidoneusersuploadoverwritinganothers.Also,extrastepsmustbetaken todeletetheuploadedfileifthedatabaseinsertfails. Wenowhavetheabilitytoaddnewcategoriestothesystemwithabrochureandpicture,butweveyettolookat howtoupdateanexistingcategorysbinarydataorhowtocorrectlyremovethebinarydataforadeletedcategory. Wellexplorethesetwotopicsinthenexttutorial. HappyProgramming!
AbouttheAuthor
ScottMitchell,authorofsevenASP/ASP.NETbooksandfounderof4GuysFromRolla.com,hasbeenworkingwith MicrosoftWebtechnologiessince1998.Scottworksasanindependentconsultant,trainer,andwriter.Hislatest bookisSamsTeachYourselfASP.NET2.0in24Hours.Hecanbereachedatmitchell@4GuysFromRolla.com. or viahisblog,whichcanbefoundat http://ScottOnWriting.NET.
SpecialThanksTo
Thistutorialserieswasreviewedbymanyhelpfulreviewers.LeadreviewersforthistutorialwereDaveGardner, TeresaMurphy,andBernadetteLeigh.InterestedinreviewingmyupcomingMSDNarticles?Ifso,dropmealine at mitchell@4GuysFromRolla.com.
17 of17