IEnumerable和WCF - 再次

sag*_*y36 -1 wcf entity-framework-4.1

好的......我已经在网上找到了两个可能的解决方案,解决了我无法在.Net 4.0 WCF服务中返回IEnumerable类型的问题.

见下面的链接.这正是我在执行WCF测试客户端工具并尝试调用方法时所获得的.

https://connect.microsoft.com/wcf/feedback/details/336696/ienumerable-t-serialization-bug

请注意,为了确保我的Web服务没有任何问题,我能够为单个记录返回此对象的类型,而不是IEnumerable.

我尝试过的两种解决方案,如下所示都不适用于我.我犯了同样的错误.这真让我抓狂.我知道问题是什么,遵循规避问题的步骤,但我仍然得到同样的错误.

我该如何解决这个问题?

这是我尝试的第一个解决方案:请注意,我甚至尝试在每个方法的最后一个语句中删除"ToList"和"ToArray",因为它已经隐含了.

接口

[OperationContract]
        IList<Priority> GetPriorities();
Run Code Online (Sandbox Code Playgroud)

方法

public IList<Priority> GetPriorities()
        {
            YeagerTechEntities DbContext = new YeagerTechEntities();

            IList<Priority> priority = DbContext.Priorities.Where(p => p.PriorityID > 0).ToList();

            CloseConnection(DbContext);

            return priority.ToList();
        }
Run Code Online (Sandbox Code Playgroud)

这是我尝试的第二个解决方案:

接口

[OperationContract]
        Priority[] GetPriorities();
Run Code Online (Sandbox Code Playgroud)

方法

public Priority[] GetPriorities()

        {
            YeagerTechEntities DbContext = new YeagerTechEntities();

            Priority[] priority = DbContext.Priorities.Where(p => p.PriorityID > 0).ToArray();

            CloseConnection(DbContext);

            return priority.ToArray();
        }
Run Code Online (Sandbox Code Playgroud)

这是一个List而不是IList仍然无法正常工作.

接口

[OperationContract]
        List<Priority> GetPriorities();
Run Code Online (Sandbox Code Playgroud)

方法

public List<Priority> GetPriorities()
        {
            YeagerTechEntities DbContext = new YeagerTechEntities();

            List<Priority> priority = DbContext.Priorities.Where(p => p.PriorityID > 0).ToList();

            CloseConnection(DbContext);

            return priority.ToList();
        }
Run Code Online (Sandbox Code Playgroud)

请注意,只检索一个对象而不是列表时,以下方法可以正常工作.

[OperationContract]
        Priority GetPriorityID(Int16 priorityid);



public Priority GetPriorityID(Int16 priorityid)
        {
            YeagerTechEntities DbContext = new YeagerTechEntities();

            Priority priority = null;

            var priorityEntity = (from p in DbContext.Priorities
                                  where p.PriorityID == priorityid
                                  select p).FirstOrDefault();

            if (priorityEntity != null)
            {
                priority = new Priority();
                priority.PriorityID = priorityEntity.PriorityID;
                priority.Description = priorityEntity.Description;
                CloseConnection(DbContext);
            }
            else
            {
                CloseConnection(DbContext);
                throw new Exception("Priority " + priorityid + " not found!");
            }

            return priority;
        }
Run Code Online (Sandbox Code Playgroud)

wcf测试客户端对本文第一个方法的整个错误消息如下.为了能够返回对象列表,分辨率是多少?

无法调用该服务.可能的原因:服务离线或无法访问; 客户端配置与代理不匹配; 现有代理无效.有关更多详细信息,请参阅堆栈跟踪.您可以尝试通过启动新代理,还原到默认配置或刷新服务来进行恢复.

接收到http:// localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService /的HTTP响应时发生错误.这可能是由于服务端点绑定不使用HTTP协议.这也可能是由于服务器中止HTTP请求上下文(可能是由于服务关闭).请参阅服务器日志以获取更多详

服务器堆栈跟踪:System.ServiceModel.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException,HttpWebRequest请求,HttpAbortReason abortReason)at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)at System.ServiceModel.Channels.RequestChannel .Request(消息消息,时间跨度超时)在System.ServiceModel.Channels.ClientReliableChannelBinder 1.RequestClientReliableChannelBinder1.OnRequest(TRequestChannel信道,消息的消息,时间跨度超时,maskingMode maskingMode)在System.ServiceModel.Channels.ClientReliableChannelBinder 1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode) at System.ServiceModel.Channels.ClientReliableChannelBinder1.Request(消息消息,时间跨度超时)在System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(消息消息,时间跨度超时)在System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息消息,时间跨度超时)在System.ServiceModel.Channels.ServiceChannel.Call( String action,Boolean oneway,ProxyOperationRuntime oper 通货膨胀,对象[]项,在System.ServiceModel.Channels.ServiceChannelProxy.Invoke对象[]在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage包括MethodCall,ProxyOperationRuntime操作)奏,时间跨度超时)(即时聊天消息)

