Mathias Maes
Mathias Maes

Reputation: 501

Return Entity Framework objects over WCF

We have a problem concerning Entity Framework objects and sending them through WCF. We have a database, and Entity Framework created classes from that database, a 'Wallet' class in this particular situation.

We try to transfer a Wallet using this code:

public Wallet getWallet()
{
    Wallet w = new Wallet();
    w.name = "myname";
    w.walletID = 123;
    return w;
}

We need to transfer that Wallet class, but it won't work, we always encounter the same exception:

"An error occurred while receiving the HTTP response to localhost:8860/ComplementaryCoins.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details."

We searched on the internet, and there is a possibility that the error is due to the need of serialization of Entity Framework-objects.

We have absolutely no idea if this could be the case, and if this is the case, how to solve it. Our DataContract looks like this (very simple):

[DataContract]
public partial class Wallet
{
    [DataMember]
    public int getwalletID { get { return walletID; } }
    [DataMember]
    public string getname { get { return name; } }
}

Does anyone ever encountered this problem?

EDIT: Our Entity Framework created class looks like this:

namespace ComplementaryCoins
{
    using System;
    using System.Collections.Generic;

    public partial class Wallet
    {
        public Wallet()
        {
            this.Transaction = new HashSet<Transaction>();
            this.Transaction1 = new HashSet<Transaction>();
            this.User_Wallet = new HashSet<User_Wallet>();
            this.Wallet_Item = new HashSet<Wallet_Item>();
        }

        public int walletID { get; set; }
        public string name { get; set; }

        public virtual ICollection<Transaction> Transaction { get; set; }
        public virtual ICollection<Transaction> Transaction1 { get; set; }
        public virtual ICollection<User_Wallet> User_Wallet { get; set; }
        public virtual ICollection<Wallet_Item> Wallet_Item { get; set; }
    }
}

Thanks for helping us.

Upvotes: 4

Views: 4111

Answers (3)

Nawed Nabi Zada
Nawed Nabi Zada

Reputation: 2875

I had the same problem some time ago and the solution for this was:

The entity framework was returning a serialized class instead of normal class. eg. Wallet_asfawfklnaewfklawlfkawlfjlwfejlkef instead of Wallet

To solve that you can add this code:

base.Configuration.ProxyCreationEnabled = false;

in your Context file. Since the context file is auto generated you can add it in the Context.tt In the Context.tt file it can be added around lines 55-65:

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
public <#=code.Escape(container)#>()
    : base("name=<#=container.Name#>")
{
base.Configuration.ProxyCreationEnabled = false;
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
    this.Configuration.LazyLoadingEnabled = false;
<#

Upvotes: 16

Yaugen Vlasau
Yaugen Vlasau

Reputation: 2218

Are you trying to recieve a IEnumerable<Wallets>? If - yes, please modify your server class that returns the IEnumerable by adding .ToArray() method

Upvotes: 0

andri
andri

Reputation: 1021

Try specifying a setter for the properties, something like this :

[DataContract]
public partial class Wallet
{
    [DataMember]
    public int getwalletID { get { return walletID; } set { } }
    [DataMember]
    public string getname { get { return name; } set { } }
}

If it still doesn't work, you may consider creating an intermediate POCO class for this purpose, and use mapper library like AutoMapper or ValueInjecter to transfer the data from the EF objects.

The POCO class should have same properties as your EF class :

[DataContract]
public class WalletDTO
{
    [DataMember]
    public int walletID { get; set; }
    [DataMember]
    public string name { get; set; }
}

And modify your method to return this class instead :

public WalletDTO getWallet()
{
    Wallet w = new Wallet(); // or get it from db using EF

    var dto = new WalletDTO();        
    //assuming we are using ValueInjecter, this code below will transfer all matched properties from w to dto
    dto.InjectFrom(w); 
    return dto;
}

Upvotes: 1

Related Questions