Jurnal de programator
99,9% Microsoft
Send mail to the author(s)
Home | Mini tools List| Blog carti| ASP.NET MVC ebook| tutorial 3.5| Subscribe by Email | twitter| linkedin | youtube | interviu
Sunday, February 28, 2010


Salvarea Setarilor pentru Windows Forms

Pe scurt :

Metoda 1. Setari in Visual Studio

Vedeti

Application Settings Architecture , http://msdn.microsoft.com/en-us/library/8eyb2ct1.aspx

· Application Settings Overview , http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx

Video tutorial : http://www.youtube.com/watch?v=-JDoZU0HBBo&feature=PlayList&p=70009BDDADB00AEF&index=1

Metoda 2. In app.config  - metoda rapida

Video Tutorial : http://www.youtube.com/watch?v=Axkt_KE0JX4&feature=PlayList&p=70009BDDADB00AEF&index=2

Metoda 3.  In app.config – metoda sigura  :

Video Tutorial : http://www.youtube.com/watch?v=oglDeV7sc94&feature=PlayList&p=70009BDDADB00AEF&index=3

Metoda 4. Fisiere XML

Video Tutorial : http://www.youtube.com/watch?v=MtK3zZYjfS0&feature=PlayList&p=70009BDDADB00AEF&index=0

Metoda 5. Fisiere INI

http://jachman.wordpress.com/2006/09/11/how-to-access-ini-files-in-c-net/
http://www.codeproject.com/KB/cross-platform/INIFile.aspx

 

Metoda 6. Baza de date

Creati o tabela cu 3 coloane :Obiect, Nume, Valoare. Accesati prin EF, L2S sau Nhibernate sau orice altceva.

Metoda 7.Registry

Video Tutorial : http://www.youtube.com/watch?v=UeBPTbWgthM&feature=PlayList&p=70009BDDADB00AEF&index=4

 

Mai multe detalii aici

full | tutoriale
Sunday, February 28, 2010 11:24:15 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Monday, February 08, 2010


Salvarea setarilor in .NET

Discutie :

setari globale (write once, read more). De obicei stocate in

Path.GetDirectoryName( Assembly.GetEntryAssembly().GetName().CodeBase))

setari de user (write –read). De obicei stocate in

Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

Posibilitatea 1 : salvarea in settings

User settings ,application settings

Posibilitatea 2 : salvarea in registry

HKCU, HKLM

Posibilitatea 3 : salvarea in fisiere de configurare

· Connectionstrings

· appSettings

· config class

Posibilitatea 4 : clase serializabile ( de ex, in XML)

Se pune problema unde se serializeaza : hard, baza de date.

Posibilitatea 5 : fisiere Ini

http://jachman.wordpress.com/2006/09/11/how-to-access-ini-files-in-c-net/

http://www.codeproject.com/KB/cross-platform/INIFile.aspx

Posibilitatea 6, Baza de date

Puteti crea o tabela cu 3 coloane : Obiect,Nume,Valoare. Acestati cu EF, L2S , NHibernate sau orice altceva.

Concluzie :

Salvarea setarilor nu e un lucru greu de facut. Problema este unde se salveaza si de catre cine poate fi accesata informatia (administrator sau utilizator obisnuit).

Downloadati codul

Tutoriale video aici

.NET | c# | tutoriale
Monday, February 08, 2010 10:15:52 PM (GMT Standard Time, UTC+00:00)  #    Comments [2]  |  Trackback


Monday, January 25, 2010


Ajutor la dezvoltarea unei aplicatii

Aplicatia este www.scurt.ro si o gasiti la adresa www.scurt.ro. Este o aplicatie de shortening service ( tinyurl si bit.ly fiind unele cunoscute deja).

Documentatia aplicatiei o gasiti la adresa http://www.scurt.ro/Home/About .

Mai intii , ce vreau sa fac cu aceasta aplicatie: Vreau sa arat ca programarea este doar baza piramidei. Si ca munca pentru o aplicatie simpla este destul de mare, in plus mai trebuie tot felul de persoane  - testare,raportare, administrator de BD, SEO specialist, marketing, vinzari si altii…

