Avatar of askasp
askasp
 asked on

ASP.NET SOAP response - class/property access

I have created a service reference for a soap wsdl and trying to work with the generated proxy classes. This is what I have so far. Just pasting snippets as an example

reference.cs file
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace=".....")]
    public partial class PER_NAME : object, System.ComponentModel.INotifyPropertyChanged {

    private string nAMEField;

      /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order=5)]
        public string NAME {
            get {
                return this.nAMEField;
            }
            set {
                this.nAMEField = value;
                this.RaisePropertyChanged("NAME");
            }
        }
    }

Open in new window


Client Code
ServiceReference1.Service_PortTypeClient serv = new ServiceReference1.Service_PortTypeClient();

serv.ClientCredentials.UserName.UserName = "....";
serv.ClientCredentials.UserName.Password = ".....";

ServiceReference1.ServiceRequest req = new ServiceReference1.ServiceRequest ();

req.ID= "...";
req.OPERATION = "....";

ServiceReference1.ServiceResponse person = new ServiceReference1.ServiceResponse ();
person = serv.GetMethod(req);

Open in new window


When I intercept the response and load it into an xml document I can see the response but I couldn't figure out how to access to the objects through generated proxy classes. How can I get the value of NAME after receiving the response?

I keep getting System.NullReferenceException probably because I am not initiating and assigning them correctly. Finally below is the generated xsd.  I also attached the structure of xsd if it helps

<xs:element cust:entityName="Names" name="PER_NAME">
    <xs:annotation>
      <xs:documentation xml:lang="en">Names - Names</xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element cust:label="Name" minOccurs="0" maxOccurs="1" name="NAME">
          <xs:annotation>
            <xs:documentation xml:lang="en"> Name, Name </xs:documentation>
          </xs:annotation>
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:maxLength value="50" />
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
    </xs:complexType>
</xs:element>

Open in new window

xml.png
ASP.NETWCF.NET Programming

Avatar of undefined
Last Comment
askasp

8/22/2022 - Mon
Bob Learned

All that is confusing, so let's narrow down the scope.  Are you trying to get a property value from "person" in this block:

ServiceReference1.ServiceResponse person = new ServiceReference1.ServiceResponse ();
person = serv.GetMethod(req);

Open in new window

askasp

ASKER
Yeah actually I am also confused here and getting frustrated since I have been working on this for a while now. Thank you for the follow-up, I hope we can get this to work because I am not even sure where to start troubleshooting this since this is my first time working with webservices.

If you look at the attachment earlier, you will see CONSTITUENT > PER_NAMES > PER_NAME > NAME. What I am trying to get is the "NAME" attribute. The rest works in the similar way so I should be able to apply the same solution.

Again as you can see in the attachment "CONSTITUENT" has direct attributes "EMPLID, BIRTHDATE, etc.." and I can get those back with person.EMPLID = .... in the code block you mentioned.

After specifiying  person = serv.GetMethod(req); if I intercept the response , I can get all the attributes of all the classes as an xml, and then I can read through nodes to get the values but that is what I am trying to avoid and I want to use the serialized objects instead.

So, in other words how can I get
ServiceReference1.PER_NAME personname = new ServiceReference1.PER_NAME();
.... and get the personname.NAME = ?

Open in new window


I didn't want to include all the files since they are long but let me know if you think that would be helpful
Bob Learned

If I understand correctly, I would guess that you could do something like this:

foreach (var perName in person.PER_NAMES)
{
    string name = perName.PER_NAME.NAME;
}

Open in new window

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
askasp

ASKER
I tried that before, I get the ServiceReference1.PER_NAME' could be found (are you missing a using directive or an assembly reference?) error because this is how it is defined in the reference.cs file..
public partial class CONSTITUENT : object, System.ComponentModel.INotifyPropertyChanged {
   private PER_NAME[] pER_NAMESField;
}

public partial class PER_NAME : object, System.ComponentModel.INotifyPropertyChanged {
   private string nAMEField;

   [System.Xml.Serialization.XmlElementAttribute(Order=5)]
      public string NAME {
         get {
                return this.nAMEField;
             }
         set {
                this.nAMEField = value;
                this.RaisePropertyChanged("NAME");
             }
        }
}

