Net读取并尝试实例化该类型的自定义属性

本文关键字:类型 自定义属性 实例化 读取 Net | 更新日期: 2023-09-27 18:30:10

我有一个WebApi项目与内部客户共享其模型,例如:

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());

Net读取并尝试实例化该类型的自定义属性。由于我们没有将FluentValidation与模型一起发货,因此导致了一个异常:

无法加载文件或程序集"FluentValidation,Version=6.0.2.0,Culture=neutral,PublicKeyToken=null"或其依赖项之一。系统找不到指定的文件。

堆栈跟踪:

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)

有可能避免这种情况吗?除了把它们一起运出去。

Net读取并尝试实例化该类型的自定义属性

在不同的命名空间中创建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类,但在非服务器端使用带有验证器的内部实现。