Problema Console App Windows & WebService

mercoledì 15 gennaio 2014 - 15.21
Tag Elenco Tags  VB.NET  |  .NET 2.0  |  .NET 3.0  |  .NET 3.5  |  .NET 4.0  |  Windows Server 2008 R2  |  Windows Server 2008  |  Windows Server 2003  |  Windows 7  |  Windows XP  |  Visual Studio 2010  |  Visual Studio 2008  |  Visual Studio 2005  |  Visual Studio 2003  |  Visual Studio Express  |  SQL Server 2008 R2  |  SQL Server 2008  |  SQL Server 2005  |  SQL Server Express  |  MySQL 5.5  |  MySQL 5.1  |  MySQL 5.0  |  Oracle 10g  |  Oracle 9g  |  Oracle 8g  |  Access (.mdb)  |  Office 2010  |  Office 2007  |  Office 2003  |  Internet explorer 8.0  |  Chrome  |  Firefox  |  Javascript  |  VBScript  |  CSS 3.0  |  HTML 4.01  |  Crystal Reports 8.5  |  SQL Reporting Services

angelo87 Profilo | Newbie

Ciao a tutti,

ho migrato il mio web service da iis6 di win2003 a iis7 di win2008, qui di seguito il codice della pagina asp.net che si collega al web service:

Dim sComune As String = "Roma"
Dim converter As New WS_Comuni
Dim Valore As New ArrayList

Valore = converter.TrovaComune(sComune)

Console.Writeline(Valore.Item(0).ToString())

Testando il codice qui sopra sulla nuova piattaforma Visual studio web developer mi indica un errore sulla riga:

Dim converter As New WS_Comuni

come se WS_Comuni fosse incompleto.

WS_Comuni è sia il nome del file .asmx pubblicato, sia il nome di riferimento del servizio nel progetto windows console application.

Per favore potete aiutarmi a risolvere questo problema, visto che ho migrato solamente da iis6 (win2003 32bit) a iis7 (win2008 64bit), senza modificare il codice?

Grazie per il supporto.
Angelo

0v3rCl0ck Profilo | Guru

ciao, riesci a postarci l'errore completo?


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Ciao,

l'errore mi viene presentato nella scheda codice in visual studio express.

Errore: PREVISTO TIPO
Angelo

0v3rCl0ck Profilo | Guru

Quindi l'errore ce l'hai in compilazione o quando eseguì il programma? Abbiamo bisogno di più informazioni dettagliate per capire il problema.

Se l'errore ce l'hai prima di eseguire il programma prova a compilare il progetto e ha copiarci tutto il risultato dall'output window. Mentre se l'errore è durate l'esecuzione visual studio si blocca sulla riga dell'errore e ti da la possibilità di copiare tutto l'errore completo di stacktrace


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

0v3rCl0ck Profilo | Guru

È come se non trovasse la classe, prova anche a controllare il namespace e se la classe in questione è Public, prova a specificare il path completo alla classe come ad esempio System.String invece che solo String, anche nel tuo caso la classe sarà all'interno di un namespace, prova a specificare tutto il percorso.


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Ciao,

ho provato a dichiarare il path completo delle classi, così come mi hai consigliato però l'errore in Visual Studio rimane, ovvero in fase di debug dell'applicazione mostra come errore "TIPO wsComuni non definito".

Un'altra cosa che ho notato, che quando era nel vecchio host (win 2003 32bit) vedevo i metodi (tra i quali TROVA COMUNE) ora che è sul nuovo host (win 2008 64bit) vedo i metodi solo se raggiungo il web service da browser, ma in fase di scrittura del codice all'interno della pagina asp.net mostra solo gli oggetti (es. wsComuni.SoapClient, TrovaComuneRequest, TrovaComuneResponse).

Mi da l'impressione che visual studio non riesca a leggere i metodi dell'operazione TROVA COMUNE per colpa di qualche blocco a monte.
Angelo

angelo87 Profilo | Newbie

L'errore lo ho in fase di scrittura del codice, e al momento che viene debuggata l'applicazione.

L'errore mostrato è uguale in entrambe i casi.
Angelo

angelo87 Profilo | Newbie

Mi sta anche venendo il dubbio che forse iis in win2008 server 64bit abbia delle restrizioni di default che limitano i servizi web pubblicati a differenza di win2003 server 32bit che magari non presentava questi vincoli.
Angelo