Open in new window

So I can't access to it directly like that
Bob Learned

Can you show me how you get to CONSTITUENT (which appears to work)?
askasp

ASKER
person = serv.GetMethod(req);
string id = person.EMPLID;

Open in new window

This gives me the CONSTITUENT > EMPLID
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
Do you think giving you the generated proxy file help? I just didn't want to expose to the internet..
Bob Learned

There is a better way to look at a web service, which uses a web browser to look at the contract by entering the web reference as the URL.

Example:

http://webgis.usc.edu/Services/Geocode/WebService/GeocoderService_V03_01.asmx

Web service contract shown in the web browser
You can select each web method, to get specific information about the method.
Bob Learned

I can't quite get a good understanding of the contract, so I am taking pot shots in the dark.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
askasp

ASKER
Yeah you mean by pasting the wsdl in the url, but not sure what you wanted me to do?
I know that is why I asked if providing the files might help
Bob Learned

I don't need the WSDL, I need the contract, since it is easier to understand.  That is what I showed in the example.

If you look at the contract in the browser, select the GetMethod, and attach a screen shot, then I can see how that works.  

Are you supposed to get PER_NAMES with GetMethod, along with CONSTITUENT?  That is the question I am trying to answer for myself.
askasp

ASKER
Okay, let me step back a little bit.

 - When I added the service reference, I did not checked "Always generate message contracts" , is that what you are referring to? so I am not sure if I see the contract

 - In the example you showed me, what is the contract? Service description or list of methods as it was shown in the url.. I guess I am having issues understanding the terminology since it is my first time implementing this and learning the process along the way

I attached the actual method in the service description
ScreenShot016.png
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
This is going to make more sense now, and this is where I get stuck
ServiceReference1.CU_ENTITY_CONSTITUENT_PortTypeClient serv = new ServiceReference1.CU_ENTITY_CONSTITUENT_PortTypeClient();
ServiceReference1.CU_CONSTITUENT_REQUEST req = new ServiceReference1.CU_CONSTITUENT_REQUEST();

ServiceReference1.CONSTITUENT person = new ServiceReference1.CONSTITUENT();
person = serv.CU_ENTITY_CONSTITUENT_GET(req);

Open in new window

Bob Learned

The term "contract" relates to the objects, properties and methods that are available through the web service.  This is a term that is commonly used with WCF web services, but is not limited to that type of web service.  

A classic ASP.NET .asmx web service has an implied contract, and WCF has an explicit contract (data contract for objects and properties, and operation contract for methods).

The screen shot that you showed is the operation contract, since it shows a single operation (CU_ENTITY_CONSTITUENT_GET).  The data contract would be the objects and properties exposed by the web service.  You are asking about how to work with the data contract, which I can't see.

The steps that I described are for the web browser, not anything in the .NET IDE.
askasp

ASKER
Okay, bear with me. I am trying to hit to a 3rd party service so I don't have control over the webservice itself. I understand what you described are nothing in the .net ide.

I have given an ?wsdl url and then through "Add Service Reference.." in vs I added the webservice ("Always generate message contracts" not checked like I mentioned earlier). Reference.cs , CU_CONSTITUENT.wsdl, CU_CONSTITUENT_CANNONICAL.xsd and CU_CONSTITUENT_CANNONICAL_REQUEST.xsd are being generated.

