Home All Groups Group Topic Archive Search About

Web Service / Authenticating Proxy .NET and COM interop

Author
9 Feb 2006 2:01 PM
whoareyou
Sorry for the repost - MS requested I do this
Hi,
I have a C# Web Service component I call 2 different ways: 
    - For testing I have a "pure" .NET solution.  A C# test harness app
invokes my C# component.
    - From the "real" application, a native C++ app,  I call the C#
component via COM interop.

My  all .NET test harness has a 407 error returned to it from the web
service component when I don't supply credentials for the proxy server. 
The real app, using COM interop, results in an underlying connection closed
error that I've seen written about many times  Anyone know why the
difference?  this is under framework version 1.1. 

Is the "underlying connection closed" error really only a defect seen when
you go native to managed as in COM interop?

Also, when I test the COM Interop solution under version 2.0 of framework
with invalid credentials (hoping to get the improved proxy handling)  I never
get a response.  The application just hangs.  I can't even cancel the request.

The above is all implemented as asynchronous using the Begin... and End...
semantics.
Thank you

Author
10 Feb 2006 9:35 AM
Peter Huang" [MSFT]
Hi

I think you may try to follow the link below to access a Web Service from
C++.
Walkthrough: Accessing an XML Web Service Using C++
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html
/vbwlkwalkthroughusingwebservicewithunmanagedcode.asp

The code above will use ATL class CSoapSocketClientT to access the Web
Service.
CSoapSocketClientT Class
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/
vclrfCSoapSocketClientT.asp
============================================================================
================================
This class conforms to ATL Server's SOAP client archetype.

Typically this class is used with SPROXY-generated classes which build up
the SOAP messages for you, but it is possible to use this class
independently in the following way:

Create an instance and pass the location of the XML Web service to the
constructor.

Call SetProxy or SetTimeout if necessary.

Call GetWriteStream and write the SOAP message to that stream.

Call SendRequest to send the SOAP message to the server.

If SendRequest succeeded, call GetReadStream to read the SOAP response.

If SendRequest failed, call GetClientError and GetStatusCode, or look at
m_fault for error information.

