none
Web API 无法序列化拥有外键的数据表,如何解决? RRS feed

  • 问题

  • 大家好:

    我现在有一个Web API项目处理数据库,其中一个数据表和其他表有外键关系,用EF生成的对应的数据实体类如下:

        public partial class Motor_SizeOfStepperMotor
        {
            [Key]
            [StringLength(50)]
            public string TypeNo { get; set; }
    
            [Required]
            [StringLength(50)]
            public string Manufacturer { get; set; }
    
            public double? Size_A { get; set; }
    
            public double? Size_B { get; set; }
    
            public double? Size_C { get; set; }
    
            public double? Size_D { get; set; }
    
            public double? Size_F { get; set; }
    
            public double? Size_G { get; set; }
    
            public virtual Motor_ParaOfStepperMotor Motor_ParaOfStepperMotor { get; set; }
        }

    实体类的最后一个属性对应的是外键。由于这个属性的存在,我无法序列化这个数据实体类,所以请求这个数据的API都会有问题。

    我又不想在数据库中去掉这个外键关系,请问该怎么解决。

    2016年5月24日 11:50

全部回复

  • 你好,

    请问你能提供一些详细信息吗(错误信息,错误重现的方法,日志...)?EF带有导航属性的也都能序列化的。

    Regards,

    Moonlight


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2016年5月25日 5:28
  • 你好,

    请求API时发回的错误为:

    <Error>
    <Message>出现错误。</Message>
    <ExceptionMessage>
    “ObjectContent`1”类型未能序列化内容类型“application/xml; charset=utf-8”的响应正文。
    </ExceptionMessage>
    <ExceptionType>System.InvalidOperationException</ExceptionType>
    <StackTrace/>
    <InnerException>
    <Message>出现错误。</Message>
    <ExceptionMessage>
    数据协定名称为“Motor_SizeOfElectric_AFE671C27AD0290AD5FC5C649C1C915D4C70120C9332C5D1997ACD4A960603D7:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies”的类型“System.Data.Entity.DynamicProxies.Motor_SizeOfElectric_AFE671C27AD0290AD5FC5C649C1C915D4C70120C9332C5D1997ACD4A960603D7”不是所需的类型。请考虑使用 DataContractResolver(如果你正在使用 DataContractSerializer),或将任何未知类型以静态方式添加到已知类型的列表。例如,可以使用 KnownTypeAttribute 属性,或者将未知类型添加到传递给序列化程序的已知类型列表。
    </ExceptionMessage>
    <ExceptionType>
    System.Runtime.Serialization.SerializationException
    </ExceptionType>
    <StackTrace>
    在 System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) 在 System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) 在 System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) 在 WriteArrayOfMotor_SizeOfElectricSpindleToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) 在 System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) 在 System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) 在 System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) 在 System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) 在 System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) 在 System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) 在 System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) 在 System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) 在 System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- 引发异常的上一位置中堆栈跟踪的末尾 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
    </StackTrace>
    </InnerException>
    </Error>

    请求的API方法是:

            // GET: api/SizeOfStepperMotor
            public IQueryable<Motor_SizeOfStepperMotor> GetMotor_SizeOfStepperMotor()
            {
                return db.Motor_SizeOfStepperMotor;
            }

    其他没有导航属性的实体类数据都是可以正确的序列化的,但只要有导航属性就会出错。

    我是用codefirst from database创建实体的


    • 已编辑 Bill Gu 2016年5月25日 6:12
    2016年5月25日 6:10
  • 会不会是外键类型缺少序列化属性

    [Serializable()]

    class Motor_ParaOfStepperMotor

    {

    }


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年5月26日 0:10
  • 你好,

    根据你的错误信息,似乎你是序列化成XML 格式的信息。请做要序列化的实体类上加上[DataContract] [DataMember]

    [DataContract]
    public partial class Motor_SizeOfStepperMotor
        {
            [Key]
            [StringLength(50)]
            public string TypeNo { get; set; }
    
            [Required]
            [StringLength(50)]
            public string Manufacturer { get; set; }
    
            public double? Size_A { get; set; }
    
            public double? Size_B { get; set; }
    
            public double? Size_C { get; set; }
    
            public double? Size_D { get; set; }
    
            public double? Size_F { get; set; }
    
            public double? Size_G { get; set; }
    
            [DataMember]
            public virtual Motor_ParaOfStepperMotor Motor_ParaOfStepperMotor { get; set; }
        }

    Best regards,

    Cole Wu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年5月26日 8:42
  • 你好:

      添加特性之后仍然报之前的错误:

    数据协定名称为“ElecSpindleSize_AC443F5612306AEF7969B9BE62EEE27D56D483293895A35961705C5ACD36DFD4:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies”的类型“System.Data.Entity.DynamicProxies.ElecSpindleSize_AC443F5612306AEF7969B9BE62EEE27D56D483293895A35961705C5ACD36DFD4”不是所需的类型。请考虑使用 DataContractResolver(如果你正在使用 DataContractSerializer),或将任何未知类型以静态方式添加到已知类型的列表。例如,可以使用 KnownTypeAttribute 属性,或者将未知类型添加到传递给序列化程序的已知类型列表。

    2016年6月23日 6:56
  • 兄弟,搞定了吗,同样的问题
    2017年5月31日 9:04