neljapäev, 26. veebruar 2009

SQL2005 ASP.NET WebService-t kasutava CLR protseduuri tegemine VisualStudio2008-ga

Selline keerulisem juhtum, et käiakse nagu uni peale, et tahetakse saada arvet PDF kujul ka e-postiga aga mul see arve trükk tehtud VisualStudio2008 ReportVieweriga, ehk RDLC fail ASP.NET veebirakenduse küljes ja nüüd tahetakse seda sama asja saada e-posti peale. Aga arveid on sadu ja tuleb ka igale eraldi saata ning kui nüüd hakata veebis ootama, kuni need tuhat arvet valmis tehakse ja minema saadetakse võib asi kätte ära surra. Lahendus selline, et võtab SQL SERVICE BROKERI kasutusele, topib need arve numbrid, mida e-postile saata sinna sisse ja paneb pärast andmebaasi töö (SqlServerAgent job) käima, mis neid arveid teele lähetab




Kõigepealt teeme ASP.NET WebService VisualStudio 2008 -ga


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using Microsoft.Reporting.WebForms;

namespace KampusInvoice
{
///



/// Summary description for Invoice
///

[WebService(Namespace = "http://www.codewiser.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
//[System.Web.Script.Services.ScriptService]
public class Invoice : System.Web.Services.WebService
{
[WebMethod]
public byte[] InvoicePdf(string raportkataloog, int invoice_form, short keel, long arvenr, int arvetyyp, int tenant)
{
//tõmbame arve trüki RDLC reporti bitijadaks
byte[] pdfsisu = null;

try
{
Microsoft.Reporting.WebForms.LocalReport pdfreport = new LocalReport();
// see peab olema just see "TurukampusConnectionString" millega andembaasi pole pöördume
string connString = System.Configuration.ConfigurationManager.ConnectionStrings["TurukampusConnectionString"].ConnectionString.Trim();
//RDLC kasutab ühte GAC-is olevat DLL-i
pdfreport.AddTrustedCodeModuleInCurrentAppDomain("ReportFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=437410073a8b26ba");
//paneme RDLC-le andmed külge
switch (invoice_form)
{
case 1: //TTÜ
{
pdfreport.ReportPath = raportkataloog + "InvoiceTTU.rdlc";
InvoicesPrintTableAdapters.TENANT_NAVISION_DEBT_KUIDO_STableAdapter nta = new InvoicesPrintTableAdapters.TENANT_NAVISION_DEBT_KUIDO_STableAdapter();
InvoicesPrint.TENANT_NAVISION_DEBT_KUIDO_SDataTable ntab = new InvoicesPrint.TENANT_NAVISION_DEBT_KUIDO_SDataTable();
nta.Connection.ConnectionString = connString;
nta.Fill(ntab, tenant, null);
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_TENANT_NAVISION_DEBT_KUIDO_S", ntab));
InvoicesPrint.ACCOUNT_PARTICIPATORY_KUIDO_SDataTable apt = new InvoicesPrint.ACCOUNT_PARTICIPATORY_KUIDO_SDataTable();
InvoicesPrintTableAdapters.ACCOUNT_PARTICIPATORY_KUIDO_STableAdapter apad = new InvoicesPrintTableAdapters.ACCOUNT_PARTICIPATORY_KUIDO_STableAdapter();
apad.Connection.ConnectionString = connString;
apad.Fill(apt, arvenr);
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_ACCOUNT_PARTICIPATORY_KUIDO_S", apt));

break;
}
default: //turku
{
pdfreport.ReportPath = raportkataloog + "Invoice.rdlc";
break;
}

}


InvoicesPrintTableAdapters.ACCOUNT_DETAILS_PRINT_KUIDO_STableAdapter taprin = new InvoicesPrintTableAdapters.ACCOUNT_DETAILS_PRINT_KUIDO_STableAdapter();
InvoicesPrint.ACCOUNT_DETAILS_PRINT_KUIDO_SDataTable taprintable = new InvoicesPrint.ACCOUNT_DETAILS_PRINT_KUIDO_SDataTable();
taprin.Connection.ConnectionString = connString;
taprin.Fill(taprintable, arvenr, keel);
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_ACCOUNT_DETAILS_PRINT_KUIDO_S", taprintable));

InvoicesPrintTableAdapters.LOGOS_KUIDO_STableAdapter lo = new InvoicesPrintTableAdapters.LOGOS_KUIDO_STableAdapter();
InvoicesPrint.LOGOS_KUIDO_SDataTable lotab = new InvoicesPrint.LOGOS_KUIDO_SDataTable();
lo.Connection.ConnectionString = connString;
lo.Fill(lotab, 1); //1 ON ARVE VÄLJATRÜKI LOGO
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_LOGOS_KUIDO_S", lotab));
InvoicesPrintTableAdapters.INVOICE_TYPE_BANK_ACCOUNT_STableAdapter ta = new InvoicesPrintTableAdapters.INVOICE_TYPE_BANK_ACCOUNT_STableAdapter();
InvoicesPrint.INVOICE_TYPE_BANK_ACCOUNT_SDataTable tb = new InvoicesPrint.INVOICE_TYPE_BANK_ACCOUNT_SDataTable();
ta.Connection.ConnectionString = connString;
tb.Locale = System.Globalization.CultureInfo.CurrentCulture;
ta.Fill(tb, Convert.ToInt32(arvetyyp));
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_INVOICE_TYPE_BANK_ACCOUNT_S", tb));
pdfreport.EnableExternalImages = true;

//teeme selle reporti väljatrüki bitijadaks
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension;
pdfsisu = pdfreport.Render("PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);

}
catch (SystemException ex)
{
throw ex;
}
return pdfsisu;
}
}
}

ja installime IIS-i peale ning kontrollime kas töötab, kontrollime vastavalt URL-lt

http://10.0.40.8:4434/Invoice.asmx

Seejärel teeme uue Visual C# SqlServer projekti, kuhu lisame Reference System.Web.Services. Kui on SQL2005 versioon, siis kompileerib dll-i .NET version 2.0-ga

ja sinna teeb ühe SQL2005 CLR salvestatud protseduuri
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void ArvePdf(SqlString raportkataloog, SqlInt32 invoice_form, SqlInt16 keel, SqlInt64 arvenr,
SqlInt32 arvetyyp, SqlInt32 tenant, SqlString fail, SqlString WebServiceUrl)
{
try
{
byte[] sisu = null;

// see KampusArve.Invoice ilmub alles siis, kui oled WebService proxy ära teinud ja projekti lisanud
// vahepeal kui midagi ArvePdf-s muudad, tuleb proxy KuidoInvoice.cs projektist ära kustutada ja uuesti lisada
KampusArve.Invoice arve = new KampusArve.Invoice();
arve.Url = (string)WebServiceUrl; // "http://10.0.40.8:4434/Invoice.asmx";
sisu = arve.InvoicePdf((string)raportkataloog, (int)invoice_form, (short)keel, (long)arvenr, (int)arvetyyp, (int)tenant);
arve.Dispose(); //mälu vabaks igaks juhuks
FileInfo fil = new FileInfo((string)fail);
FileStream f = fil.OpenWrite();
f.Write(sisu, 0, sisu.Length);
f.Close();
}
catch (SystemException ex)
{
throw ex;
}

}
};

Nüüd tuleb luua proxy klass selle WebService poole pöördumiseks

wsdl /o:KuidoInvoice.cs /n:KampusArve http://10.0.40.8:4434/Invoice.asmx

KampusArve on see namespace mis luuakse

http://10.0.40.8:4434/Invoice.asmx on olemasolev ASP.NET Webservice, mis sai enne tehtud

localhosti tegemisel kasuta, kui teed lokaalses masinas ja service on 81 pordis
wsdl /o:KuidoInvoice.cs /n:KampusArve http://localhost:81/Invoice.asmx

KuidoInvoice.cs on nüüd see proxy klass mis tehakse

Nüüd tuleb see fail lisada VisualStudio2008s vastavasse VisualC# SqlServer projekti




nüüd teeme nendest kahest failist library

csc /target:library /out:KampusWebService.dll ArvePdf.cs KuidoInvoice.cs

ja teeme ka staatilise serialization assembly, kuna SQL2005 teisiti ei luba

sgen /a:KampusWebService.dll /force

nüüd nagu asjad olemas (KampusWebService.XmlSerializers.dll ja KampusWebService.dll)

NB! Kui midagi muuta ArvePdf.cs- tuleb see proxy KuidoInvoice.cs projektist eemaldada ja uuesti teha WSDL.exe.ga ning teegid samuti uuesti luua.

paneme tehtud library-d SQL2005 sisse, kuna pöördume WebService poole siis ASSEMBLY teeme UNSAFE suvandiga. Failid tuleb ennem kopeerida SQLSERVER-i kõvakettale

VisualStudio2015 võib vaja minna et tuleb luua ka xmlserializers.dll, mis luuakse, kui lisada signeerimsvõti ja serializerdll luuaks sgen.exe käsuga
sgen /force /compiler:/keyfile:c:\Campus\KampusPdfInvoice\KampusPFDInvoice.snk KampusPdfInvoice.dll

Tekkinud
CREATE ASSEMBLY KampusVeeb
FROM 'C:\CAMPUS\KampusVeeb\bin\Debug\KampusVeeb.dll'
WITH PERMISSION_SET = UNSAFE

VisualStudio2008 deploy siin KampusWebService.dll ja KampusWebService.XmlSerializers.dll ei liiguta, tuleb käsitsi teha

CREATE ASSEMBLY KampusWebService FROM 'D:\TEMP\KampusWebService.dll'
WITH PERMISSION_SET = UNSAFE

ja ka serialization assembly, see saab olla SAFE

CREATE ASSEMBLY [KampusWebService.XmlSerializers]
FROM 'D:\TEMP\KampusWebService.XmlSerializers.dll'
WITH PERMISSION_SET = SAFE

Loome ka nüüd protseduuri SQL SERVER-isse

CREATE PROCEDURE dbo.ArvePdf
@raportkataloog NVARCHAR(400),
@invoice_form INT,
@keel SMALLINT,
@arvenr BIGINT,
@arvetyyp INT,
@tenant INT,
@fail NVARCHAR(2000),
@WebServiceUrl NVARCHAR(2000)
AS EXTERNAL NAME KampusWebService.StoredProcedures.ArvePdf


Proovime, kas töötab
--@raportkataloog on see kataloog IIS-i serveri peale, kus põhirakenduse enda RDLC --failid asuvad

EXECUTE [dbo].[ArvePdf]
@raportkataloog='D:\cw-turukampus\Raportid\'
,@invoice_form=1
,@keel=24
,@arvenr=26236
,@arvetyyp=600000
,@tenant=271088
,@fail='G:\temp\kuido.pdf'
,@WebServiceUrl='http://10.0.40.8:4434/Invoice.asmx'

ja tulemusena peaks see fail valmis olema G:\temp\kuido.pdf, mida saab nüüd e-postiga teele panna

Blogged with the Flock Browser