and in the reference.cs file I have
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(Namespace="http://www.cu.edu/cannonical/CU_CONSTITUENT/", ConfigurationName="ServiceReference1.CU_ENTITY_CONSTITUENT_PortType")]
    public interface CU_ENTITY_CONSTITUENT_PortType {
        
        // CODEGEN: Generating message contract since the operation CU_ENTITY_CONSTITUENT_GET is neither RPC nor document wrapped.
        [System.ServiceModel.OperationContractAttribute(Action="CU_ENTITY_CONSTITUENT_GET.v1", ReplyAction="*")]
        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(PER_NAME[]))]
}

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.cu.edu/cannonical/CU_CONSTITUENT/")]
    public partial class PER_NAME : object, System.ComponentModel.INotifyPropertyChanged {

        private string nAMEField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order=5)]
        public string NAME {
            get {
                return this.nAMEField;
            }
            set {
                this.nAMEField = value;
                this.RaisePropertyChanged("NAME");
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.cu.edu/cannonical/CU_CONSTITUENT/")]
    public partial class CONSTITUENT : object, System.ComponentModel.INotifyPropertyChanged {
        private PER_NAME[] pER_NAMESField;

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayAttribute(Order=8)]
        [System.Xml.Serialization.XmlArrayItemAttribute("PER_NAME", IsNullable=false)]
        public PER_NAME[] PER_NAMES {
            get {
                return this.pER_NAMESField;
            }
            set {
                this.pER_NAMESField = value;
                this.RaisePropertyChanged("PER_NAMES");
            }
        }
    }
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    [System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
    public partial class CU_CONSTITUENT_CANNONICAL_REQUEST1 {
        
        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.cu.edu/cannonical/CU_CONSTITUENT/", Order=0)]
        public ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_REQUEST CU_CONSTITUENT_REQUEST;
        
        public CU_CONSTITUENT_CANNONICAL_REQUEST1() {
        }
        
        public CU_CONSTITUENT_CANNONICAL_REQUEST1(ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_REQUEST CU_CONSTITUENT_REQUEST) {
            this.CU_CONSTITUENT_REQUEST = CU_CONSTITUENT_REQUEST;
        }
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    [System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
    public partial class CU_CONSTITUENT_CANNONICAL1 {
        
        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.cu.edu/cannonical/CU_CONSTITUENT/", Order=0)]
        public ISISWebserviceNew.ServiceReference1.CONSTITUENT CONSTITUENT;
        
        public CU_CONSTITUENT_CANNONICAL1() {
        }
        
        public CU_CONSTITUENT_CANNONICAL1(ISISWebserviceNew.ServiceReference1.CONSTITUENT CONSTITUENT) {
            this.CONSTITUENT = CONSTITUENT;
        }
    }
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public interface CU_ENTITY_CONSTITUENT_PortTypeChannel : ISISWebserviceNew.ServiceReference1.CU_ENTITY_CONSTITUENT_PortType, System.ServiceModel.IClientChannel {
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public partial class CU_ENTITY_CONSTITUENT_PortTypeClient : System.ServiceModel.ClientBase<ISISWebserviceNew.ServiceReference1.CU_ENTITY_CONSTITUENT_PortType>, ISISWebserviceNew.ServiceReference1.CU_ENTITY_CONSTITUENT_PortType {

        ////to intercept the response to get the xml
        ////add member variable to access the raw message through MyBehavior getCustomBehavior()
        //private MyBehavior b;
        //public MyBehavior getCustomBehavior() { return b; }

        public CU_ENTITY_CONSTITUENT_PortTypeClient() {

            ////create the MyBehavior object
            //b = new MyBehavior();
            ////add MyBehavior to the service contract
            //this.Endpoint.Behaviors.Add(b);
        }
        
        public CU_ENTITY_CONSTITUENT_PortTypeClient(string endpointConfigurationName) : 
                base(endpointConfigurationName) {
        }
        
        public CU_ENTITY_CONSTITUENT_PortTypeClient(string endpointConfigurationName, string remoteAddress) : 
                base(endpointConfigurationName, remoteAddress) {
        }
        
        public CU_ENTITY_CONSTITUENT_PortTypeClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(endpointConfigurationName, remoteAddress) {
        }
        
        public CU_ENTITY_CONSTITUENT_PortTypeClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(binding, remoteAddress) {
        }
        
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
        ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_CANNONICAL1 ISISWebserviceNew.ServiceReference1.CU_ENTITY_CONSTITUENT_PortType.CU_ENTITY_CONSTITUENT_GET(ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_CANNONICAL_REQUEST1 request) {
            return base.Channel.CU_ENTITY_CONSTITUENT_GET(request);
        }
        
        public ISISWebserviceNew.ServiceReference1.CONSTITUENT CU_ENTITY_CONSTITUENT_GET(ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_REQUEST CU_CONSTITUENT_REQUEST) {
            ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_CANNONICAL_REQUEST1 inValue = new ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_CANNONICAL_REQUEST1();
            inValue.CU_CONSTITUENT_REQUEST = CU_CONSTITUENT_REQUEST;
            ISISWebserviceNew.ServiceReference1.CU_CONSTITUENT_CANNONICAL1 retVal = ((ISISWebserviceNew.ServiceReference1.CU_ENTITY_CONSTITUENT_PortType)(this)).CU_ENTITY_CONSTITUENT_GET(inValue);
            return retVal.CONSTITUENT;
        }
    }

Open in new window


But as far as "Data contract" I don't have anything like what is defined in http://www.dotnetfunda.com/interview/exam286-what-are-contracts-in-wcf.aspx, so is that because that checkbox was not checked? or because it is not defined by the service and I have to define it or the snippet I provided in the reference file displays that?

Thank you again for your time and patience
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Bob Learned

With the web browser method, remove the ?WSDL from the URL, and attach that screen shot, if it works.
askasp

ASKER
Is there anyway I can pass username and password with that web browser method
http://url?op=CU_ENTITY_CONSTITUENT_GET since it is behind a firewall or any way I can see it through IDE?
Bob Learned

That all depends on the web service.  Let's take a look at the GeoCoder service from the example above:

http://webgis.usc.edu/Services/Geocode/WebService/GeocoderService_V03_01.asmx

The web method GeocodeAddressNonParsed is:

http://webgis.usc.edu/Services/Geocode/WebService/GeocoderService_V03_01.asmx?op=GeocodeAddressNonParsed

If you navigate to the web method URL in the web browser, you should see different sections (Test, SOAP 1.1, SOAP 1.2, HTTP GET, and HTTP POST), which allow you to test, and show you how requests need to be formatted for each type of request method allowed.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
I used SOAPUI to test the webservice (SOAP 1.1) since I can pass credentials there and I am able to get what I need as an xml in the response package, but I am having troubles when it comes to .net side to be able to access these properties through generated classes/objects.

In the above code if you look at the bottom under
public partial class CU_ENTITY_CONSTITUENT_PortTypeClient.... and public CU_ENTITY_CONSTITUENT_PortTypeClient()....  you will see

////to intercept the response to get the xml

That is where I also tried to debug in .net and intercepted the response after doing something like this in the code
person = serv.CU_ENTITY_CONSTITUENT_GET(req);
string xml_soap = serv.getCustomBehavior().getMyInspector().getMessage();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml_soap);

Open in new window

and then set a breakpoint at xmlDoc.LoadXml(xml_soap); , looked at xml_soap in xmlvisualizer . The result is same with the SOAPUI. I just don't know how to access these through objects in .net to make it more efficient instead of reading XPATH to read the nodes in the response. Does it all make sense?
Bob Learned

We are going back and forth, and what I am trying to explain is that I don't understand your "contract", so I can't suggest anything without understanding that.  I don't see how PER_NAMES fits into the big picture.

I tried to show you a way to show me your contract, but it sounds like you might not be able to do that with your web browser and the web service.
askasp

ASKER
Would this help since on that website I see how request and response should be structured under different methods? Below is taken from SOAPUI
Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cu="http://www.cu.edu/cannonical/CU_CONSTITUENT/">
   <soapenv:Header/>
   <soapenv:Body>
      <cu:CU_CONSTITUENT_REQUEST>
         <cu:EMPLID>value taken out</cu:EMPLID>
         <cu:OPERATION>value taken out</cu:OPERATION>
      </cu:CU_CONSTITUENT_REQUEST>
   </soapenv:Body>
</soapenv:Envelope>
Response
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <cu:CONSTITUENT xmlns:cu="http://www.cu.edu/cannonical/CU_CONSTITUENT/">
         <cu:EMPLID>value taken out</cu:EMPLID>
         <cu:BIRTHDATE>value taken out</cu:BIRTHDATE>
         <cu:BIRTHPLACE/>
         <cu:BIRTHCOUNTRY>
            <cu:COUNTRY/>
         </cu:BIRTHCOUNTRY>
         <cu:BIRTHSTATE/>
         <cu:DT_OF_DEATH/>
         <cu:PER_NAMES>
            <cu:PER_NAME>
               <cu:EMPLID>value taken out</cu:EMPLID>
               <cu:NAME_TYPE>value taken out</cu:NAME_TYPE>
               <cu:COUNTRY_NM_FORMAT>value taken out</cu:COUNTRY_NM_FORMAT>
               <cu:EFFDT>value taken out</cu:EFFDT>
               <cu:NAME>value taken out</cu:NAME>
               <cu:EFF_STATUS>A</cu:EFF_STATUS>
               .....
            </cu:PER_NAME>
            <cu:PER_NAME>
               <cu:EMPLID>value taken out</cu:EMPLID>
               <cu:NAME_TYPE>value taken out</cu:NAME_TYPE>
               <cu:COUNTRY_NM_FORMAT>value taken out</cu:COUNTRY_NM_FORMAT>
               <cu:EFFDT>value taken out</cu:EFFDT>
               <cu:NAME>value taken out</cu:NAME>
               ....
            </cu:PER_NAME>
         </cu:PER_NAMES>
         <cu:EMAIL_ADDRESSES>
            <cu:EMAIL_ADDRESS>
               <cu:EMPLID>value taken out</cu:EMPLID>
               <cu:E_ADDR_TYPE>value taken out</cu:E_ADDR_TYPE>
               <cu:EMAIL_ADDR>value taken out</cu:EMAIL_ADDR>
               <cu:PREF_EMAIL_FLAG>value taken out</cu:PREF_EMAIL_FLAG>
            </cu:EMAIL_ADDRESS>
            <cu:EMAIL_ADDRESS>
               <cu:EMPLID>value taken out</cu:EMPLID>
               <cu:E_ADDR_TYPE>value taken out</cu:E_ADDR_TYPE>
               <cu:EMAIL_ADDR>value taken out</cu:EMAIL_ADDR>
               <cu:PREF_EMAIL_FLAG>value taken out</cu:PREF_EMAIL_FLAG>
            </cu:EMAIL_ADDRESS>
         </cu:EMAIL_ADDRESSES>
         <cu:ACADEMIC_HISTORIES>
            ....
         </cu:ACADEMIC_HISTORIES>
         <cu:ADDRESSES>
            <cu:ADDRESS>
               ....
            </cu:ADDRESS>
            <cu:ADDRESS>
               ....
            </cu:ADDRESS>
         </cu:ADDRESSES>
         ....
      </cu:CONSTITUENT>
   </soapenv:Body>
</soapenv:Envelope>

Open in new window


If not, then I guess I am out of luck at this point..
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
Bob Learned

My friend, you should not be out of luck.  We just needed to find a way see the contract.  Now this is step in the right direction.

This is what I see stripped down to a class definition approximation:

CONSTITUENT
  EMPLID
  BIRTHDATE
  BIRTHPLACE
  BIRTHCOUNTRY
  COUNTRY
  BIRTHSTATE
  DT_OF_DEATH
  PER_NAMES
     PER_NAME
        EMPLID
        NAME_TYPE
        COUNTRY_NM_FORMAT
        EFFDT
        NAME
        EFF_STATUS
     EMAIL_ADDRESSES
        EMAIL_ADDRESS
           EMPLID
           E_ADDR_TYPE
           EMAIL_ADDR
           PREF_EMAIL_FLAG
     ACADEMIC_HISTORIES
     ADDRESSES
        ADDRESS

PER_NAMES should be a member of CONSTITUENT, so you should be able to do this:


ServiceReference1.CU_ENTITY_CONSTITUENT_PortTypeClient serv = new ServiceReference1.CU_ENTITY_CONSTITUENT_PortTypeClient();
ServiceReference1.CU_CONSTITUENT_REQUEST req = new ServiceReference1.CU_CONSTITUENT_REQUEST();

ServiceReference1.CONSTITUENT person = new ServiceReference1.CONSTITUENT();
person = serv.CU_ENTITY_CONSTITUENT_GET(req);

var perNames = person.PER_NAMES;

Open in new window

askasp

ASKER
Thank you for the support and bearing with me through this. I really appreciate it.

I didn't want to include all my trials but I tried what you suggested before as well. So after doing

var perNames = person.PER_NAMES;  

then what because "perNames. " is not giving me the attributes so do I need to initiate the PER_NAMES[]  somehow  just like we did with "ServiceReference1.CONSTITUENT person" and then pass it to access to its objects?
Bob Learned

If it is an array, then you can access the attributes by the index:

var name = person.PER_NAMES[0].NAME;

or

var name = person.PER_NAMES[0].PER_NAME.NAME;
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
It is an array and defined as complex type.

var name = person.PER_NAMES[0].NAME;
Object reference not set to an instance of an object.

var name = person.PER_NAMES[0].PER_NAME.NAME;
ServiceReference1.PER_NAME' could be found (are you missing a using directive or an assembly reference?)

If you look at my response above "https://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_27778078.html#a38149550" to your earlier suggestion , you can see how it is defined in the reference.cs file
Bob Learned

You should get Intellisense from the proxy class that is generated.  I now see that PER_NAME is a private field (pER_NAMESField).

private PER_NAME[] pER_NAMESField;

Is there a public property that references this private field?
askasp

ASKER
If you look at "https://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_27778078.html#a38149958" . That has all the PER_NAME related snippets, and in there I have this
public PER_NAME[] PER_NAMES {
            get {
                return this.pER_NAMESField;
            }
            set {
                this.pER_NAMESField = value;
                this.RaisePropertyChanged("PER_NAMES");
            }
        }

Open in new window

Your help has saved me hundreds of hours of internet surfing.
fblack61
Bob Learned

Now I have a context for that.

It really should be person.PER_NAMES[0], so if you are getting a null reference from that, then that is a problem with the web service call.
askasp

ASKER
Which is the same case for every other element defined as arrays as well
person.PER_NAMES[0].NAME , person.ADDRESSES[0].ADDRESS1 , etc..

can I tweak reference file in a way to access these as a workaround? because like I said earlier I can intercept the response, debug and see the results being populated in .net for all these elements. Also  in the response package I provided before through SOAPUI contains these values as well.

So I am thinking it is the automated serialization issue in .net with the web service call. After all we know how it is defined/structured in the response and we are able to send the request and get the response back - just not through objects..any way to customize? write a class to handle this once we get the response to iterate through xml attributes through .net objects/classes?
Bob Learned

1) Do you know what type of web service that you are working with?

2) Does the URL for the web service end with .asmx, .svc, or something else?
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
1) It is SOAP 1.1 unless you mean something else by "type"
2) Url ends with wsdl -  https://url?wsdl
Bob Learned

