2012-02-27 5 views
1

ASP.NET WebサイトからWCFサービスを呼び出すと、次の例外が発生します。どうやって克服できますか?WCFインターフェイスオブジェクトのリストを返すときの例外

注:サービスプロジェクトでブレークポイントを適用することによって、サービスが2つの有効なオブジェクトを返すことを確認しました。

注:サービスでは、IBankAccountのリストを撤回しています。 [OperationContract] List<IBankAccount> GetDataUsingDataContract(int userId); IBankAccountはインターフェイスです。

「例外が発生しました。接続が閉じられました:接続が予期せず閉じられました」という例外があります。詳細なスタックトレースは、次の図で使用できます。

enter image description here

//サイト

using System; 
using ServiceReference1; 
public partial class _Default : System.Web.UI.Page 
{ 
protected void Page_Load(object sender, EventArgs e) 
{ 

    Service1Client client = new Service1Client(); 

    string result = client.GetData(1); 
    Response.Write(result); 


    client.GetDataUsingDataContract(1); 
    int d = 0; 

} 
} 

//サービスインタフェース

using System.Collections.Generic; 
using System.ServiceModel; 
using DTOProject; 
namespace MyServiceApp 
{ 
[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    string GetData(int value); 

    [OperationContract] 
    List<IBankAccount> GetDataUsingDataContract(int userId); 

} 

} 

// DTO //サービス実装

using System.Runtime.Serialization; 
namespace DTOProject 
{ 
public interface IBankAccount 
{ 
    int Duration { get; set; } 
    int AmountDeposited { get; set; } 
} 
} 

using System.Runtime.Serialization; 
namespace DTOProject 
{ 
[DataContract] 
public class FixedAccount : IBankAccount 
{ 
    [DataMember] 
    public int Duration { get; set; } 

    [DataMember] 
    public int AmountDeposited { get; set; } 
} 
} 

using System.Runtime.Serialization; 
namespace DTOProject 
{ 
[DataContract] 
public class SavingsAccount : IBankAccount 
{ 
    [DataMember] 
    public int Duration { get; set; } 

    [DataMember] 
    public int AmountDeposited { get; set; } 
} 
} 

using System.Collections.Generic; 
using DTOProject; 
using BusinessLayer; 

namespace MyServiceApp 
{ 
public class Service1 : IService1 
{ 
    public string GetData(int value) 
    { 
     return string.Format("You entered: {0}", value); 
    } 
    public List<IBankAccount> GetDataUsingDataContract(int userId) 
    { 
     BusinessLayer.AccountManager accManager = new AccountManager(); 
     List<IBankAccount> accounts = accManager.GetAllAccountsForUser(userId); 
     return accounts; 
    } 

} 
} 

//ビジネス・レイヤー

using System.Collections.Generic; 
using DTOProject; 
using DataAccessLayer; 
namespace BusinessLayer 
{ 
public class AccountManager 
{ 
    public List<IBankAccount> GetAllAccountsForUser(int userID) 
    { 
     DataAccessLayer.AccounutManagerDAL accountManager = new AccounutManagerDAL(); 
     List<IBankAccount> accountList = accountManager.GetAllAccountsForUser(userID); 
     return accountList; 
    } 

} 
} 

//データアクセスレイヤ

using System; 
using System.Collections.Generic; 
using DTOProject; 
namespace DataAccessLayer 
{ 

public class DatabaseRecordSimulation 
{ 
    public string AccountType { get; set; } 
    public int Duration { get; set; } 
    public int DepositedAmount { get; set; } 
} 

public class AccounutManagerDAL 
{ 

    List<DatabaseRecordSimulation> dbRecords = new List<DatabaseRecordSimulation>() 
    { 
     new DatabaseRecordSimulation{AccountType="Savings",Duration=6,DepositedAmount=50000}, 
     new DatabaseRecordSimulation{AccountType="Fixed",Duration=6,DepositedAmount=50000} 
    }; 

    public List<IBankAccount> GetAllAccountsForUser(int userID) 
    { 

     List<IBankAccount> accountList = new List<IBankAccount>(); 
     foreach (DatabaseRecordSimulation dbRecrod in dbRecords) 
     { 
      IBankAccount acc = AccountFactory.GetAccount(dbRecrod); 
      accountList.Add(acc); 
     } 
     return accountList; 
    } 

} 

public static class AccountFactory 
{ 
    public static IBankAccount GetAccount(DatabaseRecordSimulation dbRecord) 
    { 
     IBankAccount theAccount = null; 
     if (String.Equals(dbRecord.AccountType, "Fixed")) 
     { 
      theAccount = new FixedAccount(); 
     } 
     if (String.Equals(dbRecord.AccountType, "Savings")) 
     { 
      theAccount = new SavingsAccount(); 
     } 
     return theAccount; 

    } 
} 
} 

READING:この記事を1として

答えて

4

http://social.msdn.microsoft.com/Forums/eu/wcf/thread/31102bd8-0a1a-44f8-b183-62926390b3c3 あなたがすることはできませんインタフェースを返す - あなたはクラスを返す必要があります。ただし、抽象基本タイプ - BankAccountを作成し、KnownType属性を適用することができます。たとえば:

[DataContract] 
[KnowType(typeof(FixedAccount))] 
[KnowType(typeof(SavingsAccount))] 
abstract class BankAccount { ... } 

[DataContract] 
class FixedAccount : BankAccount { ... } 

[DataContract] 
class SavingsAccount : BankAccount { ... } 

KnownType属性みましょうWCFは、明示的にサービス契約で参照されていない他のいくつかのタイプは、契約の一部となることを知っています。

+0

これは、スタックトレースを見ている間は、問題とは何も関係していません。送信例外は、シリアル化では赤いニシンで、何か変わっているようです機構。あなたはあなたの答えにこれを考慮に入れましたか?この場合、それは理にかなってupvoteを得る - しかし、私はあなたが答えで無作為に撃っているオフチャンスを判断している。 –

+0

@TomW通常、このような例外は、シリアル化が失敗した場合に発生します。私は何度も同じような例外があります。 – Coder

+1

私は多くのことを想像していました。初心者は、接続の問題であり、根底にある障害を逃している可能性が高いので、この答えは注目に値する。 –

関連する問題