|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Web Service / Authenticating Proxy .NET and COM interopHi, 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 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. 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. > > 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. 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. > > 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. 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. > > 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. 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. > > 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. |
|||||||||||||||||||||||