1) SOAP 1.1 is the protocol format, not the web service type.  WCF uses the .svc extension, WCF REST uses no extension, and ASP.NET classic web service uses .asmx.  Other types of web services, that are not .NET may have other extensions.

2) ?wsdl is a query string argument that returns the WSDL from the web service.  The URL is the part without the query string argument.

Examples:

Return the web service definition:

http://webgis.usc.edu/Services/Geocode/WebService/GeocoderService_V03_01.asmx?wsdl

Web service URL:

http://webgis.usc.edu/Services/Geocode/WebService/GeocoderService_V03_01.asmx

This one has an .asmx extension, which indicates an ASP.NET classic web service.
askasp

ASKER
It is an oracle/peoplesoft based web service is all I know at this point. Can you tell from the url what type it is when you go to it or no? I guess I can provide that as well?
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
askasp

ASKER
And back to my previous question, independent from the type of the webservice if I know that I can get a response, would it be feasible to create my own classes based on the response structure? as a workaround
Bob Learned

It is difficult to suggest anything, without really knowing what you are working with.  The documentation for the web service usually provides the details about what type of web service it is (although not always).

While a SOAP response is XML, I wouldn't suggest going down that route.  It is still an option for you, if that is the only possible solution.  I would investigate the web service as much as possible, before making that decision, though.
askasp

