2011-08-27 4 views
-1

OK ... 웹에서 살펴본 결과 .Net 4.0 WCF 서비스에서 IEnumerable 형식을 반환 할 수 없다는 두 가지 가능한 솔루션을 발견했습니다.IEnumerable 및 WCF - 아직 다시

아래 링크를 참조하십시오. 이것이 바로 WCF 테스트 클라이언트 도구를 실행하고 메서드를 호출하려고 할 때 얻는 결과입니다.

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

당신이 내 웹 서비스 아무 문제가 없는지 확인하기 위해, 나는 단지 IEnumerable을하지, 하나의 기록이 객체의 유형을 반환 할 수 있어요 마음입니다.

아래에 표시된 두 가지 해결책은 모두 저에게 적합하지 않습니다. 같은 오류가 발생합니다. 이것은 나를 미치게 만든다. 문제가 무엇인지 알고 문제를 회피하기위한 단계를 수행했지만 여전히 동일한 오류가 발생합니다.

어떻게 해결할 수 있습니까?

이것은 내가 시도한 첫 번째 해결책입니다. 이미 암시 되었기 때문에 각 메서드의 마지막 문에서 "ToList"및 "ToArray"를 제거해 보았습니다.

인터페이스

[OperationContract] 
     IList<Priority> GetPriorities(); 

방법

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

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

      CloseConnection(DbContext); 

      return priority.ToList(); 
     } 

이 I 시도 제 2 용액이다

인터페이스

[OperationContract] 
     Priority[] GetPriorities(); 

방법

,
public Priority[] GetPriorities() 

     { 
      YeagerTechEntities DbContext = new YeagerTechEntities(); 

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

      CloseConnection(DbContext); 

      return priority.ToArray(); 
     } 

여기에는 여전히 작동하지 않는 IList 대신 목록이 있습니다.

인터페이스

[OperationContract] 
     List<Priority> GetPriorities(); 

방법 대신 목록의 한 객체를 검색 할 때 아래의 방법은 잘 작동

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

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

      CloseConnection(DbContext); 

      return priority.ToList(); 
     } 

알 수 있습니다.

[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; 
     } 

이 게시물의 첫 번째 방법에 대한 wcf 테스트 클라이언트의 전체 오류 메시지는 다음과 같습니다. 객체 목록을 반환 할 수있는 해결 방법은 무엇입니까?

서비스를 호출하지 못했습니다. 가능한 원인 : 서비스가 오프라인이거나 액세스 할 수 없습니다. 클라이언트 측 구성이 프록시와 일치하지 않습니다. 기존 프록시가 유효하지 않습니다. 자세한 내용은 스택 추적을 참조하십시오. 새 프록시를 시작하거나 기본 구성으로 복원하거나 서비스를 새로 고침하여 복구를 시도 할 수 있습니다.

http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/에 대한 HTTP 응답을받는 동안 오류가 발생했습니다. 이것은 HTTP 프로토콜을 사용하지 않는 서비스 엔드 포인트 바인딩 때문일 수 있습니다. 이것은 HTTP 요청 컨텍스트가 서버에 의해 중단 되었기 때문일 수도 있습니다 (서비스 종료로 인한 것일 수도 있음). 자세한 내용은 서버 로그를 참조하십시오.

서버 스택 추적 : System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException에서 (WebException이 WebException이, HttpWebRequest를 요청, HttpAbortReason abortReason) System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply (시간 범위 제한 시간) 에서 에서 System.ServiceModel.Channels.RequestChannel.Request (메시지 메시지, TimeSpan 시간 제한) (System.ServiceModel.Channels.ClientReliableChannelBinder 1.RequestClientReliableChannelBinder) 1.OnRequest (TRequestChannel 채널, 메시지 메시지, TimeSpan 시간 제한, MaskingMode maskingMode) at System.ServiceModel.Channels. ClientReliableChannelBinder 1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode) at System.ServiceModel.Channels.ClientReliableChannelBinder 1. 요청 (메시지 메시지, TimeSpan 시간 초과)System.ServiceModel.Dispatcher.RequestChannelBinder.Request (메시지 메시지, TimeSpan 시간 초과)에 에서 System.ServiceModel.Security.SecuritySessionClientSettings1.SecurityRequestSessionChannel.Request (메시지 메시지, TimeSpan 시간 초과)에서 System.ServiceModel.Channels.ServiceChannel에 . System.ServiceModel.Channels에서 (System.ServiceModel.Channels.ServiceChannelProxy.InvokeService (IMethodCallMessage methodCall, ProxyOperationRuntime operation)) 에서 호출 (String 동작, Boolean oneway, ProxyOperationRuntime 작업, Object [] 기능, Object [] 출력, TimeSpan 시간 초과) ServiceChannelProxy.Invoke (IMessage 메시지)