Call CleanupClient before returning to Step 3 to send further messages.
============================================================================
================================
Here is C++ code snippet to access webservice.
void AccessService(){
    using namespace std;
    Service::CService ws;
    CComBSTR bstr;
    HRESULT hr = ws.HelloWorld(&bstr);
    if (SUCCEEDED(hr))
    {
        CW2A printstr(bstr);
        cout<<"C++"<<endl;
        cout<<printstr<<endl;
    }
    else
    {
        cout<<ws.GetStatusCode()<<endl;
        cout<< "An error occurred: "<<hex<<hr<< endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    if (SUCCEEDED(CoInitialize(NULL))){
        AccessService();
        CoUninitialize();
    }
    return 0;
}

NOTE: we can try to use the ws.GetStatusCode() to get the StatusCode e.g.
401.

If I have any misunderstanding, please feel free to post here.



Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
10 Feb 2006 2:01 PM
whoareyou
I'm not sure that you understand my problem.  This question doesn't concern
the proxy (code) as much as a difference between how the .NET framework runs
the same .NET code via COM interop vs. a pure .NET solution. True I could
have possibly used ATL but we are moving towards .NET.

The difference is only when I need to get past an authenticating proxy
server residing on the network.  Using .NET via COM Interop works fine except
for when an authenticating proxy server is in the mix.  This is  that I have
an issue with - the COM interop solution. 

Why would I get different return values from the same .NET code depending if
it's called via COM interop or pure .NET?

To summarize:

Pure .NET solution - NET test harness (with Authenticating proxy server in
the mix) -> NET Web Service Client (framework 1.1) works fine (receive
response with 407 error)  

Interop solution - COM Interop (with Authenticating proxy server in the mix)
-> different return (underlying connection closed)

Additionally, under 2.0 framework
COM Interop (with Authenticating proxy in the mix) -> no good (never returns
- async call can't be stopped)

Show quote
""Peter Huang" [MSFT]" wrote:

> Hi
>
> I think you may try to follow the link below to access a Web Service from
> C++.
> Walkthrough: Accessing an XML Web Service Using C++
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html
> /vbwlkwalkthroughusingwebservicewithunmanagedcode.asp
>
> The code above will use ATL class CSoapSocketClientT to access the Web
> Service.
> CSoapSocketClientT Class
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/
> vclrfCSoapSocketClientT.asp
> ============================================================================
> ================================
> This class conforms to ATL Server's SOAP client archetype.
>
> Typically this class is used with SPROXY-generated classes which build up
> the SOAP messages for you, but it is possible to use this class
> independently in the following way:
>
> Create an instance and pass the location of the XML Web service to the
> constructor.
>
> Call SetProxy or SetTimeout if necessary.
>
> Call GetWriteStream and write the SOAP message to that stream.
>
> Call SendRequest to send the SOAP message to the server.
>
> If SendRequest succeeded, call GetReadStream to read the SOAP response.
>
> If SendRequest failed, call GetClientError and GetStatusCode, or look at
> m_fault for error information.
>
> Call CleanupClient before returning to Step 3 to send further messages.
> ============================================================================
> ================================
> Here is C++ code snippet to access webservice.
> void AccessService(){
>     using namespace std;
>     Service::CService ws;
>     CComBSTR bstr;
>     HRESULT hr = ws.HelloWorld(&bstr);
>     if (SUCCEEDED(hr))
>     {
>         CW2A printstr(bstr);
>         cout<<"C++"<<endl;
>         cout<<printstr<<endl;
>     }
>     else
>     {
>         cout<<ws.GetStatusCode()<<endl;
>         cout<< "An error occurred: "<<hex<<hr<< endl;
>     }
> }
>
> int _tmain(int argc, _TCHAR* argv[])
> {
>     if (SUCCEEDED(CoInitialize(NULL))){
>         AccessService();
>         CoUninitialize();
>     }
>     return 0;
> }
>
> NOTE: we can try to use the ws.GetStatusCode() to get the StatusCode e.g.
> 401.
>
> If I have any misunderstanding, please feel free to post here.
>
>
>
> Best regards,
>
> Peter Huang
> Microsoft Online Partner Support
>
> Get Secure! - www.microsoft.com/security
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>
Author
13 Feb 2006 7:45 AM
Peter Huang" [MSFT]
Hi

I am sorry. It seems that I did not understanding your scenario very clear.
From your description, you have two test solutions.
1. pure .NET
.NET client --->proxy---->Web Service
You will get 407, which means the proxy need authentication. You did not
have concern with the scenario or you want to know how to make the .NET
client call Web Service successfully without the 407 error.

2. Com Interop
Refer to my last post about how to call Web Service from C++.
If you mean the scenario as below.
C++ client ----> .NET class libray----->proxy----->Web Service

The C++ client called .NET class library via Com Interop.
You want to know why the C++ client did not get the 407 error. If this is
not the case please let me know.
This involved the fact that .NET and COM have their own error handling
mechanism.
Error Handling
http://msdn.microsoft.com/msdnmag/issues/01/08/Interop/

Handling COM Interop Exceptions
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconhandlingcominteropexceptions.asp

HRESULTs and Exceptions
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconHRESULTsExceptions.asp


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
13 Feb 2006 2:17 PM
whoareyou
Sorry, I think I'm not being clear in my question.  Let me give some sample
code where the issue shows:
When the WebService fails with authenticating proxy it throws exception as
follows:
if(ex is System.Net.WebException)
{
..
..
// Get the HttwWebResponse to examine status
System.Net.WebException we = (System.Net.WebException)ex;       
System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)we.Response;
// called pure .NET always have resp
// When COM client calls resp always null for some reason
//     and ex.message says underlying connection is closed
   if(resp != null)
  {
      // this code does not execute for COM clients.  resp is always null
      serverError = (int)resp.StatusCode; // look for 407 enum
                                                          // proxy
authentication required
      .
     .
   }
}

So,  via pure .NET I can look at the response and I have the 407 enum.  When
I call this same exact code via COM interop, (nothing to do with how I return
errors to COM client) a WebException is still thrown.  However via COM
interop, the difference is that the response is always null - no error code
is available.  I have to look at the message included with the exception. 
This indicates that the underlying connection was closed.  I can't tell
credentials are required.

Again this is from inside the .NET component, nothing to do with the return
value via COM interop.  Only difference is that it is called from COM
interop. 
Everything for the network connection seems to be configured correctly.  If
I supply the credentials for the proxy I can connect with no issue - .NET or
COM interop. 

I am using a connection point (via COM interop) to relay the results back to
the COM client.  When I run via .NET I use a "normal" .NET event.
This is all running async via Begin and End symantecs.

When running from framework 2.0 via COM interop I never receive an
exception.  I MUST supply the credentials or I just hang and I can't even
cancel the transaction

Thanks

Show quote
""Peter Huang" [MSFT]" wrote:

> Hi
>
> I am sorry. It seems that I did not understanding your scenario very clear.
> From your description, you have two test solutions.
> 1. pure .NET
> .NET client --->proxy---->Web Service
> You will get 407, which means the proxy need authentication. You did not
> have concern with the scenario or you want to know how to make the .NET
> client call Web Service successfully without the 407 error.
>
> 2. Com Interop
> Refer to my last post about how to call Web Service from C++.
> If you mean the scenario as below.
> C++ client ----> .NET class libray----->proxy----->Web Service
>
> The C++ client called .NET class library via Com Interop.
> You want to know why the C++ client did not get the 407 error. If this is
> not the case please let me know.
> This involved the fact that .NET and COM have their own error handling
> mechanism.
> Error Handling
> http://msdn.microsoft.com/msdnmag/issues/01/08/Interop/
>
> Handling COM Interop Exceptions
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
> l/cpconhandlingcominteropexceptions.asp
>
> HRESULTs and Exceptions
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
> l/cpconHRESULTsExceptions.asp
>
>
> Best regards,
>
> Peter Huang
> Microsoft Online Partner Support
>
> Get Secure! - www.microsoft.com/security
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>
Author
14 Feb 2006 9:22 AM
Peter Huang" [MSFT]
Hi

So far I understand your scenario you are going the second test solution in
my last post.
C++ client ----> .NET class library----->proxy----->Web Service

In the .NET class library, you are using the same code with the .NET test
client.
But in the  .NET class library you will not get 407 response. You will just
get a underlying connection is closed¡§error or just hang in .NET 2.0.
If I misunderstood, please feel free to post here.

For this scenario, I think you may try to use netmon tool to see what will
return from the proxy or if it has returned from the proxy.
Microsoft have netmon tool shipped with SMS server.
You may try the netmon tool in the link below.
http://www.netmon.org/tools.htm#Sniffers

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
22 Feb 2006 2:17 PM
whoareyou
Sorry for taking so long to get back...
Upon further review with Ethereal:
407 is returned in all cases. To summarize in my .NET -> .COM interop
solution the following code will not work since the response is always NULL
System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)we.Response;
if(resp != null)
{
   serverError = (int)resp.StatusCode;.
}
The same code above works for a .NET -> .NET solution where resp is never
null.