ASKER
Thank you for all your help, even though I couldn't get it to work. I learned a lot. I will try to talk to the server side to see if they can do anything different since we both agreed on person.PER_NAMES[0] , which should work. And my last resort would be iterating through xml for the values I am looking for
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Bob Learned

Is the full URL for the web service proprietary?
askasp

ASKER
I just don't know if it is okay for me to post here before double checking, unless there is another way for me to send you? If not I will double check and post here
Bob Learned

I can wait if you are trying to get approval, but I can't help you without know what type of web service that you are working with.
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
askasp

ASKER
Thank you, and yes I am waiting on approval, which will probably be by mid next week because of the holiday week.
askasp

ASKER
So this is an OSB (oracle service bus) proxy service using doc/literal encoding. I can also provide the full generated proxy as well as the generated xsd file.The attachment and the previous snippets/files might make things more clear for you, if not then let me know what I can provide you to troubleshoot this.

I have a feeling that the generated proxy is not correct but the problem can also be on their side as well, like you said before.

Thank you
sourceConstituentProxyService.xml
Bob Learned

I am not sure that I can help you.  I tried to show you how to access the properties, and it doesn't appear to be working.  If you get XML parsing working, go with that.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
Do you think the auto generated serialization is correct? because that might be the reason why it is not working right?
Bob Learned