Aplicatia mai are citeva chestii de facut ( de ex., paginile pentru utilizatorii inregistrati, logare,erori , add-on de IE si Firefox, SEO, etc- le gasiti in documentul http://www.scurt.ro/Docs/aplicatia%20scurt.docx )

Pentru cei care ma ajuta nu pot sa le promit nimic – decit ca vor fi mentionati printre autori –si vor avea link pus pe o pagina care trebuie definita.

Cine vrea sa ma ajute, va rog sa cititi documentul, downloadati sursele – si vorbim pe email!

Multumesc,

Andrei

.NET | ASP.NET | Asp.NET MVC | c# | tutoriale
Monday, January 25, 2010 3:50:00 AM (GMT Standard Time, UTC+00:00)  #    Comments [1]  |  Trackback


Monday, January 19, 2009


Creearea Bazei de date – si suport filestream in Sql Server 2008

Deocamdata o sa facem doar tabelele pentru detaliile/resursele care tin de un Angajat . Hai sa enumeram citeva :

  1. Un Angajat are nume( se poate schimba – prin casatorie, de ex.), prenume , poza – sa le numim proprietati UserRelated
  2. Un Angajat poate avea telefon , laptop – sa le numim proprietati JobRelated
  3. Un Angajat poate avea cont de Active Directory, email , Citrix , acces VPN - sa le numim ITRelated

(Daca aveti si alte sugestii,va rog sa imi scrieti)

Evident ca am putea creea o tabela prin care sa avem , ca si coloane, toate aceste proprietati - dar aplicatia nu ar fi destul de flexibila, in cazul in care cineva ar vrea sa mai adauge un detaliu/resursa ar trebui sa refacem aplicatia. Asa incit totul se rezolva cu un nivel de indirectare – o sa creez o tabela care sa contina gruparile de Proprietati (UserRelated, JobRelated , ITRelated) –, una care sa contina Proprietatile( nume, prenume, poza, telefon, laptop, email, etc) si una care sa faca legatura intre ele. De asemenea , trebuie ca tabelele sa contina date despre cine a introdus informatia si pina cind e valabila – acestea vor fi 3 cimpuri, continute tot timpul in (aproape) fiecare tabela , de tipul :

[DateModified<NumeTabela>] [datetime] NULL, --data modificarii

[NameUserModified<NumeTabela>] [nvarchar](150) NULL, - nume utilizator care a modificat

[IPModified<NumeTabela>] [nvarchar](150) NULL, -- ip-ul de la care s-a produs modificarea

Deocamdata am ajuns la urmatoarea structura :

clip_image002

Pentru conformitate , iata scriptul de creere al tabelelor si scriptul de creere a resurselor/detaliilor Angajatului.

http://serviciipeweb.ro/iafblog/content/binary/net35/bd/1/db.zip

Ce vreau sa fac in continuare este sa fac coloana ValueBinaryUserGroupProperty de tipul FileStream – adica sa isi pastreze datele pe hard, de fapt.

Verificam ca serverul suporta filestream – click dreapta pe server, “properties”, selectati “Advanced” si verificati ca filestream este OK:

clip_image004

Apoi click dreapta pe baza de date, “properties”, selectati FileGroups si acolo adaugati un filestream(bifati si “default”)

clip_image006

Acum trebuie sa adaugam un file ca sa putem profita de acest filestream . Trebuie ales File_Type : “filestream data”, filegroup-ul si, cel mai important, folder-ul in care sa il punem (ca alegere usoara, este acelasi folder ca fisierul primar de date)

clip_image008

Acum putem sa construim tabela noastra cu filestream – stergem tabela accUserGroupProperty (drop table accUserGroupProperty ) si o creeam cu suport de FileStream :

CREATE TABLE [dbo].[accUserGroupProperty](

[IDUserGroupProperty] [uniqueidentifier] NOT NULL ROWGUIDCOL PRIMARY KEY,

ToDateUserGroupProperty datetime NULL,

[ValueTextUserGroupProperty] [nvarchar](max) NULL,

[ValueBinaryUserGroupProperty] [varbinary](max) FileStream NULL,

[IDUser] [bigint] NOT NULL,

[IDProperty] [bigint] NOT NULL,

[DateModifiedUserGroupProperty] [datetime] NULL,

[NameUserModifiedUserGroupProperty] [nvarchar](150) NULL,

[IPModifiedUserGroupProperty] [nvarchar](150) NULL,

)

Ce ne trebuie neaparat pentru o coloana de tipul FileStream :

  1. Suport Server, BD ( facut deja)
  2. O coloana in tabela respectiva de tipul NOT NULL ROWGUIDCOL PRIMARY KEY

Cu ce ne afecteaza : cu aproape nimic – dar e bine sa poti vedea fisierele pe hard * de ex., poza angajatului o sa fie direct pe hard in loc sa o stocam in BD.

Nu uitati ca tot ce am facut aici prin click-uri se poate face si prin script, cu ajutorul butonului “Script” – se poate gasi usor in toate pozele precedente

Tema pentru acasa : Creeati o baza de date cu support filestream, o tabela cu o coloana filestream si inserati un text. Observati modificarile de pe folder-ul unde ati spus sa se creeze FileStream.

Lecturi Recomandate:

FileStream cu SQL Server (pe scurt)

http://blogs.microsoft.co.il/blogs/bursteg/archive/2008/05/09/sql-server-2008-filestream-part-1.aspx

Database normalization

http://en.wikipedia.org/wiki/Database_normalization

Developing Time Oriented databases in SQL

http://www.cs.arizona.edu/people/rts/tdbbook.pdf

.NET | programare | tutorial .NET3.5 | tutoriale
Monday, January 19, 2009 10:06:02 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Tuesday, March 04, 2008


Al patrulea pas : Importul datelor

 

Va sfatuim sa cititi partile anterioare

     Primul pas : instalarea software-ului free

    Al doilea pas : Analiza aplicatiei

    Al treilea pas : Structura Bazei de date

 

Sau tutorialul anterior despre .NET 2.0

        http://serviciipeweb.ro/iafblog/content/binary/tutorial.pdf

 

Vom importa datele din fisierul Excel in Baza de date. Daca am avea SQL Server Standard( sau mai mare) am putea importa direct din Excel in SQL Server.Este suficient sa facem click dreapta pe baza noastra de date , Tasks=> ImportData – ca in figura alaturata :

Dupa ce apasam, vom selecta la surse Excel:

Iar la destinatie serverul local de SQL Server

 

Cam asta ar fi, daca am avea SQL Server Standard.

Dar ,pentru ca avem SQL Server Express, nu avem o astfel de facilitate incorporata - asa ca va trebui sa ne descurcam importand datele cu un program in C#.

Vom creea tabele in SQL Server asemanatoare cu structura datelor din Excel. Vom crea tabelele asa cu am facut la pasul 3. De pilda tabela cu date despre cartile de copii va arata asa:

Acum vom importa datele. Va trebui sa facem citirea datelor in Excel si apoi scrierea lor in SQL Server.

Sa le luam pe rind:

Cream un nou proiect in C# , intitulat "ImportDate" de tip Consola in folder-ul C:\book3.

Linga toate "using" mai adaugam si un "using System.Data.OleDb;" ca sa putem citi din Excel si using System.Data.SqlClient pentru conectare la SQL Server.

O sa ne folosim de faptul ca DataAdapter stie sa faca modificari de date automat. Ne facem ca citim un DataTable din SQL Server, il umplem apoi cu datele de la Excel si ii spunem lui DataAdapter sa faca insert-urile pentru noi.

 

Deschidem o conexiune la SQL Server si citim datele din tabela "Excel_Copii":

 

Pentru citirea din Excel vom folosi driverul de OLEDB.Cream o conexiune la Excel si o sa citim datele din tabela "Copii".

Deschidem o conexiune la Excel

"Provider = \"Microsoft.Jet.OLEDB.4.0\";Data Source=\"C:\\book3\\carte.xls\";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";

(daca vreti sa stiti ce ISAM aveti , vedeti cu regedit cheia

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\ISAM Formats)

Deschidem o noua comanda, prin care selectam datele din Worksheetul "Copii"

oc.CommandText = "select * from [Copii$]";

 

(de remarcat sintaxa cu $ si paranteze drepte)

Cod complet:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Data.OleDb;

using System.Data.SqlClient;

using System.Data;

namespace ImportDate

{

class Program

{

static void Main(string[] args)

{

using (SqlConnection sco = new SqlConnection())

{

sco.ConnectionString = "Data Source=.\\sqlExpress;Integrated Security=true;Initial Catalog=Library";

 

sco.Open();

using (SqlDataAdapter sda = new SqlDataAdapter("select * from Excel_Copii", sco))

{

// construct insert

if (sda.InsertCommand == null)

{

SqlCommandBuilder scb = new SqlCommandBuilder(sda);

sda.InsertCommand = scb.GetInsertCommand(true);

}

System.Data.DataTable dtTransfer = new System.Data.DataTable();

sda.Fill(dtTransfer);

 

 

 

 

using (OleDbConnection odc = new OleDbConnection())

{

odc.ConnectionString = "Provider = \"Microsoft.Jet.OLEDB.4.0\";Data Source=\"C:\\book3\\carte.xls\";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";

odc.Open();

using (OleDbCommand oc = new OleDbCommand())

{

oc.CommandType = System.Data.CommandType.Text;

oc.CommandText = "select * from [Copii$]";

oc.Connection = odc;

//fill data table with Excel data

System.Data.DataTable dtExcel = new System.Data.DataTable();

using (OleDbDataReader sr = oc.ExecuteReader())

{

dtExcel.Load(sr);

}

 

// transfer rows

foreach (DataRow dr in dtExcel.Rows)

{

 

DataRow drNew = dtTransfer.NewRow();

drNew.ItemArray = dr.ItemArray;

dtTransfer.Rows.Add(drNew);

}

}

 

 

sda.Update(dtTransfer);

}

}

}

}

}

}

 

La fel se importa si datele din tabela de SF.

Acum este cazul sa importam datele in tabele.

Mai intii, cea de autori.

Va trebui sa luam autorii din toate tabelele .

 

SELECT

[Autor1] as autor

FROM [Library].[dbo].[Excel_Copii]

union

select [Autor2]

FROM [Library].[dbo].[Excel_Copii]

UNION

SELECT

[Autor1] as autor

FROM [Library].[dbo].[Excel_SF]

union

select [Autor2]

FROM [Library].[dbo].[Excel_SF]

 

Observam urmatoarele date:

NULL

ISPIRESCU Petre

Andersen

George Lucas

Ion Creanga

Isaac Asimov

Petre Ispirescu

 

 

Va trebui sa facem 2 lucruri:

  1. Consolidarea datelor – in definitiv, Petre Ispirescu = ISPIRESCU Petre
  2. Inserarea in tabela Person si Tabela Author

Punctul 1 este destul de usor de facut cu un update ...

update Excel_Copii set Autor1= 'Petre Ispirescu' where Autor1 = ' ISPIRESCU Petre'

Punctul 2 il vom face inserind in tabela de persoane si pe urma in tabela de Autori

INSERT INTO [Library].[dbo].[Person]

([FirstNamePerson],[LastNamePerson]

)

 

select autor,'' from

(

SELECT

[Autor1] as autor

FROM [Library].[dbo].[Excel_Copii]

union

select [Autor2]

FROM [Library].[dbo].[Excel_Copii]

UNION

SELECT

[Autor1] as autor

FROM [Library].[dbo].[Excel_SF]

union

select [Autor2]

FROM [Library].[dbo].[Excel_SF]

 

) a where a.autor is not null

Acum separam nume de prenume:

UPDATE

    Person

SET

    FirstNamePerson = substring(FirstNamePerson,1,charindex(' ' ,FirstNamePerson)-1),

    LastNamePerson = substring(FirstNamePerson,charindex(' ' ,FirstNamePerson)+1,100)

WHERE charindex(' ' ,FirstNamePerson)>0

Rezultatul este:

IDPerson    FirstNamePerson    LastNamePerson    DateOfBirthPerson

2    Andersen        NULL

3    George    Lucas    NULL

4    Ion    Creanga    NULL

5    Isaac    Asimov     NULL

6    Petre    Ispirescu    NULL

 

Acum le vom insera in tabela de Autori:

INSERT INTO

    [Author]

([IDPerson]

)

SELECT IDPerson FROM Person

 

La fel inseram cartile si editurile..

Acum trebuie sa refacem legaturile, de pilda, intre autori si carti

    INSERT INTO [Book_Author]

([IDBook]

,[IDAuthor])

 

select IDBOOK,IDAuthor from Book b

inner join Excel_SF excel

inner join Person p on excel.Autor1 = p.FirstNamePerson + ' ' + p.LastNamePerson

inner join Author a on p.IDPerson = a.IDPerson

on excel.Titlu = b.Title

 

La fel si pentru carti cu edituri :

update book

set IDPrintingHouse =

p.IDPrintingHouse from Book b

inner join Excel_SF excel

inner join PrintingHouse p on p.NamePrintingHouse = excel.Editura

on excel.Titlu = b.Title

Ramine la latitudinea cititorului exercitiul cu celelalte update-uri.

Backupul la BD il gasiti in folder-ul database si se numeste "lib_date_importExcel.bak" . Puteti face restore.

De citit:

  1. Primul pas : instalarea software-ului free , in care downloadati VC# Express si SQL Server Express
  2. Stringuri de conexiune pentru orice baza de date : www.connectionstrings.com

 

Surse

Tutorial PDF

        

 

.NET | programare | tutoriale
Tuesday, March 04, 2008 10:02:54 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Tuesday, February 26, 2008


Al treilea pas : Structura Bazei de date

 

Va sfatuim sa cititi partile anterioare

     Primul pas : instalarea software-ului free

    Al doilea pas : Analiza aplicatiei

 

Sau tutorialul anterior despre .NET 2.0

        http://serviciipeweb.ro/iafblog/content/binary/tutorial.pdf

 

Facind deja (minima) analiza a aplicatiei, putem acum sa vorbimdespre structura bazei de date. Vom face direct o baza de date relationala in cea de a treia forma normala. Pentru aceasta pornim SQL Server Management Studio Express,ne logam la serverul local (./ sau ./sqlexpress, depinde cum ati numit instanta) prin Windows authentication (cea mai simpla metoda) si click dreapta pe Databases => New Database

Numele pe care o sa i-l dam o sa fie "Library" si o sa concepem tabelele ca fiind replica exacta a obiectelor.

Vom crea tabelele direct din "Database Diagrams" Raspundem cu "Yes" la intrebarea despre "Diagram support"

 

Si cream o diagrama noua, numita "Library".Click dreapta, "New Table", "Person". Adaugam coloanele ca in figura, cu mentiunea ca "IDPerson" o facem "Identity" si Primary Key

 

Acum vom creea tabela Author – aceasta va contine o IDPerson – evidentiere a faptului ca orice Autor este si o persoana. La fel, IDAuthor este PK si Identity

Vom"trage" IDPerson din tabela Author peste IDPerson din tabela "Person", obtinind in acest fel legatura intre Autor si Persoana.

 

La fel si pentru celelalte tabele.

In final vom avea urmatoare structura :

Vom face un backup al Bazei de date ca in figura:

Puteti crea BD singuri sau puteti face "restore" la ea dupa acest backup , numit lib_empty.bak

Surse aici

http://serviciipeweb.ro/iafblog/content/binary/net3/20080226.zip

Acest tutorial in intregime aici

Data viitoare vom importa datele din Excel in SQL Server.

De citit:

  1. Despre cele 3 forme normale : http://en.wikipedia.org/wiki/Database_normalization
  2. Identity in SQL Server : http://www.sqlteam.com/article/understanding-identity-columns
  3. PK, FK : http://en.wikipedia.org/wiki/Foreign_key
  4. Moduri de a defini mostenirea in cadrul BD : http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/09/30/how-to-model-inheritance-in-databases.aspx

     

 

 

 

.NET | programare | tutoriale
Tuesday, February 26, 2008 9:58:18 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Wednesday, February 20, 2008


Al doilea pas : Analiza aplicatiei

 

Va sfatuim sa cititi prima parte, Primul pas : instalarea software-ului free

Sau tutorialul anterior despre .NET 2.0         http://serviciipeweb.ro/iafblog/content/binary/tutorial.pdf

 

Aplicatia pe care o sa o facem este una de gestionare(management, pe stil nou) a cartilor dintr-o biblioteca publica. Presupunem ca biblioteca deja isi tine o evident a cartilor intr-un Excel cu o multitudine de sheet-uri, cam de aceasta forma

Un sheet, numit "Copii" care contine carti pentru copii,cu urmatoarele date:

 

Titlu 

Autor1 

Autor2 

editura 

Pret 

Imprumutata de  

Data imprumutului 

Craiasa zapezii 

Andersen

 

Teora 

3 

Ignat Andrei 

15/01/2008 

GREUCEANU SI ALTE POVESTI  

ISPIRESCU Petre 

 

All 

5 

  

Capra cu trei iezi  

Ion Creanga 

 

Polirom 

2 

  

  

Ursul păcălit de vulpe  

Ion Creanga 

 

All 

5 

  

Zana muntilor  

Petre Ispirescu 

 

Teora 

2 

  

  

    

Alt sheet, numit SF, cu urmatoarele date

Titlu 

Autor1 

Autor2 

Editura 

Pret 

Imprumutata de  

Data imprumutului 

Caverne de otel  

Isaac Asimov  

Teora 

15 

Ignat Andrei

15/01/2008 

Fundatia  

Isaac Asimov  

Teora 

31 

  

Fundatia si imperiul  

Isaac Asimov  

Teora 

23 

  

Fundatia si Pamantul  

Isaac Asimov  

Teora 

21 

  

Inainte de fundatie  

Isaac Asimov  

Teora 

13 

  

RAZBOIUL STELELOR 

George Lucas 

Polirom 

54 

  

 

 

Pare destul de clar , nu ? Fiecare carte are cite o fisa in carte, care spuen cine a imprumutat-o si cind.

Puteti downloada fisierul Excel de la adresa http://serviciipeweb.ro/iafblog/content/binary/carte.xls

Daca nu aveti Excel (?) , puteti downloada Excel Viewer

Acum vom face o mica analiza a datelor existente , pentru ca cerintele aplicatiei, ca de obicei, sunt vagi : "sa faca o cautare intre datele existente si sa reproduca procesul existent..."

E clar ca avem de a face cu urmatoarele obiecte:

Editura – ca atribute: nume, site, email

Persoana – nume, prenume, data nasterii

Autor – este o Persoana care in plus are ca atribut – site,(una sau mai multe) Carti publicate

Bibliotecare – este o Persoana cu drepturi de modificare Carti/Edituri/Autori/Setari

Client – Este o Persoana care are dreptul sa imprumute un numar(Setare) de Carti pe o perioada data (Setare)

Carti – ca atribute : Nume, data aparitiei, (publicata de ) Editura, (unul sau mai multi) Autori, ISBN, pret

Setari – Numar de carti imprumutate, Perioada imprumutului

 

Nu voi lua in considerare multe alte lucruri, ca de pilda faptul ca un client pierde o carte sau ca preturile pot fi modifiacte in timp ...Ar complica in mod inutil aplicatia – care nu vrea sa fie o aplicatie completa, ci doar un demo.

Data viitoare o sa facem designul Bazei de date.

Surse

 

De citit:

  1. Despre Object oriented http://en.wikipedia.org/wiki/Object_oriented

     

     

 

.NET | programare | tutoriale
Wednesday, February 20, 2008 4:52:53 AM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Tuesday, February 05, 2008


Programare in .NET 3.5

Incep din nou seria de tutorial despre programare in .NET – de data aceasta .Net 3.5

Primul pas : instalarea software-ului free

Acest pas se efectuează o singura date pe PC. Este vorba despre instalarea server-ului de Web , precum si a Visual Studio Express ca si unealta de dezvoltare. Este cel mai lung pas, dar, precum am spus, se efectuează o singura data.

 

Să începem: ai Windows (XP, de preferinţă) si ne asiguram ca ai server-ul de Web (Internet Information Services – IIS de acum înainte) pe maşină .Pentru aceasta te duci in "Control panel" => "Administrative Tools" si verificaţi ca există.

 

    Daca nu exista, mergeţi înapoi la "Control Panel", apăsaţi pe "Add or Remove programs" si apăsaţi pe "Add/Remove Windows Components". Bifaţi IIS ca in imagine si daţi "Next"( asiguraţi-vă ca aveţi CD-ul de instalare Windows prin apropiere)

 

 

Bun – acum o sa instalam VS 2008 Express. Acesta este free si îl puteţi descărca de la adresa

http://www.microsoft.com/express/download/offline.aspx. Acolo gasiţi o imagine ISO pe care o puteti downloada . O puteţi vedea cu ISObuster, Daemon Tools or Virtual CloneDrive ( căutaţi-le pe google pentru linkuri de download) sau cu un program făcut de MS, Virtual CD-ROM Control Panel for Windows XP care poate fi downloadat de la adresa:

http://download.microsoft.com/download/7/b/6/7b6abd84-7841-4978-96f5-bd58df02efa2/winxpvirtualcdcontrolpanel_21.exe

( da, ştiu, e o adresa scurta)

De asemenea, instalati SQL Server Express Edition with Advanced Services SP2 de la adresa http://www.microsoft.com/express/sql/download/default.aspx

Si tool-ul de administrare grafica, numit Microsoft SQL Server 2005 Express Edition Toolkit, de la aceeasi adresa http://www.microsoft.com/express/sql/download/default.aspx

Download pdf de aici:

http://serviciipeweb.ro/iafblog/content/binary/tutorialnet3.pdf

.NET | LINQ | programare | tutoriale
Tuesday, February 05, 2008 11:28:49 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Saturday, April 28, 2007


Programarea in .NET - partea a 17-a Rapoarte in ASP.NET –Windows Forms

Haideti sa repetam ceea ce am facut in ASP.NET pentru WindowsForms

Deschideti Book.sln, adaugati o noua forma in proiect(frmPublisherPrint.cs) si trageti ReportViewer in forma.(Daca nu il gasiti, click dreapta in Toolbox, alegeti “choose items” , cautati ReportViewer din namespace-ul Microsoft.Reporting.WinForms si selectati-l

 

 

 

Adaugam raportul existent prin click dreapta pe BookWin

 

Va duceti in BookWeb, alegeti din casuta “Files of type” ultima selectie “All files” si selectati rptPublisher.rdlc.

Acum click pe el si in fereastra de proprietati alegeti la “Copy to output directory “ “Copy always”

 

 

 

 

Bun – acum au ramas 3 lucruri de facut : vizualizarea formei ca actiune, legarea controlului de raportul existent si codul de incarcare a datelor in raport.

 

Pentru vizualizarea formei ca actiune adaugati un buton btnPrint in frmPublisherList iar pe eveniment scrieti urmatorul cod:

private void btnPrint_Click(object sender, EventArgs e)

{

frmPublisherPrint p = new frmPublisherPrint();

p.ShowDialog(this);

}

 

Pentru legarea controlului vom seta la proprietati calea catre raport(presupunem ca se va afla in acelasi folder) si processing mode la local

 

Ultimul lucru de facut – incarcarea colectiei pe evenimentul de load :

rivate void frmPublisherPrint_Load(object sender, EventArgs e)

{

BookObjects.ColPublisher publishers = new BookObjects.ColPublisher();

publishers.Load();

MessageBox.Show(""+publishers.Count);

ReportDataSource rds = new ReportDataSource("DataSet1_Publisher", publishers);

rptPublisher.ProcessingMode = ProcessingMode.Local;

rptPublisher.LocalReport.DataSources.Clear();

rptPublisher.LocalReport.DataSources.Add(rds);

rptPublisher.LocalReport.Refresh();

rptPublisher.RefreshReport();

}

( exact acelasi cod ca la Web, in afara liniei :

 

Ea previne cazul( des intilnit) in care editorul IDE adauga , cu de la sine putere, un ReportDataSource .

Ceea ce se va infatisa va fi:

 

 

 

 

 

Ce mai e de facut

1)frmPublisherPrint sa nu mai afiseze ce vrea ea - ci sa primeasca un argument(in constructor, de exemplu) care sa spun ce lista de publisher-i are de afisat

2) Avind in vedere ca rapoartele sunt aceleasi pentru Windows si Web , ar fi interesant de facut un dll care sa intoarca raport – ul cerut

 

.NET | programare | tutoriale
Saturday, April 28, 2007 11:12:44 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  |  Trackback


Sunday, April 22, 2007


PROGRAMAREA IN .NET - PARTEA A 16-A RAPOARTE IN ASP.NET

Orice aplicatie trebuie sa aiba posibilitatea de a tipari datele. Pentru aceasta in VS2005 Express se poate folosi componenta Report Viewer care e free si se poate downloada de la http://www.gotreportviewer.com.

Dupa ce o instalati, o sa aveti in toolbox urmatoarea componenta:

 

 

Acum adaugam un raport care sa fie afisat de catre aplicatie – deschidem aplicatia Web si adaugam un nou item de tipul Report si il numim rptPublisher.rdlc :

 

 

Acum adaugam un nou datasource apasand pe Add New DataSource

 

 

In ecranul urmator apasam pe NewConnection si selectam baza noastra de date:

 

Putem salva conexiunea in Web.Config(desi o mai avem) si apasam Next. Pe urmatorul ecran lasam selectat “Use SQL Statements” si iarasi Next. Acum scriem codul pentru SQL:

 

SELECT IDPublisher, NamePublisher, SitePublisher

FROM Publisher

 

si iarasi Next pina se termina ( sau direct Finish).

 

Acum in WebSite DataSource ne-a aparut dataset-ul care contine Publisher

 

 

Ne ducem pe Toolbox si tragem pe rptPublisher.rdlc un Table

Ne intoarcem pe WebSite DataSources si tragem Name Publisher pe detaliu:

 

 

Acum sa verificam

Cream o noua pagina aspx, frmPublisherReport.aspx si scriem urmatorul cod(sau tragem controlul de ReportViewer si ii spunem care e raportul)

<%@ Page Language="C#" MasterPageFile="~/Book.master" AutoEventWireup="true" CodeFile="frmPublisherReport.aspx.cs" Inherits="frmPublisherReport" Title="Report Publisher" %>

 

<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

<rsweb:ReportViewer ID="rptPublisher" runat="server">

<LocalReport ReportPath="rptPublisher.rdlc">

</LocalReport>

</rsweb:ReportViewer>

</asp:Content>

 

In codul C# punem urmatoarele linii :

using System;

using System.Data;

using System.Configuration;

using System.Collections;

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 Microsoft.Reporting.WebForms;

 

public partial class frmPublisherReport : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

BookObjects.ColPublisher publishers = new BookObjects.ColPublisher();

publishers.Load();

ReportDataSource rds = new ReportDataSource("DataSet1_Publisher",publishers);

rptPublisher.ProcessingMode = ProcessingMode.Local;

rptPublisher.LocalReport.DataSources.Add(rds);

rptPublisher.LocalReport.Refresh();

 

}

 

}

 

