1

J'ai un projet Web APIs partager ses modèles avec les clients internes, comme ceci:Json.Net lit et essaie d'instancier des attributs personnalisés du type

public PaymentController : ApiController 
{ 
    public IHttpAction PostPayment(PaymentRequest request) 
    { 
    } 
} 

[Validator(typeof(PaymentRequestValidator))] 
public class PaymentRequest 
{ 
} 

Si nous utilisons FluentValidation pour valider les demandes entrantes :

public class PaymentRequestValidator : AbstractValidator<PaymentRequest> 
{ 
} 

Lorsqu'un client effectue un appel:

httpClient.PostAsJsonAsync("api/payment", new PaymentRequest()); 

Json.Net lit une nd essaie d'instancier des attributs personnalisés sur le type. Puisque nous ne livrons pas FluentValidation aux côtés des modèles, il provoque une exception:

Impossible de charger le fichier ou l'assembly 'FluentValidation, Version = 6.0.2.0, Culture = neutral, PublicKeyToken = null' ou une de ses dépendances . Le système ne peut pas trouver le fichier spécifié.

Trace de la pile:

at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type) 
at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext) 
at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) 
at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg) 
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent) 
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit) 
at Newtonsoft.Json.Utilities.ReflectionUtils.GetAttributes(Object attributeProvider, Type attributeType, Boolean inherit) 
at Newtonsoft.Json.Serialization.JsonTypeReflector.GetAssociateMetadataTypeFromAttribute(Type type) 
at Newtonsoft.Json.Utilities.ThreadSafeStore`2.AddValue(TKey key) 
at Newtonsoft.Json.Utilities.ThreadSafeStore`2.Get(TKey key) 
at Newtonsoft.Json.Serialization.JsonTypeReflector.GetAttribute[T](Type type) 
at Newtonsoft.Json.Utilities.ThreadSafeStore`2.AddValue(TKey key) 
at Newtonsoft.Json.Utilities.ThreadSafeStore`2.Get(TKey key) 
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType) 
at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type) 
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.WriteStartArray(JsonWriter writer, Object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) 
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) 
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) 
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType) 
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding) 
at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding) 
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) 

Est-il possible d'éviter cela? D'une autre manière que de les expédier ensemble.

+0

Peut-être un résolveur de contrat personnalisé? – zaitsman

+0

@zaitsman: va essayer la semaine prochaine, merci – abatishchev

Répondre

1

Créez deux copies différentes de la classe PaymentRequest implémentant la même interface, dans des espaces de noms distincts. Peut-être quelque chose comme ceci:

public interface IPaymentRequest 
{ 
} 

//This class will be shipped to your clients. 
public class PaymentRequestDTO: IPaymentRequest 
{ 
} 


//This class will be used in your WebAPI or Server Side code. 
[Validator(typeof(PaymentRequestValidator))] 
public class PaymentRequest: IPaymentRequest 
{ 
} 

Ensuite il vous suffit d'expédier la classe DTO pour tous vos clients, mais utilisez votre implémentation interne avec votre validateur côté serveur un.