0v3rCl0ck Profilo | Guru

a parte l'host cambiato da win2003 a win2008 se mi parli di scrittura del codice vuol dire che il problema è anche di codice, quindi non hai solo cambiato l'hosting, ma anche piattaforma di sviluppo, hai cambiato versione di visual studio per caso? oppure dopo che hai spostato il web service da win2003 a win2008 hai aggiornato la service reference del progetto asp.net che punta al web service? se così fosse il generatore di codice di visual studio che genera la classe proxy per accedere al web service potrebbe averti cambiato la firma delle classi aggiungendo un namespace diverso, e se sei passato ad una versione più aggiornata di visual studio rispetto a prima, potrebbe averti cambiato anche qualcosa nei nomi dei metodi, sicuramente con le nuovi versioni è possibile ritrovarsi con aggiunti i metodi Async.


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Ciao,

la versione di visual studio è sempre rimasta quella, è cambiata solo la service pack di quest'ultimo, arrivata al momento alla SP4.

Dopo aver migrato e visto che non funzionava più ho provato anche ad aggiornare la reference del web service nel progetto web, che presenta il problema.

A questo punto cosa posso fare, visto che anche se il webservice lo ho rifatto da zero in un nuovo progetto, il problema sussiste ?

Grazie per la tua disponibilità.

Buona giornata
Angelo

0v3rCl0ck Profilo | Guru

se riesci, prova a produrci un piccolo zip contenente il progetto web service e il progetto asp.net che tenta di consumare il servizo, riproducendo lo stesso errore. Ovviamente non abbiamo bisogno di tutto il tuo progetto, ma solo una piccola parte che simuli lo stesso identico problema e il tutto lo alleghi come zip al post di risposta, in questo modo credo che vedremo subito dove sta il problema e possiamo aiutarti, altrimenti facciamo fatica a capire dove sia il problema con pochi elementi.


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Ciao,
dopo qualche tentativo di far saltare fuori qualche log migliore, son riuscito ad ottenere questo


446x200 7Kb