Si modificam fisierul rdlc deschizindu-l cu notepad-ul si scriind urmatoarele:

<?xml version="1.0" encoding="utf-8"?>

<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">

<DataSources>

<DataSource Name="BookConnectionString">

<ConnectionProperties>

<ConnectString />

<DataProvider>SQL</DataProvider>

</ConnectionProperties>

<rd:DataSourceID>c649d533-64c3-42b6-9805-19adbfccd468</rd:DataSourceID>

</DataSource>

</DataSources>

<BottomMargin>1in</BottomMargin>

<RightMargin>1in</RightMargin>

<rd:DrawGrid>true</rd:DrawGrid>

<InteractiveWidth>8.5in</InteractiveWidth>

<rd:SnapToGrid>true</rd:SnapToGrid>

<Body>

<ReportItems>

<Table Name="table1">

<Footer>

<TableRows>

<TableRow>

<TableCells>

<TableCell>

<ReportItems>

<Textbox Name="textbox7">

<rd:DefaultName>textbox7</rd:DefaultName>

<ZIndex>1</ZIndex>

<Style>

<PaddingLeft>2pt</PaddingLeft>

<PaddingBottom>2pt</PaddingBottom>

<PaddingRight>2pt</PaddingRight>

<PaddingTop>2pt</PaddingTop>

</Style>

<CanGrow>true</CanGrow>

<Value />

</Textbox>

</ReportItems>

</TableCell>

</TableCells>

<Height>0.45833in</Height>

</TableRow>

</TableRows>

</Footer>

<Left>0.5in</Left>

<DataSetName>DataSet1_Publisher</DataSetName>

<Top>0.25in</Top>

<Width>6.5in</Width>

<Details>

<TableRows>

<TableRow>

<TableCells>

<TableCell>

<ReportItems>

<Textbox Name="txtName">

<rd:DefaultName>Name</rd:DefaultName>

<Style>

<PaddingLeft>2pt</PaddingLeft>

<PaddingBottom>2pt</PaddingBottom>

<PaddingRight>2pt</PaddingRight>

<PaddingTop>2pt</PaddingTop>

</Style>

<CanGrow>true</CanGrow>

<Value>=Fields!Name.Value</Value>

</Textbox>

</ReportItems>

</TableCell>

</TableCells>

<Height>0.45833in</Height>

</TableRow>

</TableRows>

</Details>

<Header>

<TableRows>

<TableRow>

<TableCells>

<TableCell>

<ReportItems>

<Textbox Name="textbox1">

<rd:DefaultName>textbox1</rd:DefaultName>

<ZIndex>2</ZIndex>

<Style>

<PaddingLeft>2pt</PaddingLeft>

<PaddingBottom>2pt</PaddingBottom>

<PaddingRight>2pt</PaddingRight>

<PaddingTop>2pt</PaddingTop>

</Style>

<CanGrow>true</CanGrow>

<Value>Name</Value>

</Textbox>

</ReportItems>

</TableCell>

</TableCells>

<Height>0.45833in</Height>

</TableRow>

</TableRows>

</Header>

<TableColumns>

<TableColumn>

<Width>6.5in</Width>

</TableColumn>

</TableColumns>

<Height>1.375in</Height>

</Table>

</ReportItems>

<Height>2in</Height>

</Body>

<rd:ReportID>9f0247a8-15fe-4ef9-962e-c4c670524163</rd:ReportID>

<LeftMargin>1in</LeftMargin>

<DataSets>

<DataSet Name="DataSet1_Publisher">

<rd:DataSetInfo>

<rd:ObjectDataSourceType>Publisher</rd:ObjectDataSourceType>

<rd:TableName>Publisher</rd:TableName>

</rd:DataSetInfo>

<Query>

<rd:UseGenericDesigner>true</rd:UseGenericDesigner>

<CommandText />

<DataSourceName>BookConnectionString</DataSourceName>

</Query>

<Fields>

<Field Name="IDPublisher">

<rd:TypeName>System.Int32</rd:TypeName>

<DataField>IDPublisher</DataField>

</Field>

<Field Name="Name">

<rd:TypeName>System.String</rd:TypeName>

<DataField>Name</DataField>

</Field>

<Field Name="Site">

<rd:TypeName>System.String</rd:TypeName>

<DataField>Site</DataField>

</Field>

</Fields>

</DataSet>

</DataSets>

<Width>9.75in</Width>

<InteractiveHeight>11in</InteractiveHeight>

<Language>en-US</Language>

<TopMargin>1in</TopMargin>

</Report>

 

 

Acum , rulind pagina, observam ca se poate exporta raportul in Excel si PDF – mai mult decit sufficient:

 

Data viitoare vom vedea acelasi raport in WindowsForms...

 

Linkuri utile:

http://www.gotreportviewer.com/ - in partea dreapta aveti exemple de aplicatii care fac diverse – genereaza automat fisierele rdlc, scot automat fisierele Excel si multe altele

SQL Server Reporting Services – pentru utilizarea avansata a rapoartelor.

.NET | programare | tutoriale
Sunday, April 22, 2007 7:16:57 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  |  Trackback


Saturday, April 14, 2007


PROGRAMAREA IN .NET - PARTEA A 15-A OPERATII ASINCRONE IN ASP.NET SI AJAX

Modelul asincron din ASP.NET

 

 

 

Sa discutam despre operatii asincrone in ASP.NET.

Exista doua tipuri mari de operatii operatii asincrone

1. Cele care se executa doar pentru operatii lungi , care iau ceva timp de executie, si pentru care user-ul trebuie instiintat de evolutia lor.

2. Cele care trimit rapid o cerere la server si se intorc.

 

Pentru 1.,o solutie recomandata este sa puneti Async=true in codul de pagina si sa executati codul cu RegisterTaskAsync . Asta este interesant, pina cind ne dam seama ca modul de afisare al paginii este acelasi – adica este intirziata pina cind se termina toata de executat.

 

Un exemplu bun gasiti aici

http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/#S5

si aici

http://msdn.microsoft.com/msdnmag/issues/07/03/WickedCode/default.aspx

 

Totusi, as recomanda o alta abordare – pentru ca user-ul sa „vada” desfasurarea detaliata a actiunilor efectuate, as recomanda scrierea cu Response.Write intr-un div si ascunderea apoi a div-ului .

Ceva de genul acesta:

 

Pe pagina aspx, printre ultimele linii, ascunderea div-ului cu mesaje:

<script>

var mesaje = document.getElementById('mesaje');

if(mesaje != null)

mesaje.style.display = 'none';

</script>

 

In codul paginii aspx putem pune cod de genul urmator:

Response.Write("<div id='mesaje'>");

Response.Write("Begin :" + DateTime.Now.ToString("yyyy MMM dd hh:mm:ss") + "<BR>");

Response.Flush();

//executare prim task

Response.Write("Generated prim task<BR>");

Response.Flush();

//executare al doilea task

Response.Write("Generated al doilea task<BR>");

Response.Flush();

//incheiere procedura...

Response.Write("</div>");

Response.Flush();

 

 

Acest model se poate combina cu evenimente generate in cadrul task-ruilor astfel incit, daca task-urile dureaza prea mult, user-ul sa aiba totusi un feedback despre ceea ce se intimpla.

 

Sa discutam acum despre 2, executarea de operatii rapide pe server. Sa dam un exemplu simplu, si anume cautarea de publisher dupa nume. Ar fi superb daca aplicatia noastra, la apasarea primei litere a publisher-ului, ar putea sa sugereze publisher-ii care incep cu litera respectiva.

Pentru aceasta vom folosi Ajax, si vom folosi implementarea de AutoComplete de la Ajax Control Toolkit

Mai intii ,trebuie sa downloadam Ajax1.0 de aici.

 

Apoi va trebui sa modificam Web.Config astfel incit sa suporte Ajax.

Asta inseamna ca o sa luam o mare parte din Web.Config-ul unui site Ajax si o sa il mutam la noi in site.

Sa incepem :

De la o configuration o sa luam

<configSections>

<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">

<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">

<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>

<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">

<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/>

<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>

<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>

</sectionGroup>

</sectionGroup>

</sectionGroup>

</configSections>

 

De la system.web o sa luam

<pages>

<controls>

<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

</controls>

</pages>

Si

<compilation debug="false">

<assemblies>

<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

<add assembly="System.Web.Extensions.Design, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></assemblies>

</compilation>

 

Apoi Handler-e si Module:

<httpHandlers>

<remove verb="*" path="*.asmx"/>

<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

</httpHandlers>

<httpModules>

<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

</httpModules>

Apoi extensions si WebServer:

<system.web.extensions>

<scripting>

<webServices>

<!-- Uncomment this line to customize maxJsonLength and add a custom converter -->

<!--

<jsonSerialization maxJsonLength="500">

<converters>

<add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/>

</converters>

</jsonSerialization>

-->

<!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. -->

<!--

<authenticationService enabled="true" requireSSL = "true|false"/>

-->

<!-- Uncomment these lines to enable the profile service. To allow profile properties to be retrieved

and modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties and

writeAccessProperties attributes. -->

<!--

<profileService enabled="true"

readAccessProperties="propertyname1,propertyname2"

writeAccessProperties="propertyname1,propertyname2" />

-->

</webServices>

<!--

<scriptResourceHandler enableCompression="true" enableCaching="true" />

-->

</scripting>

</system.web.extensions>

<system.webServer>

<validation validateIntegratedModeConfiguration="false"/>

<modules>

<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

</modules>

<handlers>

<remove name="WebServiceHandlerFactory-Integrated"/>

<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

</handlers>

</system.webServer>

 

Acum downloadam Ajax Control Toolkit si vom referentia controalele existente, aflate in AjaxControlToolkit-NoSource\SampleWebSite\Bin . Vom adauga un nou tab in ToolBox, ii vom zice AjaxControls si vom adauga itemii apasind pe Choose Items:

 

 

Si apoi indicind prin browse calea la AjaxControlToolkit.dll pe care l-am downloadat. Apasati pe urma OK si vom avea controalele Ajax.

Trageti un AutoCompleteExtender si un textbox in frmPublisherList.aspx .

 

Vom completa

public class wsPublisher : System.Web.Services.WebService {

cu atributul

[System.Web.Script.Services.ScriptService]

si vom adauga o metoda pentru regasirea publisher-ilor care incep cu o litera data:

 

[WebMethod]

public string[] GetCompletionPublishers(string prefixText, int count)

{

if (count <= 0)

count = 10;

 

List<string> items = new List<string>(count);

BookObjects.ColPublisher publishers = new BookObjects.ColPublisher();

publishers.Load();

foreach (BookObjects.Publisher pub in publishers)

{

if (pub.Name.IndexOf(prefixText, StringComparison.CurrentCultureIgnoreCase) == 0)

items.Add(pub.Name);

 

if (items.Count == count)

break;

}

return items.ToArray();

 

}

 

 

O vom folosi in Autocomplete:

<asp:ScriptManager runat="server">

</asp:ScriptManager>

<asp:TextBox ID="txtPub" runat="server" autocomplete="off"></asp:TextBox>

<cc1:AutoCompleteExtender ID="AutoPub" runat="server"

TargetControlID="txtPub"

ServicePath="wsPublisher.asmx"

ServiceMethod="GetCompletionPublishers"

MinimumPrefixLength="1"

CompletionInterval="1000"

EnableCaching="true"

CompletionSetCount="12">

</cc1:AutoCompleteExtender>

In momentul de fata putem testa aplicatia si vedea ca se listeaza numele publisher-ilor.

 

 

Lucruri de facut:

Creat o metoda prin care sa se poata incarca doar cei care au prefix, nu toti publisher-ii cum am facut in public string[] GetCompletionPublishers(string prefixText, int count)

De pus scriptManager-ul in Master- ca sa nu fim nevoiti sa il punem in fiecare pagina.

 

De vazut celelalte controale de la Ajax Control Toolkit (live demo la adresa http://ajax.asp.net/ajaxtoolkit/Default.aspx )

 

 

 

Data viitoare vom vorbi despre scoaterea de rapoarte .

 

 

 

programare | tutoriale
Saturday, April 14, 2007 5:15:31 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  |  Trackback


Saturday, March 24, 2007


Programarea in .NET - partea a 14-a Salvare XML si Executare de operatii asincrone in Windows Forms

De ce taskuri asincrone ? In ideea ca , intr-o aplicatie Windows(si chiar ASP.NET) , operatiile lungi ar trebui sa fie executate de catre alt thread, urmind ca aplicatia sa poata sa mai afiseze ceva utilizatorulu in tot acest timp ( fie si un buton pe care scrie „apasa ca sa intrerupi operatia asta lunga ...”). De pilda, in aplicatia noastra, daca avem mai mult de 100 de Publisher-i si vrem sa ii vedem pe toti – ar trebui incarcati intr-un nou thread.

 

Ne ocupam mai intii de o aplicatie Windows Forms si pe urma de ASP.NET

Un thread nu e greu de pornit. Hai sa vedem un exemplu:

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(StartAction));

            t.Start("obiect transmis");

 

 

public void StartAction(object o)