I haven't worked with Oracle web services (Constituent Web Service), and it is possible that the proxy class is not generated correctly for those type of web services.
askasp

ASKER
Since I keep getting nullexception, I wanted to double check in Fiddler to see what exactly I am sending and receiving to double check the namespaces and here is what I found out.

Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo58XiXjknqJNiIy274G7tX0AAAAAQunUxaiaRUe5DgZsqwBx/SXH1cON1ttHvw6l1PPQH5AACQAA</VsDebuggerCausalityData>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="_0">
        <u:Created>2012-07-10T16:03:13.395Z</u:Created>
        <u:Expires>2012-07-10T16:08:13.395Z</u:Expires>
      </u:Timestamp>
      <o:UsernameToken u:Id=".....">
        <o:Username>username</o:Username>
        <o:Password>password</o:Password>
      </o:UsernameToken>
    </o:Security>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <CU_CONSTITUENT_REQUEST xmlns="http://www.cu.edu/cannonical/CU_CONSTITUENT/">
      <EMPLID>0000001</EMPLID>
      <OPERATION>FULL</OPERATION>
    </CU_CONSTITUENT_REQUEST>
  </s:Body>
</s:Envelope>

Open in new window

and the response is attached, PER_NAMES is highlighted. So why some of them are tagged with namespaces and some don't? It seems like whenever there is a value then namespace tag is not present but whenever it doesn't have a value then it is tagged with a namespace. Can this be causing the objects to be null, in this case "NAME"? Any thoughts?
ScreenShot017.png
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Bob Learned

