簡體   English   中英

Json.Net讀取並嘗試實例化類型上的自定義屬性

[英]Json.Net reads and tries to instantiate custom attributes on the type

我有一個Web Api項目與內部客戶共享其模型,例如:

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

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

我們使用FluentValidation驗證傳入請求的位置:

public class PaymentRequestValidator : AbstractValidator<PaymentRequest>
{
}

當客戶打電話時:

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

Json.Net讀取並嘗試實例化該類型上的自定義屬性。 由於我們沒有將FluentValidation與模型一起提供,因此會導致異常:

無法加載文件或程序集“ FluentValidation,版本= 6.0.2.0,區域性=中性,PublicKeyToken =空”或其依賴項之一。 該系統找不到指定的文件。

堆棧跟蹤:

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)

有可能避免這種情況嗎? 除了將它們一起運送外,還可以采用其他方式。

在不同的名稱空間中創建實現同一接口的PaymentRequest類的兩個不同副本。 也許是這樣的:

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
{
} 

然后,您只需要為所有客戶端提供DTO類,但可以在服務器端使用內部實現和驗證器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM