Nello scenario in cui un servizio WCF restituisce un DataContract con un membro enum che ha un valore non valido (un int non presente nel tipo Enum) l'eccezione generata sul lato client è The underlying connection was closed: The connection was closed unexpectedly.
Stranamente questa eccezione viene attivata perché DataContractSerializer non può serializzare sul lato server della connessione.Errore in anticipo o lancio chiaro quando un'enumerazione non può essere serializzata
avrei preferito qualcosa di più utile gettato su di me e più importante prima, durante l'esecuzione sul lato server, ma forse un avviso del compilatore ...
WCF Service Contract
[ServiceContract]
public interface IDtoService
{
[OperationContract]
MyDto GetData(int value);
}
public enum Rating
{
None = 0,
NotSet = 1,
Somevalue = 34
}
[DataContract]
public class MyDto
{
Rating _rate;
[DataMember]
public Rating Rating
{
get { return _rate; }
set
{
_rate = value;
}
}
}
Servizio implementazione
public class DtoService : IDtoService
{
public MyDto GetData(int value)
{
var dto = new MyDto { Rating = (Rating) 42 }; // not in ENUM!
return dto;
}
}
client
var cl = new DtoServiceClient.DtoServiceClient();
var tada = cl.GetData(1); // connection closed exception
Per avere l'eccezione effettiva gettato ho dovuto disbale 'consentire solo il mio codice' nel VS2010 opzioni di debug e nelle eccezioni dialogo abilitazione generate per 'linguaggio comune eccezioni di runtime'
Con che le impostazioni l'eccezione importante è:
SerializationException
valore Enum '42' non è valido per il tipo 'WcfService1.Rating' e non può essere serializzato. Assicurarsi che i valori enum necessari sono presenti e sono contrassegnati con attributo EnumMemberAttribute se il tipo ha DataContractAttribute attributo
Questo viene al costo che il debugger diventa molto rumoroso di tutti gli altri tipi di eccezioni generate che per quanto ne so può essere ignorato
Cosa posso provare a lanciare questa eccezione senza il rumore?
C'è qualcosa che posso modificare o aggiungere nella pipeline di WCF?
Una possibile soluzione per riuscire presto con il costo di rilavorazione è l'aggiunta di un'asserzione in più nel setter del membro enum:
Debug.Assert(Enum.IsDefined(typeof(Rating), value),"value is not valid for this enum");
Un'alternativa che ho provato era l'aggiunta di un contratto con la speranza un avvertimento potrebbe essere prodotto. Non ho trovato nulla di meglio di una copia di Debug.Assert.
System.Diagnostics.Contracts.Contract.Assert(Enum.IsDefined(typeof(Rating), value));
C'è la possibilità di avere il compilatore emettono questo controllo per me o c'è un'alternativa che non sono a conoscenza?
(ho anche provato a compilare con l'check for arithmetic overflow/underflow
abilitato senza aspettarsi di essere succeful)
CodeContracts emette un avvertimento, (bisogna enble impliciti obblighi di scrittura Enum) anche se questo non aiuta
il valore effettivo non può essere nell'intervallo definito per questo valore enumerazione
questo comportamento è in VS2010/Net 4.0 contesto.
Mi sembra che il contratto sia il meglio che si possa fare senza tentare di estendere il comportamento di serializzazione WCF (che può diventare fiacco come uno yak). –
@SixtoSaez Dopo aver scavato un po 'di più, sento che il tuo suggerimento è il più pratico ora. Non voglio fare uno yak ... – rene