If the attached image is the SOAP response, then you are getting the values.  If the proxy is not able to parse out the values, then the fault is with how the proxy is generated.  

One possibility is to attempt to use the legacy Add Web Reference method to add a method to the project, instead of Add Service Reference.

How to: Add a Reference to a Web Service
http://msdn.microsoft.com/en-us/library/bb628649.aspx

1) In Solution Explorer, right-click the name of the project that you want to add the service to, and then click Add Service Reference.

2) In the Add Service Reference dialog box, click the Advanced button.

3) In the Service Reference Settings dialog box, click Add Web Reference.
askasp

ASKER
I have tried the web reference method already before posting the question and the result was the same.

Yes the attached document is the soap response I captured with Fiddler and the values are being populated. The problem has been to parse them out and being able to access these values through proxy auto generated serialized classes and objects.

Below is what I tried and I would appreciate if you can give me feedback on this method as to its advantages/disadvantages or would it be considered a complete hack which might break in the long run (I know updating the reference would recreate the reference.cs file)

 - I saved the response I captured with Fiddler to a local xml file
 - I used xsd.exe tool to create entity classes for xml serialization and deserialization from the exact response I received from the server (attachment)
 - Then I replaced the relative sections in the previous reference.cs file with the new class , which I generated through xsd locally

I was able to get the value by "person.PER_NAMES.PER_NAME.NAME" so it did work.

Few questions:

- This is still better than manually parsing xml or loading the response into an xml document and then iterating through, right ?