在异常重新抛出[0]:在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天reqMsg,即时聊天retMsg)在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&MSGDATA,的Int32类型)在IYeagerTechWcfService.GetPriorities( )在YeagerTechWcfServiceClient.GetPriorities()

内部异常:基础连接已关闭:接收时发生意外错误.在System.Net.HttpWebRequest.GetResponse()在System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度超时)

内部异常:无法从传输连接读取数据:远程主机强制关闭现有连接.System.Net.Connection.SyncRead上的System.Net.PooledStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)处的System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小) (HttpWebRequest请求,布尔userRetrievedStream,布尔probeRead)

内部异常:一个现有的连接被强制由远程主机在System.Net.Sockets.Socket.Receive关闭(字节[]缓冲液,的Int32偏移的Int32大小,的SocketFlags的SocketFlags)在System.Net.Sockets.NetworkStream.Read(字节[]缓冲区,Int32偏移量,Int32大小)

我修改了我的类(见下文),但仍然得到了同样的错误.

当然,在他们从Entity Framework获取对象并希望将其作为IEnumerable传回之前,必须有人尝试过此操作.我对此非常沮丧.请帮帮我...

根据我之前的帖子,我的课程与以下更改完全相同.我尝试了两种方法.

请分别参考第一个和第二个场景.

接口的第一种情况

我尝试只使用Customer类,然后使用它的IEnumerable声明.

using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using YeagerTechModel;

namespace YeagerTechWcfService
{
//[ServiceKnownType(typeof(YeagerTechModel.Customer))]
 [ServiceKnownType(typeof(IEnumerable<YeagerTechModel.Customer>))]
 [ServiceContract]
 public interface IYeagerTechWcfService
 {

 [OperationContract]
IEnumerable<Customer> GetCustomers();

