Così ho elaborato come passare i miei oggetti personalizzati nei servizi web di ASP.Net json. Funziona un fascino.Risoluzione dei tipi di array JSON nei servizi Web ASP.Net
Problema che sto avendo sta passando in matrici diritte dei miei oggetti personalizzati o alternativamente passando in array che sono parametri dei miei oggetti personalizzati.
Così, per esempio ...
Public Class WebService1
Inherits System.Web.Services.WebService
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
Public Function AddPersonList(ByVal PersonList As PersonList) As String
Debug.Assert(False)
End Function
Public Class Person
Public Sub New()
End Sub
Public Property FirstName As String
Public Property LastName As String
End Class
Public Class PersonList
Inherits List(Of Person)
End Class
End Class
<script>
$(function() {
$.ajax({
type: "POST",
url: "WebService1.asmx/AddPersonList",
data: " { PersonList: [ { FirstName: 'Max', LastName: 'Gershkovich' }, { FirstName: 'Test1', LastName: 'Test2' } ] }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (e) { debugger; },
error: function (e) { debugger; }
});
});
</script>
esito errore: Il valore \ "System.Collections.Generic.Dictionary`2 [System.String, System.Object] \" non è di tipo \ "WebApplication1.WebService1 + Person \" e non può essere utilizzato in questa raccolta generica. \ R \ nParametro nome: valore
Quindi, come posso spiegare a ASP.net che si tratta di una serie di persone?
Nota: il fatto di modificare la funzione come Elenco (di Persona) o ArrayList funziona, ma dato che implemento le mie raccolte personalizzate questo non è ottimale per me.
UPDATE: Ok, quindi, quello che ho elaborato finora è che questo problema è sicuramente associato a come JavascriptSerializer utilizza SimpleTypeResolver per risolvere i tipi. In pratica se faccio qualcosa di simile
Public Function AddPersonList(ByVal PersonList As String) As PersonList
posso ricreare l'errore utilizzando il seguente codice.
Dim PersonList As PersonList = jsonSerializer.Deserialize(Of PersonList)(PList)
Tuttavia quando fornisco il mio tipo personalizzato resolver lungo le linee di
Dim jsonSerializer As New JavaScriptSerializer(New MyCustomTypeResolver)
posso creare con successo un caso del mio elenco personalizzato.
Ora ho elaborato come fornire il mio convertitore personalizzato nel file web.config. Sulla falsariga di questo ...
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="MyCustomConverter" type="WebApplication1.MyCustomConverter" />
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
Ma il problema è che non riesco a trovare un modo per specificare un CustomTypeResolver. La mia ipotesi è che questo è l'unico pezzo del puzzle che mi manca.
PSS: ho cercato di utilizzare l'assembly nome completo come specificato nella documentazione per il SimpleTypeResolver (SimpleTypeResolver MSDN) ma questo genera un "Operazione non è valida a causa dello stato corrente dell'oggetto." eccezione - che è un errore causato quando il TypeResolver non può risolvere il nome (so che questo testando con il mio CustomTypeResolver)
UPDATE @ Oleg e Sean:
Apprezzo sinceramente il vostro input e hanno infatti cambiato la mia domanda per riflettere i tuoi suggerimenti; avendo detto che il problema con questo cambiamento è che richiede una rielaborazione della mia implementazione di classe e del suo comportamento associato in modi che avrei preferito evitare.
Il mio problema non è mai stato passare in una lista (di oggetto) nel mio servizio web (ho semplicemente posto la domanda in quanto tale per semplificarlo per StackOverflow). In tal caso sarei disposto ad accettare completamente con un elenco generico (di), ma il mio problema era in realtà che uno dei miei oggetti personalizzati implementato una proprietà con un forte tipizzato lista (dei) così per esempio:
Customer {CustomerID AS Guid, FirstName AS String, LastName AS String, EmailAddresses AS EmailAddressList}
che ora ha bisogno di essere cambiato in
Customer {CustomerID AS Guid, FirstName AS String, LastName AS String, EmailAddresses AS List(Of EmailAddress)}
Questa non è certamente la fine del mondo ed è probabilmente meglio nel contesto webservice (come avete suggerito), ma sicuramente un danno quando si tratta di utilizzo applicazione interna delle le mie proprietà della collezione. Ciò significa che una volta che ho questa proprietà ho bisogno di trasmetterla alla mia CustomCollectionList ogni volta che voglio usare alcune funzionalità avanzate o ho bisogno di implementare un'altra proprietà che espone la CustomCollectionList. Entrambe le soluzioni lasciano un sapore sgradevole nella mia bocca.
Per quanto mi riguarda, si tratta di una limitazione del meccanismo di serializzazione in .NET per JSON. Devo ancora vedere un esempio di questa funzionalità e non sono stato in grado di risolverlo da solo. Basta rileggere la domanda dopo un upvote –