1

I have a CibilResponse Class that has properties that are of class type (TUEF class).

I am trying to assign values using : CibilEnquiryEnq.Tuef.Version = "12"; but it throws null reference error. I have already solved this error but through creating an object like : CibilEnquiryEnq.Tuef = new CibilWcfService.TUEF(); and not through constructor.

ICIBIL.cs

[ServiceContract]
public interface ICIBIL
{

    [OperationContract]
    string InsertCibil(CibilResponse cibilResponse);

    [OperationContract]
    string TestInsert(string testObj);

    [OperationContract]
    string GenerateEnquiry(CibilEnquiry testObj);

}

[DataContract]
public class CibilEnquiry
{
    [DataMember]
    public TUEF Tuef { get; set; }
    public CibilEnquiry()
    {
        this.Tuef = new TUEF();           
    }

}


 [DataContract]
    public class TUEF
    {
        [DataMember]
        public string SegmentTag { get; set; }
        [DataMember]
        public string Version { get; set; }
        [DataMember]
        public string MemberReferenceNumber { get; set; }
   }

Application:(not working)

CibilWcfService.CIBIL obj = new CibilWcfService.CIBIL();
CibilWcfService.CibilEnquiry CibilEnquiryEnq = new CibilWcfService.CibilEnquiry();
CibilEnquiryEnq.Tuef.Version = "1111"; // null reference error here and Tuef is null

Application:(working)

CibilWcfService.CIBIL obj = new CibilWcfService.CIBIL();
CibilWcfService.CibilEnquiry CibilEnquiryEnq = new CibilWcfService.CibilEnquiry();
CibilEnquiryEnq.Tuef = new CibilWcfService.TUEF();
CibilEnquiryEnq.Tuef.Version = "1111";//works fine

I don't understand why I have to add CibilEnquiryEnq.Tuef = new CibilWcfService.TUEF(); to make this work. I am already initializing tuef in constructor in my wcf.

I created a sample in a console application (excluded wcf) and it worked fine without having Tuef = new TUEF();, initializing in constructor was enough.

SamuraiJack
  • 5,131
  • 15
  • 89
  • 195

1 Answers1

3

The proxy objects generated by adding a service reference are not the same objects as you are defining in the service contract, they just happen to be created within the same namespace etc under the consuming clients service reference. Basically they are just DTOs that you use to consume the service.

If you want to have strong dependency between the objects then you can not use the service reference and you need to extract the contract to a separate assembly that you can reference.

1) CibilWcfService.Contract - contains the ICIBIL interface + datacontract objects. You need to reference System.ServiceModel, System.ServiceModel.Web and System.Runtime.Serialization for DataContract related attributes.

2) CibilWcfService - This hosts the WCF service and refers the CibilWcfService.Contract assembly.

namespace CibilWcfService
{
    using CibilWcfService.Contract;

    public class CibilService : ICIBIL
    {
        // ... Interface implementation
    }
}

3) CibilClient - This is your consuming client application, it also refers the CibilWcfService.Contract assembly. You create the channel to the service like this, then the new CibilEnquiry() is using the same constructor as defined in your contract. You need to reference System.ServiceModel for ChannelFactory.

using CibilWcfService.Contract;


var cf = new ChannelFactory<ICIBIL>();
var channel = cf.CreateChannel(new EndpointAddress("http://127.0.01/CibilServiceUri"));

if (channel != null)
{
    var CibilEnquiryEnq = new CibilEnquiry();
    CibilEnquiryEnq.Tuef.Version = "1111"; 

    channel.GenerateEnquiry(CibilEnquiryEnq);
}
Janne Matikainen
  • 5,061
  • 15
  • 21
  • GenerateEnquiry method is called later on.. I am assigning value `CibilEnquiryEnq.Tuef.Version = "1111";` in the application not wcf. – SamuraiJack Nov 17 '15 at 09:37
  • You mean you want me to add this piece of code within CibilEnquiry without removing `CibilEnquiry() ` constructor? – SamuraiJack Nov 17 '15 at 09:40
  • Ok, I think I got whats wrong, you are creating the service with service reference, which then creates the necessary classes to your consuming client. This however does not create similar constructor as you have defined in your data contract. You would need to extract the datacontract to a contract assembly which you can refer to both the client and the server and then use channel factory to create the channel to your service. – Janne Matikainen Nov 17 '15 at 10:39
  • And how do I do that? It sounds complicated. Is it? – SamuraiJack Nov 17 '15 at 11:05
  • Updated my answer if you have not yet noticed. – Janne Matikainen Nov 17 '15 at 11:55
  • I am not able to find `CibilWcfService` in intellisense in wcf and there is no `namespace CibilWcfService ` in wcf. However it exists in client – SamuraiJack Nov 20 '15 at 05:37
  • That is the name of your wcf service project, the one where you are currently making the datacontract. – Janne Matikainen Nov 20 '15 at 07:25