- Auto generated "reference.cs" file is basically composed of proxy configuration, request class, response class and all related xml serialization/deserialization (if I am not missing anything). With this method, do I even need the reference.cs file? or should I combine everything in a separate class, pulling the config settings from webconfig and include my custom serialization/deserialization in this class as well to return the objects I need? Because updating the reference will refresh everything in the reference.cs file.

 - Other than ease of use, is there any advantage of using the auto-generated reference.cs file as far as performance or can I do everything manually under one class instead of adding a service reference?

I know this is a loaded question but I am just trying to figure out what is the best way to handle this to implement my own workaround since I don't have control over the server side and for what things I should use reference.cs file and when I should use a custom class?

As always thank you for your support.
Bob Learned

Here is something to think about:

When you using hand-crafted serialization, then you need to address the possibility of breaking changes in the web service response.  Deserialization would need to know the "version" of the response, in order to determine which class/methods to use.  This can be difficult to deal with, since you don't have control over the web service.  How would you know that something has changed, other than unit testing or the application breaks?
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
askasp

ASKER
And the breaking changes you have mentioned can be avoided by "updating the reference" through IDE, correct? to keep it in sync.

The issues I can think of are, the web service being down, definition/field types of fields might change, fields/attributes/nodes might be updated or added, or the structure might change which will break the application.

Even though I do not have the control over how the webservice is being structured/ defined, it will be based on our specific needs - meaning it needs to be discussed and we will know in advance before any changes take place, it will be tested and then go live.

Given the scenario, do you still have the same concern? If not back to my previous question again , what do you think the best way to implement this in a custom/handcrafted  way based on your experience, at what point I should switch from the auto-generated reference.cs file to my custom class? or do I even need to use it at all? or intercept the response through AfterReceiveReply and then pass it to my custom class?
ASKER CERTIFIED SOLUTION
Bob Learned

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
askasp

ASKER
Yeah and that was my only concern, if the response structure comes dynamic based on the ID I send as a request instead of a static response with the exact elements every time, populated vs not populated. I need to ask and double check that with the server side because if it is static then this method would probably be smooth.

I appreciate all your effort and valuable feedback on this. I think we are good for now and I can close the question unless you have any other thoughts/links/example to provide as an example of this type of implementation
Bob Learned

This is so far outside of the normal practice with web services, that the concerns are too vague to enumerate.
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
askasp

ASKER
A quick comment - Part of me still thinks I am not initializing the array classes correctly when I make the call which is kinda similar to the issue here (http://stackoverflow.com/questions/9883024/arrays-in-webservices-object-reference-not-set-to-an-instance-of-an-object) , which in my case correct initialization of PER_NAMES and PER_NAME..
Bob Learned

I didn't think that the arrays were part of the request, but part of the response.  That would be coming from the web service after the call.
askasp

ASKER
Yes that is correct, arrays are part of the response which still needs to be initiated. The layout is like we talked before.
CONSTITUENT
     PER_NAMES
          PER_NAME
                NAME
          PER_NAME
                NAME
     PER_NAMES
     ADDRESSES
          ADDRESS
               ADDRESS1
          ADDRESS
               ADDRESS1
     ADDRESSES
CONSTITUENT

ServiceReference1.CU_ENTITY_CONSTITUENT_PortTypeClient serv = new ServiceReference1.CU_ENTITY_CONSTITUENT_PortTypeClient();
ServiceReference1.CU_CONSTITUENT_REQUEST req = new ServiceReference1.CU_CONSTITUENT_REQUEST();

ServiceReference1.CONSTITUENT person = new ServiceReference1.CONSTITUENT();
person = serv.CU_ENTITY_CONSTITUENT_GET(req);

So person.PER_NAMES[0].NAME or person.ADDRESSES[0].ADDRESS1 -->null as we discussed here - https://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_27778078.html#a38150456

I just think I am not initiating them properly like that link I referenced
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Bob Learned

CU_CONSTITUENT_REQUEST does not have any arrays.  The arrays are part of CONSTITUENT, which you get in the response.  You don't have to initialize anything in the response, since that comes from the call to the web method.
askasp

ASKER
Hmm ok.. Thank you