[0]에서 예외 재 제기 : at System.Runtime.Remoting.Proxy.RealProxy.HandleReturnMessage YeagerTechWcfServiceClient.GetPriorities에서 IYeagerTechWcfService.GetPriorities에서 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, INT32 타입)에 (iMessage를 reqMsg, iMessage를 retMsg) () ()

내부 예외 : 기본 연결이 닫혔습니다 : 수신시 예기치 않은 오류가 발생했습니다. 전송 연결에서 데이터를 읽을 수 없습니다 : 기존 연결 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply에서 System.Net.HttpWebRequest.GetResponse() (시간 범위 제한 시간)

내부 예외에 원격 호스트에 의해 강제로 닫혔습니다. System.Net.Sockets.NetworkStream.Read (Byte [] 버퍼, Int32 오프셋, Int32 크기)의 System.Net.PooledStream.Read (Byte [] 버퍼, Int32 오프셋, Int32 크기)의 System.Net의 Connection.SyncRead (HttpWebRequest를 요청 부울 userRetrievedStream 부울 probeRead)는

내부 예외 : 기존 연결 강제 System.Net.Sockets.Socket.Receive에서 원격 호스트에 의해 폐쇄 된 (바이트 [] 버퍼 INT32 오프셋 , Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read (Byte [] 버퍼, Int32 오프셋, Int32 크기)

내 클래스를 수정했지만 (아래 참조) 여전히 정확한 오류가 발생합니다.

분명히 Entity Framework에서 개체를 가져 와서 IEnumerable으로 다시 전달하려고 시도한 사람이 있어야합니다. 나는 이것에 매우 좌절하고있다. 제발 도와주세요 ...

내 이전 게시물을 기반으로, 내 수업은 정확히 다음과 같은 변경 사항과 동일합니다. 두 가지 방법론을 시도했습니다.

첫 번째 및 두 번째 시나리오를 별도로 참조하십시오.인터페이스

에 대한

첫 번째 시나리오는 그냥 고객 클래스와 다음의는 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); 

그것은 내 웹 서비스에 의해 참조 동일한 솔루션 (동일한 솔루션의 다른 프로젝트) 내 YeagerTechModel 프로젝트에 있습니다.

고객 객체 인터페이스에 대한

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

} 

두 번째 시나리오에 대한

첫 번째 시나리오 : 고객 개체에 대한

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

두 번째 시나리오

난 그냥 고객 클래스를 사용하여 시도하고 그 다음 IEnumerable 선언은 th의 맨 아래에있다. 수업입니다.

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

} 

내가 시도 : 엔티티 프레임 워크 모델의 일부 고객 객체를 다시 전달하려고 할 때

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

문제는 직렬화 문제가 될 것으로 보인다. 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(); 
     } 
+1

서비스가 실행중인 컴퓨터의 Windows 이벤트 로그를 살펴 보셨습니까? 서비스를 디버그하려고 했습니까? '새로운 목록 (new [] {새로운 우선 순위()});를 반환하려고 했습니까? –

+0

클라이언트가 –

+0

추적을 사용하도록 설정 한 것이 아니라 예외에 대한 서비스를 확인해보고 더 자세한 오류 메시지가 표시됩니다. 내가 포함하도록 원래 게시물을 편집합니다. 그것을 확인하고 알려주십시오 .... – sagesky36

답변

7

대답은 내 EF 호출하기 전에 false로 속성을 설정하는 것만 큼 간단했다 .... 내가 노력하고 여전히 똑같은 오류가 발생하고있는 무슨의 최신 데이터베이스 DbContext.Configuration.ProxyCreationEnabled = false; EF는 자동으로 프록시 클래스를 생성합니다. 동적 프록시 - 그들은 유선상에서 좋게 재생되지 않습니다. - 이것을 끕니다 (ContextOptions.ProxyCreationEnabled == false).

+0

글쎄,이 대답은 프록시를 사용하기를 원한다면 실망 스럽다. – Casey