Scusa se ti rispondo solo ora, ma purtroppo ho avuto degli imprevisti lavorativi.. :(
Angelo

0v3rCl0ck Profilo | Guru

Perfetto da questo errore si vede che il problema è di permessi di esecuzione della stored procedure.

Hai forse cambiato la connection String durante la migrazione, cambiando utente.. Oppure hai migrato anche il database e ti sei dimenticato di ricollegare l'utente del db a quello dell'istanza nuova di sql?

Ad ogni modo è semplice controlla che utente utilizzi nella connection String e dai i permessi a quell'utente di eseguire quella stored procedure dandogli la GRANT EXECUTE.


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Ciao ho migrato sia la parte web, sia parte di database su una nuova vm, ripristinando il tutto (sql incluso) dai backup della sera prima (.bak nel caso di sql generato e successivamente restorato dall'utility di sql server).

E' possibile lanciare il comanda GRANT EXECUTE per tutto il database (tabelle, stored e viste) oppure lo devo fare tante volte per ogni oggetto ??

Grazie e buona domenica
Angelo

0v3rCl0ck Profilo | Guru

>Ciao ho migrato sia la parte web, sia parte di database su una
>nuova vm, ripristinando il tutto (sql incluso) dai backup della
>sera prima (.bak nel caso di sql generato e successivamente restorato
>dall'utility di sql server).

allora è stato questo che ha compromesso tutte le permission, perchè il backup del database porta con se solo le utenze e i ruoli sotto forma di puri metadati, i ruoli rimangono a posto senza problemi, ma gli utenti di fatto non sono più gli stessi utenti della nuova istanza, anche se hanno lo stesso nome, questo perchè sono collegati con identificativi univoci e non per nome, quindi se volevi ripristinare completamente il database avresti dovuto anche restorare il master db.

Ecco cosa contiene il masterdb: http://technet.microsoft.com/en-us/library/ms187837.aspx

e anche il restore dell'msdb se volevi ripristinare tutti i job di sql agent: http://technet.microsoft.com/en-us/library/ms187112.aspx

>
>E' possibile lanciare il comanda GRANT EXECUTE per tutto il database
>(tabelle, stored e viste) oppure lo devo fare tante volte per
>ogni oggetto ??
>

se hai già gli utenti presenti sul db restorato che hanno già le grant sulle stored procedure oppure associati a roles che a loro volta hanno già le grant, puoi semplicemente ricreare lo stesso utente a livello di istanza sql, e ricollegare l'utente nuovo all'utente presente sul db restorato, con questo comando:

nuovo metodo:

ALTER USER UserName WITH LOGIN = UserName

vecchio metodo, alla prossima versione di sql server (dopo la 2012) verrà rimossa:

EXEC sp_change_users_login 'Auto_Fix', 'user'

script da eseguire sul database a cui devi ripristinare gli utenti.

Se non hai più gli utenti e non fai uso già di ruoli a cui puoi semplicemente assegnare il nuovo utente, puoi utilizzare uno script per assegnare il ruolo a tutte le tabelle o stored procedure, ma ti consiglio vivamente a questo punto di rivedere le permission del db, sfruttando i ruoli invece che assegnare direttamente l'utente per scongiurare lo stesso problema la prossima volta:

http://www.mukkapati.com/blog/post/T-SQL-Script-for-Grant(ing)-permissions-to-all-tables-in-a-database-to-a-user.aspx

lo stesso script può essere riadattato per le stored procedure, cerca il filtro adatto per la sysobjects e sei a posto.

>Grazie e buona domenica
>Angelo
Prego
Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Grazie, la tua spiegazione mi è stata molto utile, il problema in sql lo ho risolto... :)

Secondo te una funzione scritta così in un web service è corretta oppure si può migliorare ??

code:

<WebMethod()> _
Public Function FindComune(ByVal oComune As String) As ArrayList

Dim connectionString As String = ConfigurationManager.ConnectionStrings("ConnDB_Comuni").ToString()

Dim sRicerca As String = "comune LIKE '" + oComune + "'"
Dim sRighe As Integer = "0"
Dim oDati As ArrayList

Using conn As New SqlConnection(connectionString)

Using cmd As New SqlCommand("dbo.VS_COMUNI")
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New SqlParameter("@ID", DBNull.Value))
cmd.Parameters.Add(New SqlParameter("@ricerca", sRicerca))

conn.Open()
cmd.Connection = conn

Using rdr As SqlDataReader = cmd.ExecuteReader()
If rdr.HasRows Then
Dim dt As New DataTable()
dt.Load(rdr)

sRighe = dt.Rows.Count

If sRighe > 0 Then

For Each dr As DataRow In dt.Rows

oDati = New ArrayList()

With oDati
.Add(dr.Item(1).ToString()) 'Comune
.Add(dr.Item(2).ToString()) 'Provincia
.Add(dr.Item(3).ToString()) 'Regione
End With

Next

End If

End If

End Using

End Using

End Using

Return oDati

End Function


Grazie in anticipo per il tuo supporto
Angelo

0v3rCl0ck Profilo | Guru

Direi che può andare bene, come punti di miglioria ce ne possono essere tanti, come separare la logica di lettura a database dalla logica del servizio, quindi fare una classe ComuniStorage dove fai la query a database e ritorni una lista o un solo elemento di una classe (Comune) con le 3 proprietà comune, provincia e regione, poi dal metodo di servizio ritornare un Comune oppure un List<Comune> e richiamare il metodo su ComuniStorage tipo GetListaComuni() o GetComune(ricerca as string) che ritorni appunto o un singolo Comune o una lista in base a quello che ti serve.

Puoi anche evitare il datatable/dataset, utilizzando il datareader per riempire un oggetto Comune e/o una lista.

Dim oComune As String = "" Dim connectionString As String = "" Dim sRicerca As String = "comune LIKE '" + oComune + "'" Dim sRighe As Integer = "0" Dim oDati As ArrayList Using conn As New SqlConnection(connectionString) Using cmd As New SqlCommand("dbo.VS_COMUNI") cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add(New SqlParameter("@ID", DBNull.Value)) cmd.Parameters.Add(New SqlParameter("@ricerca", sRicerca)) conn.Open() cmd.Connection = conn Using rdr As SqlDataReader = cmd.ExecuteReader() If rdr.Read() Dim comune As New Comune() comune.Comune = rdr("Comune") comune.Provincia = rdr("Provincia") comune.Regione = rdr("Regione") End If End Using End Using End Using

quindi avere almeno 3 classi:

Comune (modello del comune)
ComuneStorage (accesso al database e ritorna il modello comune)
ComuneService (accesso al comuneStorage e ritorna il modello comune)

Ad ogni modo per altre domande, crea un post nuovo e chiudi questo accettando una delle miei risposte, ed eventualmente se questa risposta non è abbastanza e vuoi ulteriori dettagli, apri un altro post con una richiesta specifica.


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

0v3rCl0ck Profilo | Guru

un esempio completo di quello che ti dicevo:

Class Comune Property Comune() As String Property Provincia() As String Property Regione() As String End Class Class ComuneStorage Private ReadOnly _connectionString As String Public Sub New() Me.New(ConfigurationManager.ConnectionStrings("ConnDB_Comuni").ConnectionString) End Sub Public Sub New(ByVal connectionString As String) _connectionString = connectionString End Sub Public Function GetComune(ByVal oComune As String) As Comune Dim sRicerca As String = "comune LIKE '" + oComune + "'" Using conn As New SqlConnection(_connectionString) Using cmd As New SqlCommand("dbo.VS_COMUNI") cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add(New SqlParameter("@ID", DBNull.Value)) cmd.Parameters.Add(New SqlParameter("@ricerca", sRicerca)) conn.Open() cmd.Connection = conn Using rdr As SqlDataReader = cmd.ExecuteReader() If rdr.Read() Then Dim comune As New Comune() comune.Comune = rdr("Comune") comune.Provincia = rdr("Provincia") comune.Regione = rdr("Regione") Return comune End If End Using End Using Return Nothing End Using End Function End Class Class ComuneService <WebMethod()> _ Public Function FindComune(ByVal oComune As String) As Comune Dim comuneStorage As New ComuneStorage Dim comune As Comune = comuneStorage.GetComune(oComune) Return comune End Function End Class


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Grazie x il codice lo ho provato e funziona molto bene... :)