        {

            string s = o.ToString();

            System.Threading.Thread.Sleep(5000);

            //executa actiunea

            //trimite text

            if (this.InvokeRequired)

            {

                this.Invoke((MethodInvoker)delegate()

                 {

                     this.Text = s;

                 });

                //sau

                //this.Invoke(new MethodInvoker(evenimentfaraparametri());

                //this.Invoke(new EventHandler(btnDiscounts_Click));

                //this.BeginInvoke(new EventHandler(eveniment cu parametri));

            }

            else

                this.Text = s;

        }

 

 

Totusi, exista o problema – dintr-un thread nu se pot accesa DIRECT controale din alt thread – si de aceea avem instructiunea this. Invoke .Diferenta intre this.Invoke si este this.BeginInvoke aceea ca prima instructiune asteapta rezultatul actiunii, pe cind a doua doar executa si se intoarce imediat sa execute codul ramas.

 

De aceea exista controlul numit BackgroundWorker – care asigura ca , din evenimentul propriu generat, sa accesezi orice obiect de pe forma. O sa facem acest lucru pentru salvarea in XML a colectiei de Publisher-i in format XML.

.NET are o forma usoara de a salva o colectie/clasa in format XML , salvindu-i proprietatile.

Vom utiliza modalitatea cea  mai usoara de a face acest lucru

Marcam clasa Publisher si clasa colectie ColPublisher cu atributul de   [Serializable] :

 

[Serializable]

    public class ColPublisher : System.Collections.ObjectModel.KeyedCollection<string,Publisher>

 

[Serializable]

    public class Publisher

 

Acum o sa facem serializarea obiectului Publisher:

#region Serializer

        /// <summary>

        /// instanta pentru lazy load

        /// </summary>

        private static XmlSerializer m_Serializer;

        /// <summary>

        /// serializator pentru obiectul publisher

        /// </summary>

        private static XmlSerializer Serializer

        {

            get

            {

                if (m_Serializer == null)

                    m_Serializer = new XmlSerializer(typeof(Publisher));

 

                return m_Serializer;

            }

        }

 

        /// <summary>

        /// salveaza obiectul ca XML

        /// </summary>

        [XmlIgnore]

        public string XML

        {

            get

            {

                StringBuilder sb = new StringBuilder();

                EncodingStringWriter sw = new EncodingStringWriter(sb, Encoding.Default);

                XmlTextWriter xtw = new XmlTextWriter(sw);

                Serializer.Serialize(xtw, this);

                return sb.ToString();

 

 

            }

        }

        /// <summary>

        /// recreeeaza un Publisher dintr-un string XML

        /// </summary>

        /// <param name="XML">string care contine tot </param>

        /// <returns></returns>

        public static Publisher FromXML(string XML)

        {

            StringReader sr = new StringReader(XML);

            return Serializer.Deserialize(sr) as Publisher;

        }

        #endregion

 

 

   

Copiem apoi acelasi cod( cu citeva diferente) si pentru ColPublisher

 

Citeva comentarii despre cod:

De ce am pus [XmlIgnore] peste  public string XML ? Pentru a nu serializa si aceasta proprietate, dind astfel nastere la o nedorita recursivitate

Ce e cu clasa EncodingStringWriter ? Este facuta pentru a putea schimba Encoding=ul- daca aveti de exemplu caractere speciale(diacritice) romanesti/franceze/etc.

De ce metoda FromXML este statica- iar XML este pe instanta? Asa mi se pare normal – transformarea dintr-un obiect in XML sa apartina obiectului, iar din XML in obiect nu poate sa apartina unui obiect( ah, daca as fi putut scrie this = Serializer.Deserialize(sr) as Publisher  !) - ci doar clasei.

Nu se poate face codul mai „generic”? Ba da- una din deosebiri ar fi ca FromXML ar trebui sa fie pe instanta...

 

 

Haideti acum in proiectul Windows sa serializam o colectie de Publisher-i.Pe forma frmPublisherList adaugam un buton btnSave, cu textul Save, dublu click si scriem urmatorul cod:

private void btnSave_Click(object sender, EventArgs e)

        {

            BookObjects.ColPublisher col = colPublisherBindingSource.DataSource as BookObjects.ColPublisher;

            string strSave = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);

            strSave = Path.Combine(strSave, "pub.xml");

            File.WriteAllText(strSave, col.XML);

            System.Diagnostics.Process.Start(strSave);

        }

 

 

Rulati proiectul, adaugati 2 publisher-i si apasati pe save.

Este clar ca, daca sunt multi publisher-i, procesul poate deveni prea lung si blocheaza interfata.

 

Haideti sa folosim background worker. Il adaugam din toolbox , il redenumim bgSave, dublu click. Luam codul din btnSave_Click, il adaugam la si pe urma scriem doar bgSave.RunWorkerAsync();

 

private void btnSave_Click(object sender, EventArgs e)

        {

            bgSave.RunWorkerAsync();

        }

 

        private void bgSave_DoWork(object sender, DoWorkEventArgs e)

        {

            BookObjects.ColPublisher col = colPublisherBindingSource.DataSource as BookObjects.ColPublisher;

            string strSave = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);

            strSave = Path.Combine(strSave, "pub.xml");

            File.WriteAllText(strSave, col.XML);

            System.Diagnostics.Process.Start(strSave);

 

        }

 

Data viitoare  o sa vorbim despre modelul asincron din ASP.NET.

.NET | programare | tutoriale
Saturday, March 24, 2007 1:59:38 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Saturday, March 17, 2007


Tutorial .NET - p13 - Log-area operaţiilor cu log4net

In orice aplicaţie este bine sa ţinem evidenta operaţiilor făcute de utilizator( ce a modificat sau chiar ce a văzut). In acest scop putem folosi fie mecanismul de trace din .net,  fie o soluţie proprie, fie Logging and Instrumentation Application Block(http://msdn2.microsoft.com/en-us/library/ms998162.aspx), fie log4net(http://logging.apache.org/log4net/

 

Vom utiliza in acest exemplu log4net .El suporta log-area operaţiilor in felurite moduri – in fişier, baza de date, email, telnet si multe altele.

Downloadati versiunea 1.2.10 de la adresa http://logging.apache.org/log4net/downloads.html si sa începem configurarea aplicaţiei. Copiaţi conţinutul folder-ului log4net-1.2.10\bin\net\2.0\debug in C:\Book\sharedDll si sa începem modificarea proiectului Windows pentru a înregistra ce a făcut utilizatorul

 

Deschidem Book.sln si deschidem App.Config. Acolo scriem următoarele imediat sub configuration:

  <configSections>

    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

  </configSections>

  <log4net>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">

      <File value="Log4Net.log"/>

      <AppendToFile value="true"/>

      <rollingStyle value="Composite"/>

      <maximumFileSize value="1MB"/>

      <maxSizeRollBackups value="10"/>

      <datePattern value="yyyyMMdd"/>

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>

      </layout>

    </appender>

    <root>

      <level value="Debug"/>

      <appender-ref ref="RollingLogFileAppender"/>

    </root>

  </log4net>

 

 

După cum se vede, folosim RollingLogFileAppender ( adică un fişier a cărui denumire va fi diferita in fiecare zi după modelul datePattern ) de tipul Composite(daca depaseste  maximumFileSize atunci se creează un nou fişier in ziua respectiva).

 

Sa adăugam referinţa proiectului nostru (BookWin) dll-ul log4net.dll din sharedDll .Avem de făcut următoarele in Program.cs :

In funcţia Main scriem prima linie:

log4net.Config.XmlConfigurator.Configure();

apoi adăugam următorul membru in clasa Program:

public static readonly log4net.ILog logger = log4net.LogManager.GetLogger("RollingLogFileAppender");

 

Haide sa scriem in fişier de cite ori un utilizator adaugă un nou Publisher.

In frmPublisherAdd.cs, la evenimentul private void btnAdd_Click(object sender, EventArgs e) vom adăuga codul de log-are:

if (Program.logger.IsDebugEnabled)

                Program.logger.Debug("Adaugat publisher cu numele:" + p.Name);

 

Cam atit e de făcut. Acum rulaţi proiectul, adaugaţi un Publisher, si o sa vedeţi un fişier log4Net.log in care scrie următoarele:

 

<data> [1] DEBUG RollingLogFileAppender Adaugat publisher cu numele:newpub

 

 

E interesant la log4Net ca puteţi adăuga mai mulţi appender-i, astfel ca , de pilda, sa trimită si email de cate ori o modificare e făcuta.

 Observatie 1:

Pentru aplicatia Web, modificarile in Web.Config sunt aceleasi - iar in global.asax trebuie pusa linia urmatoare:

 void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup      
        log4net.Config.XmlConfigurator.Configure();   
    }

Observatie 2:

In loc sa punem codul in fiecare pagina de Web si Windowspe salvare, mai bine punem in fiecare cod de "salvare" al obiectelor- de pilda in public void Save()

Lectura obligatorie: documentaţia de log4net...

 

.NET | programare | tutoriale
Saturday, March 17, 2007 2:15:50 AM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Sunday, March 11, 2007


Tutorial .NET : generarea documentatiei proiectului

Documentarea - Scrierea de fişiere Help.

 

In .NET sunt doua tipuri mari de fişiere Help : Cele care produc Help pentru utilizatorul final si cele care sunt auto-generate din comentarii la cod.

 

Avem nevoie de următoarele:

1.Html Help Workshop – e free si puteţi sa îl downloadati de aici

http://www.microsoft.com/downloads/details.aspx?familyid=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en. Adiţional puteţi downloada si fişiere css stil Office de aici

http://www.microsoft.com/downloads/details.aspx?FamilyId=A6A76073-0E0A-49BB-8E21-318B798B4CF6&displaylang=en

 

 