 [OperationContract]
 Customer GetCustomerID(Int16 customerid);
Run Code Online (Sandbox Code Playgroud)

它驻留在我的YeagerTechModel项目中,与我的Web服务引用的相同解决方案(同一解决方案中的另一个项目).

Customer对象的第一个场景

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace YeagerTechModel
{
[Serializable]
[DataContract]
 public partial class Customer
 {
 public Customer()
 {
 this.Projects = new HashSet<Project>();
 }

 [DataMember]
 public short CustomerID { get; set; }

 [Required]
 [StringLength(50)]
 [DataType(DataType.EmailAddress)]
 [DataMember]
 public string Email { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string Company { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string FirstName { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string LastName { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string Address1 { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string Address2 { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string City { get; set; }

 [StringLength(2)]
 [DataType(DataType.Text)]
 [DataMember]
 public string State { get; set; }

 [StringLength(10)]
 [DataType(DataType.Text)]
 [RegularExpression(@"^\d{5}(-\d{4})?$")]
 [DataMember]
 public string Zip { get; set; }

 [StringLength(12)]
 [DataType(DataType.PhoneNumber)]
 public string HomePhone { get; set; }

 [StringLength(12)]
 [DataType(DataType.PhoneNumber)]
 [DataMember]
 public string CellPhone { get; set; }

 [StringLength(100)]
 [DataType(DataType.Url)]
 [DataMember]
 public string Website { get; set; }

 [StringLength(50)]
 [DataType(DataType.EmailAddress)]
 [DataMember]
 public string IMAddress { get; set; }

 [DataMember]
 public System.DateTime CreatedDate { get; set; }

 [DataMember]
 public Nullable<System.DateTime> UpdatedDate { get; set; }

 public virtual ICollection<Project> Projects { get; set; }

 }
Run Code Online (Sandbox Code Playgroud)

接口的第二种情况:

using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using YeagerTechModel;

namespace YeagerTechWcfService
{
 [ServiceContract]
 public interface IYeagerTechWcfService
 {

 [OperationContract]
IEnumerable<Customer> GetCustomers();

 [OperationContract]
 Customer GetCustomerID(Int16 customerid);
Run Code Online (Sandbox Code Playgroud)

Customer对象的第二种情况

我尝试过只使用Customer类,然后在这个类的底部使用它的IEnumerable声明.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace YeagerTechModel
{
 [KnownTypeAttribute("KnownTypes")]
 [Serializable]
 [DataContract]
 public partial class Customer
 {
 public Customer()
 {
 this.Projects = new HashSet<Project>();
 }

 [DataMember]
 public short CustomerID { get; set; }

 [Required]
 [StringLength(50)]
 [DataType(DataType.EmailAddress)]
 [DataMember]
 public string Email { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string Company { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string FirstName { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string LastName { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string Address1 { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string Address2 { get; set; }

 [StringLength(50)]
 [DataType(DataType.Text)]
 [DataMember]
 public string City { get; set; }

 [StringLength(2)]
 [DataType(DataType.Text)]
 [DataMember]
 public string State { get; set; }

 [StringLength(10)]
 [DataType(DataType.Text)]
 [RegularExpression(@"^\d{5}(-\d{4})?$")]
 [DataMember]
 public string Zip { get; set; }

 [StringLength(12)]
 [DataType(DataType.PhoneNumber)]
 public string HomePhone { get; set; }

 [StringLength(12)]
 [DataType(DataType.PhoneNumber)]
 [DataMember]
 public string CellPhone { get; set; }

 [StringLength(100)]
 [DataType(DataType.Url)]
 [DataMember]
 public string Website { get; set; }

 [StringLength(50)]
 [DataType(DataType.EmailAddress)]
 [DataMember]
 public string IMAddress { get; set; }

 [DataMember]
 public System.DateTime CreatedDate { get; set; }

 [DataMember]
 public Nullable<System.DateTime> UpdatedDate { get; set; }

 public virtual ICollection<Project> Projects { get; set; }

 static Type[] KnownTypes()
 {
return new Type[] { typeof(IEnumerable<Customer>) };
 }

 }
Run Code Online (Sandbox Code Playgroud)

我试过了:

return customer;
return customer.ToList();
return customer.ToArray();


public IEnumerable<Customer> GetCustomers()
 {
 YeagerTechEntities DbContext = new YeagerTechEntities();

 IEnumerable<Customer> customer = DbContext.Customers.Where(p => p.CustomerID > 0);

 CloseConnection(DbContext);

return customer;
 }
Run Code Online (Sandbox Code Playgroud)

尝试传回作为Entity Framework模型一部分的Customer对象时,问题似乎是序列化问题.必须有一种记录的方法来传回从Entity Framework模型派生的这种类型的对象.

它在哪里????

这是我尝试的最新内容,我仍然得到同样的错误....

namespace YeagerTechWcfService
{
    [ServiceContract]
    public interface IYeagerTechWcfService
    {
        [OperationContract]
        List<Customer> GetCustomers();



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace YeagerTechModel
{
    [Serializable]
    [DataContract]
    public partial class Customer
    {
        public Customer()
        {
            this.Projects = new HashSet<Project>();
        }

        [DataMember]
        public short CustomerID { get; set; }

        [Required]
        [StringLength(50)]
        [DataType(DataType.EmailAddress)]
        [DataMember]
        public string Email { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string Company { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string FirstName { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string LastName { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string Address1 { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string Address2 { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string City { get; set; }

        [StringLength(2)]
        [DataType(DataType.Text)]
        [DataMember]
        public string State { get; set; }

        [StringLength(10)]
        [DataType(DataType.Text)]
        [RegularExpression(@"^\d{5}(-\d{4})?$")]
        [DataMember]
        public string Zip { get; set; }

        [StringLength(12)]
        [DataType(DataType.PhoneNumber)]
        public string HomePhone { get; set; }

        [StringLength(12)]
        [DataType(DataType.PhoneNumber)]
        [DataMember]
        public string CellPhone { get; set; }

        [StringLength(100)]
        [DataType(DataType.Url)]
        [DataMember]
        public string Website { get; set; }

        [StringLength(50)]
        [DataType(DataType.EmailAddress)]
        [DataMember]
        public string IMAddress { get; set; }

        [DataMember]
        public System.DateTime CreatedDate { get; set; }

        [DataMember]
        public Nullable<System.DateTime> UpdatedDate { get; set; }

        public virtual ICollection<Project> Projects { get; set; }
    }


public List<Customer> GetCustomers()
        {
            YeagerTechEntities DbContext = new YeagerTechEntities();

            List<Customer> customer = DbContext.Customers.Where(p => p.CustomerID > 0).ToList();

            return customer.ToList();
        }
Run Code Online (Sandbox Code Playgroud)

sag*_*y36 7

答案就像在对数据库进行EF调用之前将属性设置为false一样简单.DbContext.Configuration.ProxyCreationEnabled = false; EF自动生成代理类.动态代理 - 它们在线路上运行不好 - 关闭它们(ContextOptions.ProxyCreationEnabled == false).