What I realized is in the .NET -> .COM interop solution  is that for some
reason the true error condition is instead found in the InnerException.  For
this case the outer exception indicates only that the "underlying connection
was closed".  So basically same code as above but:
System.Net.WebException we = ex.InnerException as System.Net.WebException;
System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)we.Response;
if(resp != null)
{
   serverError = (int)resp.StatusCode;
}
Any ideas why I should have to look at InnerException for COM interop?

Also the hanging under .NET 2.0 seems to also happen under .NET 1.1. 
However,  the issue here seems to be .NET using http 1.1 vs. what my proxy
server is using, which is http 1.0.  There seems to be some incompatibility
between versions .  This only happens when I supply a userID and an incorrect
password.  If I change the property on the HttpWebRequest object returned to
Version10 this seems to take care of this issue.  I can also duplicate this
with Internet Explorer going against my proxy if I configure IE to use HTTP
1.1 for proxy authentication.

Thanks



Show quote
""Peter Huang" [MSFT]" wrote:

> Hi
>
> So far I understand your scenario you are going the second test solution in
> my last post.
> C++ client ----> .NET class library----->proxy----->Web Service
>
> In the .NET class library, you are using the same code with the .NET test
> client.
> But in the  .NET class library you will not get 407 response. You will just
> get a underlying connection is closed¡§error or just hang in .NET 2.0.
> If I misunderstood, please feel free to post here.
>
> For this scenario, I think you may try to use netmon tool to see what will
> return from the proxy or if it has returned from the proxy.
> Microsoft have netmon tool shipped with SMS server.
> You may try the netmon tool in the link below.
> http://www.netmon.org/tools.htm#Sniffers
>
> Best regards,
>
> Peter Huang
> Microsoft Online Partner Support
>
> Get Secure! - www.microsoft.com/security
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>
Author
23 Feb 2006 2:32 AM
Peter Huang" [MSFT]
Hi

First I think we need to confirm what is your scenario with Com Interop
solution.
C++ client ----> .NET class library----->proxy----->Web Service

If it is the problem at the above one, then the problem occurred in .NET
class library----->proxy----->Web Service should did not be related with
Com interop.
Becaused the problem is all occurred in the .NET library called web service.

If I misunderstand, please correct me.
If you want to handle exception across Com interop layer.

I htink you may try to have a look at the information below about how to
handle exception between .NET and COM via Com inerop wrap.
This involved the fact that .NET and COM have their own error handling
mechanism.
Error Handling
http://msdn.microsoft.com/msdnmag/issues/01/08/Interop/

Handling COM Interop Exceptions
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconhandlingcominteropexceptions.asp

HRESULTs and Exceptions
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconHRESULTsExceptions.asp




Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
23 Feb 2006 1:55 PM
whoareyou
Hi Peter,
Both articles are good, but this isn't what I'm trying to solve.

The issue seems to be with .NET library and only happens under the scenario
I described.   I am having no issues returning error information from COM
(please see earlier postings). From watching in the debugger I can see the
problem is that the .NET library exception contains different information to
return to COM (different from the pure .NET solution). As I just discovered,
when calling the .NET library from COM I must look at the innerexception
information.  I can change my library to additionaly check the
innterexception and return this to my COM client, and this is probably what
I'll end up doing.

Before doing so, I am trying to understand why the same .NET code behaves
differently depending on client that is calling the library.  The only
difference I see is that in one case a C++ unmanaged client calls via COM
interop, and in the other case a .NET managed client calls the code.

Show quote
""Peter Huang" [MSFT]" wrote:

> Hi
>
> First I think we need to confirm what is your scenario with Com Interop
> solution.
> C++ client ----> .NET class library----->proxy----->Web Service
>
> If it is the problem at the above one, then the problem occurred in .NET
> class library----->proxy----->Web Service should did not be related with
> Com interop.
> Becaused the problem is all occurred in the .NET library called web service.
>
> If I misunderstand, please correct me.
> If you want to handle exception across Com interop layer.
>
> I htink you may try to have a look at the information below about how to
> handle exception between .NET and COM via Com inerop wrap.
> This involved the fact that .NET and COM have their own error handling
> mechanism.
> Error Handling
> http://msdn.microsoft.com/msdnmag/issues/01/08/Interop/
>
> Handling COM Interop Exceptions
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
> l/cpconhandlingcominteropexceptions.asp
>
> HRESULTs and Exceptions
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
> l/cpconHRESULTsExceptions.asp
>
>
>
>
> Best regards,
>
> Peter Huang
> Microsoft Online Partner Support
>
> Get Secure! - www.microsoft.com/security
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>
Author
24 Feb 2006 5:25 AM
Peter Huang" [MSFT]
Hi

Here I assumed that you have gone the way below.
C++--->.NET Library--->proxy---->WebService

In this way, if there is 407 returned from proxy to the .NET Library, the
try catch block in the .NET Library will generate the exception which is
different from the way below.
.NET client --->proxy----> WebService.

The code in the .NET client and .NET Library are of the same.
e.g.
try
{
}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}

In the two scenario, the Debug Writeline will output differently.

If so can you provide a simple reproduce sample for us to make further test?

Thanks!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

AddThis Social Bookmark Button