2. Pentru documentaţia codului exista înainte NDoc – dar din păcate dezvoltatorul nu mai face dezvoltarea pentru .Net 2.0( vezi http://johnsbraindump.blogspot.com/2006/07/ndoc-20-is-dead.html)

Alternativa este SandCastle (http://www.sandcastledocs.com) din care ultimul CTP este aici (http://www.microsoft.com/downloads/details.aspx?FamilyID=E82EA71D-DA89-42EE-A715-696E3A4873B2&displaylang=en).

 

3.De asemenea, pentru ca SandCastle e greu de utilizat din command line, exista mai multe GUI-uri pentru el – intre care vom lucra cu SandCastle Help File Builder de pe CodePlex (http://www.codeplex.com/Wiki/View.aspx?ProjectName=SHFB). O sa lucram cu ultimul release ,1.3.3.1 PROD aflat aici

http://www.codeplex.com/SHFB/Release/ProjectReleases.aspx?ReleaseId=1209

si as downloada chiar sursele ...

 

Începem cu documentarea codului pentru BookObjects, urmând sa trecem la generarea de Help pentru proiectul Windows.

 

Comentariile in C# se fac scriind trei slash-uri deasupra clasei/metodei/cimpului pe care vreţi sa le documentaţi:

/// <summary>

/// Aceasta clasa tine toti publisher-ii

/// Mod de utilizare : folositi Load

/// </summary>

public class ColPublisher : System.Collections.ObjectModel.KeyedCollection<string,Publisher>

{

 

/// <summary>

/// varianta interna de generat cheie unica pentru un Publisher

/// </summary>

/// <param name="item">publisher-ul</param>

/// <returns></returns>

protected override string GetKeyForItem(Publisher item)

{

Continuaţi cu toate metodele sau downloadati ultima varianta de proiect de aici:

http://serviciipeweb.ro/iafblog/content/binary/part12/book.zip

 

In plus, trebuie sa mai setaţi faptul ca trebuie generata documentaţia XML din proprietatile proiectului:

 

 

Acum in folder-ul C:\Book\BookObjects\bin\Debug aveţi generata documentaţia XML. Pornim SandCastle Help File Builder care arata cam asa:

 

 

Apăsam pe Add si ne ducem in C:\Book\BookObjects\bin\Debug. Acolo indicam dll-ul generat iar programul o sa „observe” si fişierul XML. Apăsam pe iconiţa de compilare si ... eroare...

Error: Unresolved assembly reference: System.Configuration (System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a) required by BookObjects

Last step completed in 00:00:02.403

 

 

După descriere vedem că ii lipseşte o referinţa la System.Configuration. Acest dll se afla in GAC (Global Assembly Cache) si o vom adăuga. In Project Properties , la Build=>Dependencies apăsaţi pe butonul cu cele 3 puncte.

Acum in ecranul următor exista un buton cu imaginea de folder si cu o icoana de o cheie care iese, iar la tooltip scrie „Add GAC dependencies”

 

 

Apăsaţi pe el si căutaţi System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a in lista care urmează.

 

Acum spune ca ii lipseşte un XSL(Error: The transform file 'C:\Program Files\Sandcastle\ProductionTransforms\AddOverloads.xsl' could not be loaded. The error is: Could not find file 'C:\Program Files\Sandcastle\ProductionTransforms\AddOverloads.xsl'.). Pentru asta fie downloadati un CTP de SandCastle mai vechi sau Visual Studio 2005 SDK Version 4.0 de la adresa http://www.microsoft.com/downloads/details.aspx?FamilyID=51a5c65b-c020-4e08-8ac0-3eb9c06996f4&DisplayLang=en si copiaţi XSL-ul cu pricina in folder-ul <Program Files>\ Sandcastle\ProductionTransforms, alături de celelalte.

 

Acum rulati din nou si ceea ce se va genera este un document chm , numit Documentation.chm aflat in C:\Book\BookObjects\bin\Debug\Help:

 

 

Putem personaliza ceea ce se generează destul de uşor, modificând setările de aici:

 

 

E clar acum ca aceasta documentaţie se poate regenera la cerere.

 

Sa generam acum documentaţia pentru Windows Forms.

Ar trebui pentru fiecare forma sa avem cate un Help – aşa ca o sa cream 3 fişiere HTML care o sa tina List, Add si Update.

 

Vom crea un nou folder, numit HelpWindows, in C:\book\Help si vom pune in el cele 3 fişiere : add.htm,list.htm,update.htm.

Pornim HTML Help Workshop, File=>New =>Project si daţi next. Adaugati fişierele htm si apăsati pe Contents. Acceptaţi creerea unui nou fişier si apăsând pe iconiţa din stânga cu aspect de fişier adăugat la conţinut cele 3 fisiere, dindu-le numele corespunzătoare. Acum, după compilare, s-a generat un fişier chm. Haideţi sa îl integram cu aplicaţia Windows.

 

 

Sarcina de a copia fişierul chm lângă executabil o las cititorului, având in vedere ca am mai făcut aşa ceva(Project=>Properties=>Build Events). Sa mergem la forma de list si sa adaugam din ToolBox un control HelpProvider. LA proprietati la HelpNameSpace puneti numele chm-ului. Acum pe forma, gasiti HelpKeyword on... (setati valoarea la list.htm) si HelpNavigator on...( setat la topic). Rulati, apasati F1 si iata fisierul de help!

 

Puteti downloada ultimele surse de aici

http://serviciipeweb.ro/iafblog/content/binary/part12/book.zip

 

Lecturi utile:

GAC http://www.codeproject.com/dotnet/DemystifyGAC.asp

MSHelp 2.0 http://www.helpware.net/mshelp2/h20.htm

 

 

 

 

 

 

 

.NET | programare | tutoriale
Sunday, March 11, 2007 6:29:11 AM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Sunday, March 04, 2007


Teste automate cu NUnit- partea 11
De ce ar trebui sa faceti teste automate ?

Din mai multe motive :

1.      Pentru ca e o modalitate usoara de a releva functionalitatile mari ale aplicatiei

2.      Pentru ca la orice modificare la care nu sunteti sigur daca dauneaza cumva logicii aplicatiei puteti rula testele vechi si vedeti daca ati stricat ceva sau nu(Nota : ar trebui sa adaugati un nou test pentru cei care vin dupa voi )

3.      E mai usor de fixat bug-urile daca, pe deasupra, rulati testele in fiecare noapte – si a doua zi dimineata vedeti ceva stricat...

4.       

Hai sa trecem la treaba:

 

Mai intii downloadati NUnit de la http://www.nunit.org/index.php?p=download ( eu am folosit versiunea 2.2.8 )Exista si surse si setup de instalare. Eu as sfatui sa luati sursele sa le compilati.

Apoi la solutia noastra Book.sln adaugam un nou proiect de tipul Class Library , numit BookTest , adaugam o referinta la nunit.framework.dll , aflat in NUnit-2.2.8-src\src\NUnitFramework\framework\bin\Debug2005, modificam class1.cs in TestPublisher.cs si incepem sa scriem testul.Testul cel mai simplu este unul de CRUD – create , read, update, delete.

Avem nevoie de obiectele Publisher respective, precum si de setari in fisierul App.Config pentru a recunoaste Baza de date, precum si de Baza de date.

Pentru Publisher, adaugam o referinta la BookObject in tab-ul „Projects” de la Add Reference.

Pentru App.Config, adaugam un fisier de tipul application configuration file si copiem de la BookDos partile relevante, astfel incit fisierul arata astfel :

 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<appSettings>

<add key="DatabaseUsed" value="MDB"/>

<!-- possible values : MDB, SQLServer-->

</appSettings>

<connectionStrings>

<add name="MDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\book.mdb;User Id=admin;Password=;"/>

<!-- TODO : add for asp.net application the connection string with SQL Server-->

</connectionStrings>

</configuration>

 

Pentru baza de date, e simplu : in Build Events, la Post Build Command Line adaugam

copy $(ProjectDir)..\BookData\*.mdb $(TargetDir)

Acum putem incepe sa scriem testul :

 

 

using System;

using System.Collections.Generic;

using System.Text;

using NUnit.Framework;

using BookObjects;

namespace BookTest

{

[TestFixture] //arata ca e o clasa care contine teste

public class TestPublisher

{

[Test] //arata ca metoda care urmeaza este un test

[Category("CRUD")] //categoria -de obicei, testele de CRUD ar trebui puse impreuna

public void CRUD()

{

Publisher p = new Publisher();

p.Name = "Amazon";

p.Save();

 

//sa il gasim

ColPublisher cp = new ColPublisher();

cp.Load();

bool bFound= false;

foreach (Publisher pLoop in cp)

{

if (pLoop.Name == p.Name)

{

bFound = true;

break;

}

}

//daca acea conditie(bFound) nu e true, atunci se afiseaza mesajul de eroare

Assert.IsTrue(bFound, "Nu s-a gasit publisher cu numele " + p.Name + " dupa insert");

//sa il modificam

p.Name = "O'Reilly";

p.Update();

 

//sa il gasim din nou

cp = new ColPublisher();

cp.Load();

bFound = false;

foreach (Publisher pLoop in cp)

{

if (pLoop.Name == p.Name)

{

bFound = true;

break;

}

}

//daca acea conditie(bFound) nu e true, atunci se afiseaza mesajul de eroare

Assert.IsTrue(bFound, "Nu s-a gasit publisher cu numele " + p.Name + " dupa update");

 

//acum sa il stergem

p.Delete();

 

//si sa vedem ca nu a fost gasit

cp = new ColPublisher();

cp.Load();

bFound = false;

foreach (Publisher pLoop in cp)

{

if (pLoop.Name == p.Name)

{

bFound = true;

break;

}

}

 

//daca acea conditie(bFound) nu e false, atunci se afiseaza mesajul de eroare

Assert.IsFalse(bFound, "S-a gasit publisher cu numele " + p.Name + " dupa delete");

 

 

 

}

}

}

 

 

Il compilam si sa rulam testul. Gasiti in folderul NUnit-2.2.8-src\src\GuiRunner\nunit-gui-exe\bin\Debug2005 un nunit-gui.exe si porniti-l.Apasati File=> Open si mergeti in C:\Book\BookTest\bin\Debug si incarcati BookTest.dll . Ar trebui sa apara figura urmatoare

 

Apasati pe RUN si primul lucru pe care il vedeti este:

 

 

Se vede clar ca e ceva prost... ne uitam in TestPublisher.cs si vedem ca la linia 37 este

p.Update();

Ceva a mers prost la update ... sa vedem linia 107 din Publisher.cs

strSQL += "'" + this.Site.Replace("'", "''") + "'";

Acum e clar ce s-a intimplat ... Cind am facut testul, nu am initializat Site-ul cu nimic... si atunci este null , ceea ce inseamna ca .Replace nu poate fi aplicat

Sa modificam codul din Publisher.cs ca sa ia in seama si acest lucru :

if (this.Site == null)

strSQL += " NULL ";

else

strSQL += "'" + this.Site.Replace("'", "''") + "'";

 

Acum apare alta eroare :

 

Este destul de clar ca aplicatia nu a updatat numele ...

De ce ?Ne dam seama imediat : in momentul in care aplicatia a adaugat un nou Publisher , nu a regasit ID-ul inserat ... iar cind a facut update, IDPublisher este 0 , ceea ce inseamna ca nu a putut fi facut update corect.

Cum modificam acest lucru ? Pentru access , putem sa selectam maxim de ID,iar pentru SQL Server putem crea o procedura stocata ... sau sa intoarcem @@Identity

Hai sa facem pentru Access , modificand Publisher.cs, procedura Save, adaugind la final:

if(Settings.TheDatabase == Settings.DatabaseUsed.MDB)

{

 

strSQL = "select max(IDPublisher) as nr from Publisher";

using (DbConnection dc = Settings.TheConnection)

{

dc.Open();

using(DbCommand dco =Settings.TheCommand)

{

dco.CommandType = System.Data.CommandType.Text;

dco.CommandText = strSQL;

dco.Connection = dc;

object o = dco.ExecuteScalar();

this.IDPublisher = int.Parse(o.ToString());

}

}

}

Acum rulam din nou testul si totul e verde , ceea ce e de bine :

 

 

E clar ca exemplu a fost mai degraba simplut, iar ceea ce conteaza, de fapt, sunt regulile de business si de validare - ca de exemplu, validarea CNP

 

 

.NET | programare | tutoriale
Sunday, March 04, 2007 12:20:30 AM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Tuesday, February 27, 2007


Prezentare RONUA
Am facut prezentarea la RONUA, impreuna cu Andrei Maxim , Hilde Corbu si Aurelian Popa

Super interesanta prezentarea lui Andrei. Pe a lui Hilde nu am reusit sa o urmaresc(telefoane, vorbit cu mai mult cu Bogdan Ciungu cu care nu ma vazusem de mult si pe care il simpatizez mult), iar a lui Aurelian nu am vazut-o din cauza ca la servici avusesem ceva urgent de facut- si trebuia terminat

Acum propun sa cititi 2 rinduri de prezentari:
Cea propusa de MS : link
Cea facuta de mine : link

Ce e mai important sunt linkurile:

Linkuri documentatie :

Excel 2002 si XML
http://support.microsoft.com/kb/288215
 Office 2003: XML Reference Schemas
http://www.microsoft.com/downloads/details.aspx?familyid=fe118952-3547-420a-a412-00a2662442d9&displaylang=en
ECMA-376 -Office Open XML File Formats
http://www.ecma-international.org/publications/standards/Ecma-376.htm

Linkuri utile:
Free Excel Xml Writer Library
http://www.carlosag.net/Tools/ExcelXmlWriter/Default.aspx
Open XML Translator enables interoperability with ODF
http://openxmldeveloper.org/archive/2007/02/02/1172.aspx
Open XML Package Explorer
http://www.codeplex.com/PackageExplorer

.NET | Excel | programare | tutoriale
Tuesday, February 27, 2007 8:46:09 PM (GMT Standard Time, UTC+00:00)  #    Comments [3]  |  Trackback


Sunday, February 25, 2007


Tutorial .NET : Dos Project - very short demo

Open the book.sln solution and add a new project of type ConsoleApplication (name it  BookDos)

Add reference to the BookObjects project and add an app.config file and write to this file the same as in the corresponding app.config file from BookWin application.

The post build event on project – properties must be the same as for the BookWin

copy $(ProjectDir)..\BookData\*.mdb $(TargetDir)

 

In Program.cs file please enter the following code:

using System;

using System.Collections.Generic;

using System.Text;

using BookObjects;

 

namespace BookDos

{

    class Program

    {

        static void Main(string[] args)

        {

            ColPublisher col = new ColPublisher();

            col.Load();

            Console.WriteLine("Records Number:" + col.Count);

            foreach (Publisher p in col)

            {

                Console.WriteLine(p.Name);

            }

        }

    }

}

 

 

And, of course, the number of records will be 0 – as we do not have any records.


In the following we will show how to perform some automated tests with NUnit .

 

 

.NET | programare | tutoriale
Sunday, February 25, 2007 11:25:02 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Sunday, February 11, 2007


Programming in .NET - part 9 -site map and localization

The site map is relatively easy:

Add a new item – find “Site Map” and accept the default name (Web.sitemap)

And put the following

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode url="default.aspx" title="Main"  description="First Page">

    <siteMapNode url="frmPublisherList.aspx" title="All publishers"  description="Publishers list" >

      <siteMapNode url="frmPublisher_Insert.aspx" title="New Publisher" description="Add new"></siteMapNode>

      <siteMapNode url="frmPublisher_Edit.aspx" title="Edit Publisher" description="Edit"></siteMapNode>

      <siteMapNode url="frmPublisher_Delete.aspx" title="Delete Publisher" description="Delete"></siteMapNode>

    </siteMapNode>

    <siteMapNode url="frmBookList.aspx" title="All books"  description="Book list" >

 

    </siteMapNode>

  </siteMapNode>

</siteMap>

 

( the names are pretty suggestive – url, title and description)

Now it’s time to put to work :

Open Book.master , and put a site map control ( find into the navigation tab on toolbox) before content place holder:

<asp:SiteMapPath ID="SiteMapPath1" runat="server" Font-Names="Verdana" Font-Size="0.8em" PathSeparator=" : ">

                            <PathSeparatorStyle Font-Bold="True" ForeColor="#990000" />

                            <CurrentNodeStyle ForeColor="#333333" />

                            <NodeStyle Font-Bold="True" ForeColor="#990000" />

                            <RootNodeStyle Font-Bold="True" ForeColor="#FF8000" />

                        </asp:SiteMapPath>

 

 

And put a tree view instead of right menu:

<asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1" MaxDataBindDepth="1">

                        </asp:TreeView>

                        <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />

 

 

 

Now, if you run the project, and press new  button, you will see the following

 

 

Sure that all books it is not implemented yet – but it is your task to do it.

 

Now we will proceed to the localization part. We want to be able that people see the content in English and French.

We will localize just one form, and we left the others as an exercise to the reader.

The setting of language will be set in a cookie on the user’s PC and will be read each time.

Add a drop down list to the master page, near Book application with the following code:

<asp:DropDownList runat="server" id="ddlLanguage" OnSelectedIndexChanged="ddlLanguage_SelectedIndexChanged" AutoPostBack="true">

                            <asp:ListItem Text="English" Value="en">

                            </asp:ListItem>

                            <asp:ListItem Text="French" Value="fr">

                            </asp:ListItem>

                        </asp:DropDownList>

 

 

On the .cs page, let’s store the actual configuration :

protected void ddlLanguage_SelectedIndexChanged(object sender, EventArgs e)

    {

        HttpCookie cookie = Request.Cookies["Language"];

        cookie.Value = ddlLanguage.SelectedValue;

        Response.AppendCookie(cookie);

        cookie.Expires = System.DateTime.Now.AddYears(1);

        Response.Redirect(Request.Url.LocalPath);

    }

 

 

 

So we have saved the value ... now, let’s retrieve it:

protected void Page_Load(object sender, EventArgs e)

    {

        if (!IsPostBack)

            ChangeLanguage();

 

    }

    private void ChangeLanguage()

    {

        HttpCookie cookie = Request.Cookies["Language"];

        if (cookie == null)

        {

            //set default the cookie in web.config

            string s = Thread.CurrentThread.CurrentUICulture.Name;

            cookie = new HttpCookie("Language");

            cookie.Value = s;

            cookie.Expires = System.DateTime.Now.AddYears(1);

            Response.AppendCookie(cookie);

        }

 

 

        foreach (ListItem li in ddlLanguage.Items)

        {

            if (li.Value == cookie.Value)

            {

li.Selected = true;

                 break;           

}

 

        }

 

    }

 

 

 

Now we must change the language : We can put this on each page, overriding InitializeCulture , or put in a global.asax file( that retains the application events) on Application_BeginRequest: ( new item => Global Application Class)

 

    protected void Application_BeginRequest(object sender, EventArgs e)

    {

        string lang = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;

        HttpCookie cookie = Request.Cookies["Language"];

 

        if (cookie != null && cookie.Value != null)

            lang = cookie.Value;

 

        System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(lang);

        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(lang);

    }

 

 

It is time now to proceed to the localization

Add an Asp.NET folder, named “App_LocalResources”

 

And in this folder, add three resource files, named :

frmPublisherList.aspx.en.resx

frmPublisherList.aspx.fr.resx

frmPublisherList.aspx.resx

(The file name is compose by the name of the aspx file + (optional) language + .resx )

In these files we will add just one string for the Text property of the button that is new, like in the figure:

 

 

Now, we put meta:resourcekey="btnNew" on the button:

<asp:Button ID="btnNew" runat="server" Text="New" OnClick="btnNew_Click" meta:resourcekey="btnNew"/>   

 

And we will see in this mode the translation by changing from English to French in the combo.

Attention: if you do not have the invariant culture file ( the one without language in the name) it does not work!

If you have several items that are invariant ( like the “save”  button) you can add resources to the special folder App_GlobalResources and add there resx files ( that now can be named as you want to ) As example suppose we have now in the App_GlobalResources the files

Buttons.en.resx

Buttons.fr.resx

Buttons.resx

And one resource named

btnSaveText

We can acces as so :

 

<%$ Resources:Buttons,btnSaveText%>

 

 

<asp:Button ID="btnSave" Text="<%$ Resources:Buttons,btnSaveText%>" runat="server" OnClick="btnSave_Click" />

Or , programatically, by writing :

Resources.Buttons.btnSaveText

 

Next time we will look at making a DOS project for the same application

Items to read:

Localization: http://quickstarts.asp.net/QuickStartv20/aspnet/doc/localization/localization.aspx

Master Pages:

http://quickstarts.asp.net/QuickStartv20/aspnet/doc/masterpages/default.aspx

.NET | ASP.NET | programare | tutoriale
Sunday, February 11, 2007 9:41:24 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Sunday, February 04, 2007


tutorial .NET - p8 - edit in ASP.NET
 

Now we will edit the Publisher objects .

Add a new WebForm , name it frmPublisher_Insert.aspx and make sure the “Place code in separate file” and “Select master page” are both selected by default.

Change in source view the title from “Untitled Page” to “Insert Publisher”

Now we must put controls in place to insert publishers

There must be the name and site of the publisher.

I prefer enter a table for this and the page will look like this:

 

<%@ Page Language="C#" MasterPageFile="~/Book.master" AutoEventWireup="true" CodeFile="frmPublisher_Insert.aspx.cs" Inherits="frmPublisher_Insert" Title="Insert Publisher" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

    <table>

        <tr>

            <td colspan="2">Enter values

            </td>

        </tr>

        <tr>

            <td>

               Name

            </td>

            <td>

                <asp:TextBox ID="txtName" runat="server">

                </asp:TextBox>

            </td>

        </tr>

        <tr>

            <td>

               Site

            </td>

            <td>

                <asp:TextBox ID="txtSite" runat="server">

                </asp:TextBox>

            </td>

        </tr>

        <tr>

            <td><asp:Button ID="btnSave" Text="Insert" runat="server" />

            </td>

            <td><asp:Button ID="btnCancel" Text="Cancel" runat="server" />

            </td>

        </tr>

    </table>

</asp:Content>

 

Now switch to design view and double click on Insert button in order to generate Click event. Double click in solution explorer the frmPublisher_Insert.aspx and , in Design view, double click on Cancel button in order to generate Click event.

For cancel it is clear what we must do – redirect to the frmPublisherList.aspx

Response.Redirect("frmPublisherList.aspx", false);

For save button, we must create a new publisher and save

  Publisher p = new Publisher();

        p.Name = txtName.Text;

        p.Site = txtSite.Text;

        p.Insert();

        Response.Redirect("frmPublisherList.aspx", false);

Please try it by setting the frmPublisher_Insert.aspx as start page and run the project (F5)

If all works well (please ensure that Insert has a call to Save()) you will see in the frmPublisherList.aspx the item you just selected.

It is clear that frmPublisherList.aspx has a need for a new button . Let’s put it

<asp:Button ID="btnNew" runat="server" Text="New" OnClick="btnNew_Click" />

And on code:

protected void btnNew_Click(object sender, EventArgs e)

    {

        Response.Redirect("frmPublisher_Insert.aspx", false);

    }

That will be ok for adding a new publisher.

Now for editing and deleting we can make on list… but I prefer having 2 new pages.

So modify a little bit the code on the grid, in order to have the edit and delete operations : the edit will be a link , and the delete will be a button to see how different is the model on the two implementations.

The list page now looks like this:

<%@ Page Language="C#" MasterPageFile="~/Book.master" AutoEventWireup="true" CodeFile="frmPublisherList.aspx.cs" Inherits="frmPublisherList" Title="Publisher Lists" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

    <asp:GridView ID="grdPublisher" runat="server" AutoGenerateColumns="false">

        <Columns>

            <asp:BoundField DataField="Site" HeaderText="Site" />

            <asp:BoundField DataField="Name" HeaderText="Name" />

            <asp:TemplateField HeaderText="Operations">

                <ItemTemplate>

                    <asp:Button runat="server" ID="btnDelete" CommandName="deletepub" CommandArgument='<%# Eval("IDPublisher") %>' Text="Delete" />

                    <asp:HyperLink runat="server" ID="hkEdit" NavigateUrl='<%# Eval("IDPublisher","~/frmPublisher_Edit.aspx?ID={0}") %>' Text="Edit"></asp:HyperLink>

                </ItemTemplate>

            </asp:TemplateField>

        </Columns>

   

    </asp:GridView>

    <br />

    <asp:Button ID="btnNew" runat="server" Text="New" OnClick="btnNew_Click" />

</asp:Content>

 

The link hkEdit is self explanatory – it goes to the frmPublisher_Edit.aspx with the ID of publisher in the row.

For the button we must create the event – and the event is on the grid itself – is the RowCommand

On the .cs file:

    protected void grdPublisher_RowCommand(object sender, GridViewCommandEventArgs e)

    {

        switch(e.CommandName)

        {

            case "deletepub":

                int idPublisher;

                if(int.TryParse(e.CommandArgument.ToString(),out idPublisher))

                {

                    Response.Redirect("frmPublisher_Delete.aspx?ID="+ idPublisher, false);

                    return;

                }

                Response.Write("Can not find id:" + idPublisher);

                break;

            default:

                Response.Write("Do not know command : " + e.CommandName);

                break;

        }

    }

 

Now create the two pages frmPublisher_Delete and frmPublisher_Edit 

On both we will copy the table from the new page and the source – without the class declaration. One more thing is to retrieve from ID the editing publisher:

 

  int idPublisher;

        if(!int.TryParse(Request.QueryString["ID"],out idPublisher))

        {

            Response.Redirect("frmPublisherList.aspx", false);

            return;

        }

        //we have id of the publisher

 

How can we retrieve from the ID of the publisher  the object ? Remember that in Windows forms application we did pass from one form to another the publisher object. Here we have just the Id. For this, we will open again the Book.sln solution and add the method to load one single object.

I like to put the method on ColPublisher and make it static … to not apparently create a new object.

 

public static Publisher sLoadFromID(int ID)

        {

            DbConnection db = Settings.TheConnection;

            using (db)

            {

                db.Open();

                IDataReader ir = Settings.Load("select IDPublisher, NamePublisher, SitePublisher from Publisher where IDPublisher="+ ID, db);

                while (ir.Read())

                {

                    Publisher p = new Publisher();

                    p.FillObject(ir);

                    return p;

                }

            }

            return null;

        }

 

Compile and go to Web project.We can have the publisher:

//we have id of the publisher

        Publisher p = ColPublisher.sLoadFromID(idPublisher);

        if (p == null)//maybe someone deleted

        {

            Response.Redirect("frmPublisherList.aspx", false);

            return;

        }

        if (!IsPostBack)

        {

            //now fill the text boxes

            txtName.Text = p.Name;

            txtSite.Text = p.Site;

        }

 

Why we have put  (!IsPostBack ) ? Simply because the textboxes must be filled only once – the first time. When the user enter new name and/or new site and after clicks on save, we must preserve his data .Other problem is that when we have to save the data, we must have the same code to load the publisher – so we put this into a function into the page:

private Publisher pub

    {

        get

        {

            int idPublisher;

            if (!int.TryParse(Request.QueryString["ID"], out idPublisher))

            {

               

                return null;

            }

            //we have id of the publisher

            return ColPublisher.sLoadFromID(idPublisher); ;

           

        }

    }

 

The code on PageLoad will be now shorter :

protected void Page_Load(object sender, EventArgs e)

    {

        Publisher p = pub;

        if (p == null)

        {

            Response.Redirect("frmPublisherList.aspx", false);

            return;

        }

 

        if (!IsPostBack)

        {

            //now fill the text boxes

            txtName.Text = p.Name;

            txtSite.Text = p.Site;

        }

    }

 

And we must modify the code on saving also :

protected void btnSave_Click(object sender, EventArgs e)

    {

        Publisher p = pub;

        if (p == null)

        {

            //TODO : throw an exception that someone deleted the publisher

            Response.Redirect("frmPublisherList.aspx", false);

            return;

 

        }

 

        p.Name = txtName.Text;

        p.Site = txtSite.Text;

        p.Update();

        Response.Redirect("frmPublisherList.aspx", false);

    }

 

 

You can modify also the text of btnsave from “Insert” to “Save”

On the delete page we will put the same code to retrieve the Publisher .Here is the code:

using System;

using System.Data;

using System.Configuration;

using System.Collections;

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 BookObjects;

 

public partial class frmPublisher_Delete : System.Web.UI.Page

{

    private Publisher pub

    {

        get

        {

            int idPublisher;

            if (!int.TryParse(Request.QueryString["ID"], out idPublisher))

            {

 

                return null;

            }

            //we have id of the publisher

            return ColPublisher.sLoadFromID(idPublisher); ;

 

        }

    }

    protected void Page_Load(object sender, EventArgs e)

    {

        Publisher p = pub;

        if (p == null)

        {

            Response.Redirect("frmPublisherList.aspx", false);

            return;

        }

 

        if (!IsPostBack)

        {

            //now fill the text boxes

            txtName.Text = p.Name;

            txtSite.Text = p.Site;

        }

    }

    protected void btnSave_Click(object sender, EventArgs e)

    {

        Publisher p = pub;

       

        if(p != null)

            p.Delete();

 

        Response.Redirect("frmPublisherList.aspx", false);

    }

    protected void btnCancel_Click(object sender, EventArgs e)

    {

        Response.Redirect("frmPublisherList.aspx", false);

    }

}

 

 

Do not forget to change the text “Insert” of btnSave to “Delete”. You also can put readonly property to true on the textboxes

<%@ Page Language="C#" MasterPageFile="~/Book.master" AutoEventWireup="true" CodeFile="frmPublisher_Delete.aspx.cs" Inherits="frmPublisher_Delete" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

    <table>

        <tr>

            <td colspan="2">Enter values

            </td>

        </tr>

        <tr>

            <td>

               Name

            </td>

            <td>

                <asp:TextBox ID="txtName" runat="server" ReadOnly="true">

                </asp:TextBox>

            </td>

        </tr>

        <tr>

            <td>

               Site

            </td>

            <td>

                <asp:TextBox ID="txtSite" runat="server" ReadOnly="true">

                </asp:TextBox>

            </td>

        </tr>

        <tr>

            <td><asp:Button ID="btnSave" Text="Delete" runat="server" OnClick="btnSave_Click" />

            </td>

            <td><asp:Button ID="btnCancel" Text="Cancel" runat="server" OnClick="btnCancel_Click" />

            </td>

        </tr>

    </table>

</asp:Content>

 

 

Next time we will put some modifications to the site: a site map(in order to can have indications for the user where he is)  and code to change and load resources in English and French languages at run time.

 

.NET | ASP.NET | programare | tutoriale
Sunday, February 04, 2007 10:49:59 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Monday, January 15, 2007


ASP.NET application

Now, it’s time to make the ASP.NET application. I suppose that you have already installed Internet Information Services (you will find in the Administrative tools folder) . If not, please install and run aspnet_regiis.exe that you will find into <WindowsPath> \Microsoft.NET\Framework\<latest version> (my path is C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727)

 

Install SQL Server Express(<Address>) and WebDeveloper(<Adress>) – no install of SQL because you have done this already.

 

Now it’s time to import our data to the SQL Database. Start SQL Server Management Studio and you will find the databases already installed.Create a new database (name: Book) and import the mdb database into this new database. Right Click on Book => Tasks= > Import data .

In the first screen choose as data source Microsoft Access

 

The next screen is correctly completed – as you can, use windows authentication.

Choose next “Copy data from one or more table or views” and click “select all” in the following screen.

You can now press Finish and make the task.

 

Some modifications are necessary to be done:

Choose Book=> Tables in SQL Server Management Studio. Right click Publisher table and press modify.

We must make IDPublisher an auto number like in Access, In SQL Server, auto number is named identity.

 

As you modify the (Is Identity) property, you will see the identity incremend and seed to be modified also in 1 and 1.

Save the table.

The next step is to create a folder where we create the internet program.

Goto C:\Book and create a new folder , named BookWeb

Now , from the Administrative Tools folder double click Internet Information Services and expand (local computer)=> WebSites=> Default Web Site.Right click Default Web Site and choose New => Virtual Directory. Click next. In the Alias please enter BookWeb. For the directory enter C:\Book\BookWeb .Press twice “Finish” and we are ready.

 

Now we are ready to program our first page in ASP.NET.

As usually we will have a list page and create/update/delete pages for Publisher.To make the possibility that the site has an unitary interface, we will create a master page –Book.master.

Open Microsoft Visual Web Developer 2005 Express Edition and choose Open Web Site like in the image:

 

Choose “Local IIS” tab and “BookWeb” as virtual directory

Now we will cre

In the “Solution Explorer” right click the http://localhost/BookWeb and choose              Add new Item – and choose Master Page and name it “Book.master”.Do not forget “ Place code in separate file”    

 

The interface of the master page will be rather simple  : a table that has 2 rows and 2 column , the upper row being an unique cell

 

The content is here:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Book.master.cs" Inherits="Book" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

        <div>

            <table width="100%">

                <tr>

                    <td colspan="2" align="center">

                        Book application</td>

                </tr>

                <tr>

                    <td width="10%">

                        Right menu

                    </td>

                    <td>

                        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">

                        </asp:ContentPlaceHolder>

                    </td>

                </tr>

            </table>

        </div>

    </form>

</body>

</html>

 

 

 

Now the list page.

Add a new Item – Web Form(frmPublisherList.aspx) – and make sure that you have checked BOTH checkboxes. The next dialog shows you the BookMaster that you must select and then press OK.Right click on the file and choose “Set as start page”

In the asp:content tag drag a gridview ( found in Toolbox=> Data) .

This gridview must be filled with data – so we will connect to the objects that we have created. Here is a problem – how we can found if we create for the dll a Debug or Release and bind to the apropiate folder ? The solution, as always in programming, is indirection : make a new folder , bookdll and we will copy here the sources, independently of debug or release.

So we create the C:\Book\BookDll , go back to the Book solution and on Build Events copy the sources in the BookDll folder and put this line in the      Post build command line:

copy $(TargetDir)*.*  $(ProjectDir)..\BookDll /Y

Compile the project.

Now you will find in the C:\Book\BookDll folder the BookObjects.dll

Add a reference to the BookObjects.dll in the BookWeb application( old story : right click http://localhost/BookWeb project, choose add reference, click Browse tab – and navigate to the C:\Book\BookDll folder.

 

On the frmPublisherList.aspx press F7 and put this lines into the Page_load event

if (!IsPostBack)

            BindData();

 

The BindData function:

private void BindData()

    {

        BookObjects.ColPublisher publishers = new BookObjects.ColPublisher();

        publishers.Load();

        grdPublisher.DataSource = publishers;

        grdPublisher.DataBind();// main difference ASP and Windows forms - this call

    }

 

 

Now , if you run the project, an error will occur : Object reference not set to an instance of an object

This is because we do not add yet the web.config with database connection.add a new web configuration file ,named default Web.Config, and in the connection strings put this:

<connectionStrings>

    <add name="SQLServer" connectionString="server=.;Trusted_Connection=true;database=Book;"/>

  </connectionStrings>

And we must specify that we connect to the SQL .

<appSettings>

    <add key="DatabaseUsed" value="SQLServer"/>

    <!-- possible values : MDB, SQLServer-->

  </appSettings>

 

 

Now press again CTRL+F5.  The error that you have now is

Cannot open database "Book" requested by the login. The login failed.
Login failed for user '<PCNAME>\ASPNET'.

Why this error? Remember that we have put Trusted_Connection=true in the web.config. So the user that is connecting is the user that runs the site.

We have more solutions :

1)      Use in the web.config a connection with user name and password (good for Internet sites)

2)      Run the site on other credentials for anonymous( good for internet/intranet sites) – option made in IIS like in image

3)      Disable anonymous and use “Integrated windows”  in collaboration with a setting in web.config file, <identity impersonate="true"/>( good for intranet sites )

4)      Create a SQL Server user for the credentials user(IUSR_ )that has rights on the database.

You can make your choice…Personally, I prefer the first solution.

OK.The next time we will see how to insert data on the SQL database.

 

 

           

Recommended Readings

Master Pages

ConnectionStrings

programare | tutoriale
Monday, January 15, 2007 12:22:56 AM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Sunday, December 17, 2006


P6 - setup program

Now to the performing of the setup.We suppose that we want to deploy from a CD.

 

Right click Book win project, choose properties, and click on “Publish” tab.

There you will find the “Publishing location” – default to http://localhost/BookWin/

If you do not have IIS, then you can select a path, like C:\Book\BookSetup\

The problem that we have is that in the files that we need to install must be also the mdb file.

If you have something like a VS.NET Standard(or more) you have a special project template that allows you to add other files to the deployment. For the moment, we have to do what we can do. So, please right click the bookwin project, click add=>existing item and search for  the book.mdb file from C:\Book\BookData .

Compile the project (CTRL+Shift+B) and now you will find the book.mdb on the application files – as data file.

Now to the prerequisites : Because we are deploying a CD, it is better to include .NET 2.0 – and download from the same location (when  we are deploying from internet, I think it is preferable to deploy from MS site )



The updates will not be yet available, since we do not have yet a web site. But we can customize some of  Options, like publisher name, product name and others.

 

Now press Publish Wizard :

            The first step is where to make the setup kit (C:\Book\BookSetup\ already selected ) , the next is from where (click “from cd –rom or dvd rom”).

            The third allows the application to check for updates – but , for the moment, we do not have a WebSite yet, so “the application will not check for updates”

            And press finish!

 

If an error occurs, that says that can not find package, please go to Microsoft .NET Framework Version 2.0 Redistributable Package (x86) http://www.microsoft.com/downloads/details.aspx?FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5&displaylang=en  and download the kit. Copy this kit to <C:\Program Files>\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper\Packages\DotNetFX

For instmsia.exe , goto http://go.microsoft.com/fwlink/?LinkId=37285 

 

Now you can write the folder C:\Book\BookSetup to a CD and test .

If you do not want a CD, you can wrote a file and load as a CD.

One  way is to  create a ISO file with Alex Feinman IsoRecorder

http://isorecorder.alexfeinman.com/isorecorder.htm

Download his software ( I have tested the version for XP SP2 ) and right click the folder Book Setup








You will see Create ISO image file – click and accept default setting.

Now you have a CD  -and you can load this CD with  Virtual CD Control Panel.

 

You can now test the CD you have already created.

More, if you want to test on another environment, you can download Virtual PC 2004 SP1 or VMWare and create with those a new Windows Installation (of course, you must have the Windows installation CDs).

 

Next time we will do a ASP.NET application with SQL Server as a backend.

Suggested readings:

            Comparison between VS.NET 2005 editions: http://msdn.microsoft.com/vstudio/products/compare/default.aspx

            Virtual PC 2004 SP1 (free) http://www.microsoft.com/downloads/details.aspx?familyid=6d58729d-dfa8-40bf-afaf-20bcb7f01cd1&displaylang=en

            Deployment problems : http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=13937&SiteID=1

            Virtual CD Control Panel –  http://download.microsoft.com/download/7/b/6/7b6abd84-7841-4978-96f5-bd58df02efa2/winxpvirtualcdcontrolpanel_21.exe

            Alex Feinman – Make ISO http://isorecorder.alexfeinman.com/isorecorder.htm

           

.NET | programare | tutoriale
Sunday, December 17, 2006 10:04:05 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Monday, December 11, 2006


editarea de obiecte

Va trebui, asa cum am promis, sa facem adaugarea/ modificarea / stergerea de obiecte( pe scurt, C(R)UD – create, (read), update, delete). Luam un buton din Toolbox, il tragem pe forma, ii setam din proprietati ( apasati F4) numele la btnAdd si text la “&Add” ( &A e pentru ca, atunci cind apasam <ALT> + A , sa fie ca si cind dam click pe button)

 

 

Acum dati dublu click pe button – si veti intra in codul de click. Avem o problema : trebuie ca user-ul sa introduca numele Publisher-ului. O sa creeam o noua forma : Click dreapta pe BookWin, Add => Windows Form- si ii veti da denumirea de frmPublisherAdd.cs. Apasati F4 si la Text puneti : Add Publisher

 

Adaugati un Label( Name: lblName , Text : &Name) si un textbox ( Name : txtName)

Adaugam acum un Button de Add ( Name : btnAdd, Text : &Add) si unul de Exit (Name : btnExit, Text : E&xit)

 

Codul de pe btnExit e cel mai usor ( dati dublu click pe buton)

  private void btnExit_Click(object sender, EventArgs e)

        {

            this.Close();//close the form

        }

Codul de pe Button-ul de Add :

 

            private void btnAdd_Click(object sender, EventArgs e)

        {

            BookObjects.Publisher p = new BookObjects.Publisher();

            p.Name = txtName.Text;

            p.Save();

this.Close();//close the form

        }

 

E clar ca trebuie sa scriem metoda de Save pe Publisher

Inapoi la clase : si acolo vom scrie metoda de save.

  public void Save()

        {

            string strSQL = " insert into Publisher(NamePublisher";

            if (!string.IsNullOrEmpty(this.Site))

                strSQL += ",SitePublisher ";

 

            strSQL += " ) Values (";

 

            strSQL += "'" + this.Name.Replace("'","''") + "'";//terminator for string in SQL is ' - so replace with ''

           

            if (!string.IsNullOrEmpty(this.Site))

                strSQL += "," +"'"+ this.Site.Replace("'", "''") +"'";//terminator for string in SQL is ' - so replace with ''

 

 

            strSQL += " )";

 

           

            Settings.ExecuteSQL(strSQL);

           

           

           

        }

 

In sfirsit, sa scriem codul pentru adaugare de pe forma de list:

E clar ca va trebui sa facem re incarcarea datelor  - deci o sa luam codul de pe frmPublisherList_Load si o sa il punem in o functie generica , RebindData()

 

private void btnAdd_Click(object sender, EventArgs e)

        {

            frmPublisherAdd f = new frmPublisherAdd();

            f.ShowDialog(this);

            RebindData();

        }

 

private void RebindData()

        {

BookObjects.ColPublisher publishers = new BookObjects.ColPublisher();

            publishers.Load();

            colPublisherBindingSource.DataSource = publishers;

        }

 

Sa verificam functionarea

Dati CTRL+ F5 , apasati Add – introduceti un nume – apasati Add – si verificati ca se vede in lista ceea ce ati introdus.

 

Sa facem acum stergerea.

Adaugati alt buton(Name = btnDelete, Text = &Delete) si sa scriem cod pentru delete

private void btnDelete_Click(object sender, EventArgs e)

        {

 

            BookObjects.Publisher p = colPublisherBindingSource.Current as BookObjects.Publisher;

            if (p != null)

            {

                //avert the user

                if (MessageBox.Show(this, "Delete " + p.Name, "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)

                    return;

 

 

                p.Delete();

                RebindData();

            }

        }

 

In sfirsit, sa scriem codul pentru update: iarasi buton, iarasi cod

private void btnUpdate_Click(object sender, EventArgs e)

        {

            BookObjects.Publisher p = colPublisherBindingSource.Current as BookObjects.Publisher;

 

            if (p == null)

                return;

 

            frmPublisherUpdate f = new frmPublisherUpdate(p);

            f.ShowDialog(this);

            RebindData();

        }

 

Pentru asta, adaugam o alta forma, in care sa facem update .

Dar avem neaparata nevoie de un publisher pe care sa facem update.Vom modifica constructorul formei ca sa accepte ca parametru de intrare un publisher.

 

Ca sa punem valorile deja obtinute in text box-uri, avem 2 variante :

Fie codam de mina de doua ori ( ceva de genul  txtName.Text= m_Publisher.Name si , pe salvare, m_Publisher.Name= txtName.Text),fie lucram cu DataBindings direct . Prefer acum, pentru rapiditate, a doua varianta :

 

public partial class frmPublisherUpdate : Form

    {

        private BookObjects.Publisher m_Publisher;

        public frmPublisherUpdate(BookObjects.Publisher pub)

        {

            m_Publisher = pub;

            InitializeComponent();           

        }

 

       

        private void frmPublisherUpdate_Load(object sender, EventArgs e)

        {

            txtName.DataBindings.Add("Text", m_Publisher, "Name");

            txtSite.DataBindings.Add("Text", m_Publisher, "Site");

        }

 

        private void btnSave_Click(object sender, EventArgs e)

        {

            m_Publisher.Update();

            this.Close();

        }

 

        private void btnExit_Click(object sender, EventArgs e)

        {

            this.Close();

        }

 

 

    }

 

Sa scriem si codul de salvare pe publisher :

  public void Update()

        {

            string strSQL = " update Publisher set ";

            strSQL += " NamePublisher = ";

 

            strSQL += "'" + this.Name.Replace("'", "''") + "'";

 

            strSQL += ",";

 

            strSQL += " SitePublisher = ";

 

            strSQL += "'" + this.Site.Replace("'", "''") + "'";

 

 

            strSQL += " where IDPublisher = " + this.IDPublisher;                           

            strSQL += " ";

 

 

            Settings.ExecuteSQL(strSQL);

        }

 

 

Ca tema de acasa, ramine sa faceti acelasi lucru pentru tabela Author.

Data viitoare o sa facem un mic refactoring de code... si o sa facem un program de setup pentru aplicatia Windows.

 

           

programare | tutoriale
Monday, December 11, 2006 7:53:13 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Monday, December 04, 2006


Part 4 : .NET programming

If you have not read yet the first parts, please found them here: Part 1 , Part 2 and Part 3

 

 

Now we have the Access database on the C:\Book\BookData – and the dll to load data is on the C:\Book\BookObjects.

We will create a Windows Forms project to see the data that is in the MDB file.

Right click on the solution -and choose: Add => New Project => and choose Windows Application. Put the name BookWin. A new form is created for you by default.

Change the name from Form1 to frmPublisherList.cs, double click on the file, press F4 to bring Properties window up front and change the Text from Form1 to List of Publishers.

Now we must tell to the windows project to use the objects project that we created earlier. Right click BookWin project in the Solution Explorer, click „Add reference” and go to the Projects tab on the next window. Double Click the BookObjects project.Compile(CTRL+SHIFT+B).

 

I must found a way to copy the MDB in the same location as the executable, in order that the path can function easily even the application will be deployed in other paths. (Not every user will easily agree to deploy the application on the same path as we do, C:\Book – maybe he wants to install in other places).

The solution to be always in sync is to perform the copy automatically and precisely when the build is complete.

Right click on BookWin project from Solution Explorer, select properties (or find in menu Project => Book Project Properties)

On the “build events“tab you have a pre and a post build event command line

We will wrote this code in the post build

copy $(ProjectDir)..\BookData\*.mdb $(TargetDir)

That means copy all MDB files from the following dir C:\Book\BookData (obtained as following from the project dir (C:\Book\BookObjects\), the up (C:\Book\), the to BookData (C:\Book\BookData)) to TargetDir (does no matter if debug or release)

Save and compile (CTRL + SHIFT + B)

Now in the C:\Book\BookObjects\bin\Release or in the C:\Book\BookObjects\bin\Debug must be another copy of the MDB file.

Very good * let’s write now the connection to the MDB. Right Click on BookWin in the Solution Explorer – click Add => New Item => and choose “Application Configuration File” ( default name :App.config – do not change this!) and put the following lines:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<appSettings>

<add key="DatabaseUsed" value="MDB"/>

<!-- possible values : MDB, SQLServer-->

</appSettings>

<connectionStrings>

<add name="MDB" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\book.mdb;User Id=admin;Password=;"/>

<!-- TODO : add for asp.net application the connection string with SQL Server-->

</connectionStrings>

</configuration>

Now it’s the moment to load the records. We put code in the settings.cs file to be able to switch connection at run-time:

public static DbConnection TheConnection

{

get

{

switch (TheDatabase)

{

case DatabaseUsed.MDB:

OleDbConnection oc = new OleDbConnection(ConnectionStringMDB);

return oc;

case DatabaseUsed.SQLServer:

SqlConnection sc=new SqlConnection(ConnectionStringSQLServer);

return sc;

default:

// Maybe throw an error that config file has not been initialized with

// the database type ?

return null;

}

}

}

 

And to load Records:

public static IDataReader Load(string CommandLine, DbConnection dbcon)

{

 

if (!(dbcon.State == ConnectionState.Open))

dbcon.Open();

 

DbCommand dc = null;

switch (TheDatabase)

{

case DatabaseUsed.MDB:

dc = new OleDbCommand(CommandLine);

break;

case DatabaseUsed.SQLServer:

dc = new SqlCommand(CommandLine);

break;

default:

//TODO : throw specific error that database type does not properly have been initialized

break;

}

dc.CommandType = CommandType.Text;

dc.Connection = dbcon;

return dc.ExecuteReader();

 

return null;

 

 

}

 

 

As you see, we return a DbConnection no matter we use the OleDbConnection or SqlConnection .

Now let’s fill in the Load code in the ColPublisher file:

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.Common;

 

namespace BookObjects

{

public class ColPublisher : System.Collections.ObjectModel.KeyedCollection<string,Publisher>

{

protected override string GetKeyForItem(Publisher item)

{

return "K" + item.IDPublisher;

}

public void Load()

{

DbConnection db = Settings.TheConnection;

using (db)

{

db.Open();

IDataReader ir = Settings.Load("select IDPublisher, NamePublisher, SitePublisher from Publisher", db);

while (ir.Read())

{

Publisher p = new Publisher();

p.FillObject(ir);

//TODO : add p into the collection

}

}

}

 

}

}

 

We realize now that the ColPublisher is not a collection where to add the new publisher p. Fortunately, the .NET collection is enough big to contain many collection.

Just look into the System.Collections namespace, then into System.Collections.ObjectModel and into System.Collections.Specialized. You will find many more on the net ( for example, an implementation of a Set collection : http://www.codeproject.com/csharp/sets.asp)

We will derive the ColPublisher from the System.Collections.ObjectModel.KeyedCollection<string,Publisher> .We must wrote how to generate the key for a specific Publisher -and what Key is better than the ID ?

protected override string GetKeyForItem(Publisher item)

{

return "K" + item.IDPublisher;

}

 

Now we can wrote the Load method properly :

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.Common;

 

namespace BookObjects

{

public class ColPublisher : System.Collections.ObjectModel.KeyedCollection<string,Publisher>

{

protected override string GetKeyForItem(Publisher item)

{

return "K" + item.IDPublisher;

}

public void Load()

{

DbConnection db = Settings.TheConnection;

using (db)

{

db.Open();

IDataReader ir = Settings.Load("select IDPublisher, NamePublisher, SitePublisher from Publisher", db);

while (ir.Read())

{

Publisher p = new Publisher();

p.FillObject(ir);

this.Add(p);

}

}

}

 

}

}

 

And use it from the Form :

Double click on the frmPublisherList.cs and drag a DataGridView to the form

 

Now configure the data source:

 

Click on “(none)” and select “add new data source”

In the next dialog, choose “Object”



 

and press next.

Now expand the BookObjects node and choose “ColPublisher”. Press Next and then Finish.

To the form is a new control added: colPublisherBindingSource – and the Grid has already the columns defined.

Now wrote the data to load the data from the database:

Double click on form, and you will find yourself in the Form_Load event :

private void frmPublisherList_Load(object sender, EventArgs e)

{

BookObjects.ColPublisher publishers = new BookObjects.ColPublisher();

publishers.Load();

colPublisherBindingSource.DataSource = publishers;

}

 

Now the results – right click on BookWin – and select “Set as startup project”

Now press F5 * and wait to see the results. If the best case, you will see a form with no data at all – and this is very correct – because of the fact that are no items in the Book.mdb

 

In the next lesson we will wrote code to do insert of a new Publisher and viewing him on the form ( finally!)

 

Recommended readings:

CSLA : http://www.lhotka.net/cslanet/ – a good framework to handle all the security, scalability , binding and other issues ( and, most of all, free).

 

 



 

 

 

 

programare | tutoriale
Monday, December 04, 2006 9:48:54 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]  |  Trackback


Monday, August 28, 2006


programarea in .NET - partea a 3-a - codul pentru obiecte

Ar fi folositor sa cititi partea 1 si partea a 2-a

Acum la creearea obiectelor

Fiecare obiect trebuie sa aiba proprietati care corespund cimpurilor din Baza de date si , pentru usurinta, alte proprietati/metode

O sa scriu codul pentru Publisher si o sa las pe celelalte ca un exercitiu pentru dvoastra. Pentru a salva/sterge/creea un obiect de tip Publisher o sa implementam corespondentele metode corresponding method update / delete / insert.

Faptul ca un publisher trebuie sa aiba un nume unic o sa il scriem mai tirziu.

Stim deja ca trebuie sa avem doua baze de date, asa incit o sa avem doua stringuri de conexiune -pentru Access si pentru SQL Server)

Pentru a usura scrierea stringurilor de conexiune, va rog sa consultati www.connectionstrings.com

PEntru a vedea toate inregistrarile din tabela publisher, trebuie sa stocam undeva multimea lor. Aceasta multime va fi o clasa numita ColPublisher. Ea va contine o metoda numita Load care va incarca Publisher-ul din baza de date si le va stoca intr-o colectie.

Acum , cind stim ce avem de facut in continuare, hai sa scriem ceva cod

Start Visual C# Express( daca e prima oara cind il lansati, va va intreba setarile -puneti pe cele de C#)si creati un nou proiect numit Books

si salvati in C:\book

De obicei, the System.Data.dll este listat in referinte. Daca nu, va rog sa il adaugati. Oricum, adaugati va rog si o referinta la System.Configuration.

Click dreapta pe Solution Explorer si Add reference laOleDBConnection ca mai jos :

Redenumiti Class1.cs dinproprietati( click pe fisier in Solution Explorer si apasati F4) in Publisher.cs

Daca raspundeti "yes" la urmatoarea intrebare, numele clasei va fi schimbat din Class1 in Publisher – si faceti-o public class

Acum o sa scriem proprietatile de baza pentru un Publisher :

using System;

using System.Collections.Generic;

using System.Text;

namespace BookObjects

{

public class Publisher

{

#region Database properties

private int m_IDPublisher;

public int IDPublisher

{

get

{

return m_IDPublisher;

}

set

{

m_IDPublisher = value;

}

}

private string m_Name;

public string Name

{

get

{

return m_Name;

}

set

{

m_Name = value;

}

}

private string m_Site;

public string Site

{

get

{

return m_Site;

}

set

{

m_Site = value;

}

}

#endregion

}

}

Trebuie sa le incarcam aceste proprietati din Baza de date, asa incit o sa scriem o metoda Fill:

O sa o scriem astfel incit sa nu avem dependenta de BD:

#region Database methods

public void FillObject(System.Data.IDataReader idr)

{

this.Name = idr["NamePublisher"].ToString();

this.Site = idr["SitePublisher"].ToString();

}

#endregion

ACum va trebui sa scriem codul de incarcare din BD a diverselor inregistrari. Asaugati o noua clasa ( Project => Add Class) si denumiti-o ColPublisher.cs.

Din nou , faceti-o public class si haide sa scriem metoda care incarca datele din BD.

public void Load()

{

}

ACum ne dam seama ca ne trebuie cele doua conexiuni - si o metoda de a vedea pe care din ele le incarcam.

Asa incit vom incepe sa scriem cod spre a incarca conexiunile :

public static string ConnectionStringMDB

{

get

{

return System.Configuration.ConfigurationManager.ConnectionStrings["MDB"];

}

}

public static string ConnectionStringSQLServer

{

get

{

return System.Configuration.ConfigurationManager.ConnectionStrings["SQLServer"];

}

}

Asa cum am tot spus, avem doua stringuri de conexiune.

A venit timpul sa stim cind incarcam una si cind cealalta in functia Load.

O sa adaug o noua clasa numita Settings si o sa pun acolo setarile comune

O sa adaug o enumerare care o sa imi spuna ce baza de date voi utiliza

public enum DatabaseUsed

{

None,

MDB,

SQLServer

}

si o sa o citim din fisierul de configurare(App.config sau Web.Config) :

public static DatabaseUsed TheDatabase

{

get

{

return Enum.Parse(typeof(DatabaseUsed), System.Configuration.ConfigurationManager.AppSettings["DatabaseUsed"];

}

}

Puteti obserava ca am pus configurarea in Appsetting . Putem stoca si stringurile de conexiune in acelasi loc - dar am vrut sa fim compatibili cu standardul Microsoft.

Codul poate fi obtinut de aici

Data viitoare o sa scriem cod pentru a incarca datele din BD si a le pune in colectie.

De citit:

Pentru .NET best practices, puteti citi http://www.ssw.com.au/ssw/Standards/default.aspx

PEntru construirea unui ORM (Object-relational_mapping) cum facem aici, cititi articolul urmator de pe Wikipedia (http://en.wikipedia.org/wiki/Object-relational_mapping) si puteti gasi o lista de ORM la adresa http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software . Cred ca ar trebui sa cititi cel putin unul, de exemplu Nhibernate : http://www.hibernate.org/343.html

Pentru a genera acelasi cod plecind de la tabele dintr-o baza de date, cititi Code Generation (http://en.wikipedia.org/wiki/Code_generation) si poate CodeSmith (http://www.codesmithtools.com/)

programare | tutoriale
Monday, August 28, 2006 8:38:46 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  |  Trackback


Sunday, August 20, 2006


programarea in .NET - partea a 2-a - creearea bazei de date

Programming in .NET - partea a 2-a - creearea Bazei de date
Cititi mai intii <a href="http://serviciipeweb.ro/iafblog/2006/08/10/Programarea+In+NET+Partea+1.aspx">Programarea In NET - Partea 1 </a>

Conventie : notarile si codul si comentariile or sa fie in engleza. Nu de alta -dar e limba internationala a programarii.

Bun - acum ca ne-am lamurit ce vrem sa facem, hai sa concepem Baza de date.
Aceasta o sa fie, pentru Windows forms, Access - iar pentru ASP.NET - SQL Express.
De ce aceasta alegere ? Simplu :
Pentru aplicatia Windows forms - aleg ceva care sa fie usor de facut deployment-ul
Pentru aplicatia ASP.NET - trebuie sa fie ceva care sa mearga repede - deci un SQL Server se impune
Cum o sa facem sa generam cod pentru oricare din acestea doua, o sa vedeti.

Structura Proiectului:
O sa cream proiectul in C:\Book
In acest director vom crea BookWin.sln ( solutia care va tine proeictul windows si proiectul Consola dos)
si
BookWeb.sln (solutia care va contine proiectul Web -si aplicatia SmartClient)

In acest director vom avea:
BookData( fisierele mdb, scripturile de creeare sql express)
BookObjects( proiectul de conectare la BD si de obiecte)
BookWin( proiectul de Windows)
BookDos ( proiectul de DOS)
BookWeb(proiectul Web)
BookDeployWeb(proiectul de deployment Web)
BookDeployWin(proiectul de deployment Windows)
BookDeploySmartClient(unde vom face deployment-ul SmartClient)
BookTest
Bun - acum haideti sa facem primul pas - creearea bazei de date Access.

Haideti sa creeam impreuna MDB-ul.
Pornim Acces - cream o noua baza de date - o salvam in BookData.
O sa va arat cum se creeaza prima tabela:
Cind sunteti pe tabul "Tables" apasati pe "New Table"


Alegeti "Design View"

 Si incepeti sa introduceti valorile prezentate


Pentru a face IDAuthor Primary Key - dati click dreapta pe coloana de dinainte de IDAuthor si click pe "Primary Key"


La fel se creeaza si celelalte tabele.
Acum ar trebui sa le legam intre ele.
Pentru aceasta , accesati Tools=> Relationships
Adaugati tabelele


Trageti , de pilda, de la IDBook de la tabela Book la IDBook de la tabela Author_Book


Aveti grija sa selectati "referential entigrity" - cascade delete si update



Acum avem Baza de date.Il puteti downloada de aici: book.mdb

Haideti sa concepem obiectele.Acestea or sa fie ca in prima prezentare:
<a href="http://serviciipeweb.ro/iafblog/2006/08/10/Programarea+In+NET+Partea+1.aspx">Programarea In NET - Partea 1 </a>

In a treia parte, postata online la data de 28 August 2006 o sa scriem cod pentru accesul la Baza de date, precum si obiectele principale pentru acest proiect.

tutoriale
Sunday, August 20, 2006 11:21:35 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  |  Trackback


Thursday, August 10, 2006


Programarea in .NET - partea 1
Acesta este un prim articol dintr-o serie care vrea sa prezinte programarea in .NET( Windows si Internet) pe intelesul incepatorilor.
Ca sa puteti urma acest mini-curs, trebuie sa aveti cunostinte minime de programare.Nu o sa va fac teoria variabilelor, nici nu o sa va tin un curs de SQL si nici despre programarea 3-tier.
Exemplele date vor fi facute in C# -dar ele se pot trece la fel de bine in VB.NET sau orice alt limbaj pe care .NET il suporta.Pentru mai multe limbaje, accesati adresa :
http://www.dotnetpowered.com/languages.aspx
Ceea ce o sa ne intereseze in acest tutorial este partea de programare a lui .NET.
De ce aveti nevoie:
1. Un calculator cu Windows instalat( de preferinta , orice de la XP in sus)
2. IIS pentru proiectul Internet . Vedeti daca exista in Control Panel => Administrative Tools => Internet Information Services (IIS) Manager.
Daca nu, duceti-va la Control Panel => Add Or Remove programs => add / remove Windows components si il gasiti acolo
3. MSDN 2006 May - pentru tutoriale si exemple - free :http://www.microsoft.com/downloads/details.aspx?FamilyID=373930CB-A3D7-4EA5-B421-DD6818DC7C41&displaylang=en
4.SQL Server Express - free : http://msdn.microsoft.com/vstudio/express/sql/download/
4. Visual Studio Web Development Express  free  - pentru proiecte internet - http://msdn.microsoft.com/vstudio/express/vwd/)
5. Visual C# Express  free  - pentru proiecte windows - http://msdn.microsoft.com/vstudio/express/visualcsharp/)
6. Optional : ReportViewer Control in Visual Studio 2005 free - pentru raportari locale - http://www.gotreportviewer.com/
 
Dupa ce ati downloadat si instalat aceste programe, prima aplicatie pe care o sa o facem este un proiect cu baze de date prin care o sa indexam cartile din biblioteca proprie.
Proiectul o sa fie schematic, doar pentru demonstrarea programarii Windows si Internet cu .NET.
Elementele principale ale proiectului or sa fie Cartea , Autorul si Editura
 
Atributele principale ale Cartii sunt :
Titlu
Data Aparitiei
ISBN
Editura ( presupunem ca 1 carte nu este editata de mai multe edituri)
 
 
Atributele principale ale Autorului sunt :
Nume
Prenume
 
Atributele principale ale Editurii sunt:
Nume
SiteWeb
 
O carte poate avea mai multi autori, iar un autor poate aparea pe mai multe carti ( legatura multi la multi)
O carte poate avea o singura editura , dar o editura poate publica mai multe carti
 
Ce se cere :
- forme de introducere a celor 3 obiecte
- cautare in baza de date dupa : Editura, Carte, Autor
- afisarea obiectelor in functie de relatiile dintre ele ( de exemplu, daca se selecteaza un autor, sa se afiseze toate cartile scrise de el )
 
 
Urmatorul articol vine fix peste 1 saptamina, luni 21 august.
 
Pina atunci, astept intrebarile voastre la adresa :contact@serviciipeweb.ro


programare | tutoriale
Thursday, August 10, 2006 11:11:38 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  |  Trackback


Theme design by Jelle Druyts

Pick a theme: