tags:

views:

30

answers:

2

Hi. I'm a newbie to WCF, trying to perform relatively simple task. I'm trying to return list of objects read from the database but cannot overcome some really annoying exceptions. The question is very simple? What's wrong with the picture?

[ServiceContract]
public interface IDBService
{        
    [OperationContract]
    string Ping(string name);

    [OperationContract]
    InitBDResult InitBD();
}

public InitBDResult InitBD()
        {
            _dc = new CentralDC();
            InitBDResult result = new InitBDResult();
            result.ord = _dc.Orders.First();
            return result;
        }


[DataContract]
    public class InitBDResult
    {
        //[DataMember]
        //public List<Order> Orders { get; set; }

        [DataMember]
        public Order ord { get; set; }
    }
A: 

For WCF issues like this, it's useful to use the Service Trace Logging facility. You have to enable it in your config. Then, perform the action that fails and look at the log. It'll most likely give you detailed exception messages about the problem.

More information on MSDN:

http://msdn.microsoft.com/en-us/library/ms732023.aspx

Drew Noakes
+2  A: 

Based on what you posted:

public InitBDResult InitBD()
{
    _dc = new CentralDC();
    InitBDResult result = new InitBDResult();
    result.ord = _dc.Orders.First();
    return result;
}

Is that method contained in a class that implements the IDBService interface?? That's not quite clear from your post....

[DataContract]
public class InitBDResult
{
        //[DataMember]
        //public List<Order> Orders { get; set; }

        [DataMember]
        public Order ord { get; set; }
}

Is the Order class also marked with [DataContract] and any properties that should be serialized with the [DataMember] attributes??

By default, WCF uses the data contract serializer, and it requires the classes to be returned (all of them) to be marked with [DataContract] and inside those classes, all properties and fields that should be returned in the serialized response to have the [DataMember] attribute.

The [Serializable] attribute doesn't do anything for the default WCF serialization. Read up on WCF serialization in MSDN magazine - highly recommended!

For development, it is often helpful to turn on the exception details from your WCF services, so you get more information about what's gone wrong. To do this, you need to have a service behavior in your config:

 <behaviors>
    <serviceBehaviors>
      <behavior name="debugging">
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>

and then apply that behavior to your service in your config:

<service name="...." behaviorConfiguration="debugging">

Then you'll get the information about details of your exceptions - not just a generic "something went wrong" exception.

marc_s
First of all, thanks for the useful advices.They surely helped a lot.Now to the point of discussion:The Order class is actually a part of the framework generated by the Linq2Sql project and its definition is stored within the data context's designer class. I can't edit the designer code directly but I still must somehow add the [DataMember] Attribute to all properties. Should I declare partial class Order with the property extensions( is that possible at all?)BTW, the [DataContract] attribute before the Order declaration DID the trick regarding the object but not its properties...
Gena Verdel
Yep, just had to turn the Serialization mode on...
Gena Verdel
While deserializing in the data context object, the autonumber id field fails to get updated and remaains with its default value , albeit it's marked with the [DataMember] Attribute.Any thoughts?
Gena Verdel
I'll try to make myself clear:I'm NOT trying to update the autonumber field. Instead the following sequence occurs: Request is sent to the Service;Request is accepted;Entity is retrieved from the database;(it looks perfect with all properties set as they should be)Entity is sent over the Channel(tcp in that case);All properties appear normal but one, which happens to be the ID property.
Gena Verdel
@Gena Verdel: WCF requires its fields to have both a get and set method - my guess is this might not be the case for the ID field, since as it's the autonumbered ID, it shouldn't ever be updated. Maybe it's enough to just set that field's readonly property to false in the Linq-to-SQL designer? Just a guess....
marc_s
In fact there are both get and set methods and readonly property IS set to false...I think the problem is much deeper.All my entity objects are derived from the base class BaseObject which has one property ID. This enables various generics options, etc. The property itself is dummy and baseobject doesn't really store any value. This is achieved by setting override attribute onto ID column of entity class. When I changed the property name in the entity class from ID to ID2 it worked, i.e ID2 was set to its normal values.
Gena Verdel
Is there any way to preserve this model Entity: BaseObject with the ID property in the latter and still enjoy the WCF functionality?
Gena Verdel