0
votes

I found my mistake. I use NHibernate lazy loading. And serializer can't serialize RoleProxy.

How to get object with Dictionary field from WCF service? When i try to do it, i get this exception:

The underlying connection was closed: The connection was closed unexpectedly.

Stack trace:

Server stack trace: at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at UserManagmentStudio.DataService.IDataService.GetUser() at UserManagmentStudio.DataService.DataServiceClient.GetUser() in C:\Users\d.kolpakov\documents\visual studio 2010\Projects\UserManagmentStudio\UserManagmentStudio\Service References\DataService\Reference.cs:line 64 at UserManagmentStudio.Controllers.UsersController.Index(UserFilter filter, String dataType) in C:\Users\d.kolpakov\documents\visual studio 2010\Projects\UserManagmentStudio\UserManagmentStudio\Controllers\UsersController.cs:line 29 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.<>c_DisplayClass15.b_12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)

Service interface:

  [ServiceContract]
    public interface IDataService
    {
        [OperationContract]
        User GetUser();
    }

User.cs:

   [DataContract(IsReference = true)]
    public class User : IValidatableObject
    {
        [DataMember]
        private readonly IDictionary<Role,AccessLevel> roles = new Dictionary<Role,AccessLevel>();

        public virtual IDictionary<Role,AccessLevel> Roles
        {
            get { return roles; }
        }

.....

    }

Role.cs:

[DataContract(IsReference = true)]


       public class Role
        {
    private readonly IDictionary<User, AccessLevel> users = new Dictionary<User, AccessLevel>();

            [DataMember]
            public virtual Int32 Id { get; set; }

            [DataMember]
            public virtual String Name { get; set; }

            public virtual IDictionary<User,AccessLevel> Users
            {
                get { return users; }
            }
    }

AccessLevel.cs:

   [DataContract(IsReference = true)]
    public class AccessLevel
    {
        [DataMember]
        public virtual Int32 Id { get; set; }

        [DataMember]
        public virtual String Value { get; set; }
    }
3

3 Answers

3
votes

Try changing the IDictionary to a read-write Dictionary property. In a data contract you have to specify an implementation, otherwise the deserializer doesn't know how to construct the object, I think

1
votes
[DataContract]
    public class User : IValidatableObject
    {
        [DataMember]
        public Dictionary<Role,AccessLevel> Roles
        {
            get; set;
        }
    }

[DataContract]       
public class Role
     {           
        [DataMember]
        public Int32 Id { get; set; }

        [DataMember]
        public String Name { get; set; }

        [DataMember]
        public Dictionary<User,AccessLevel> Users
        {
           get;set;
       }
}
0
votes

Read-only variables can not be passed to/form a service, as they are not serializable. so you should add a set for User.Roles property.