Il codice che mi hai mandato estrae un record solo, se volessi estrarre n record, in base per esempio alla provincia, sarebbe possibile avere come risultato un ciclo che restituisce tutti i comuni della provincia selezionata?

Grazie in anticipo.

0v3rCl0ck Profilo | Guru

potresti aggiungere una funzione così:

Public Function GetComuni(ByVal oComune As String) As List(Of Comune) Dim comuni As New List(Of Comune) Dim sRicerca As String = "comune LIKE '" + oComune + "'" Using conn As New SqlConnection(_connectionString) Using cmd As New SqlCommand("dbo.VS_COMUNI") cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add(New SqlParameter("@ID", DBNull.Value)) cmd.Parameters.Add(New SqlParameter("@ricerca", sRicerca)) conn.Open() cmd.Connection = conn Using rdr As SqlDataReader = cmd.ExecuteReader() While rdr.Read Dim comune As New Comune() comune.Comune = rdr("Comune") comune.Provincia = rdr("Provincia") comune.Regione = rdr("Regione") comuni.Add(comune) End While End Using End Using Return comuni End Using End Function


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

angelo87 Profilo | Newbie

Ciao,

ho testato giusto stasera il tuo ultimo update di codice, e gira che è una favola.... Anche la console client che scarica i dati va che è una meraviglia... :)

Grazie ancora !!


Spero un domani di poter contraccambiare il favore !!
Angelo

0v3rCl0ck Profilo | Guru

>Ciao,
>
>ho testato giusto stasera il tuo ultimo update di codice, e gira
>che è una favola.... Anche la console client che scarica i dati
>va che è una meraviglia... :)

bene, ricorda c'è un gruppo di classi per disegnare le tue entità (model layer), un altro gruppo per modellare/interagire con quelle entità (business layer), e un gruppo di classi per l'accesso ai dati da uno o più storage su file/sql/websvc (data access layer). Non esiste un particolare obbligo o dovere nell'utilizzare questi gruppi di classi, non sei costretto ad averli tutti per forza, ma serve per darti un punto di partenza per disaccoppiare diverse tipologie di lavoro che vengono svolte all'interno della tua applicazione. Più dividi, e più isoli, più avrai il controllo di potere cambiare una piccola parte senza dovere riscrivere tutto il resto dell'app, come contro hai che perdi sempre di più la visione completa dell'intera applicazione, ma tutto il resto ne guadagna.

>
>Grazie ancora !!
>

figurati!!

>
>Spero un domani di poter contraccambiare il favore !!

Potresti darci una mano sul forum, se vedi domande a cui sai rispondere, non aspettiamo altro

Ciao,
Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5