为什么来自asp.net c#application的web服务调用返回null?

时间:2016-02-25 14:52:49

标签: c# asp.net web-services wcf soap

在我的应用程序中,我正在使用Web服务,并且当我调用Web服务功能时,我正在使用自定义类在soap请求的标头中使用用户名和密码创建usernametoken。

参考我制作标题的自定义类: - https://msdn.microsoft.com/en-us/library/ms730868(v=vs.110).aspx

但是,当我使用xmlns:wsse时,我收到了内部错误,当我使用xmlns:o标题中的<security>标记时,我得到空响应。

如果我在配置中添加用户名和密码

,相同的应用程序工作正常
<headers>
    <wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>username</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
   </headers>

我想将不同调用的用户名和密码更改为同一个webservice,因此我使用自定义类并生成标题,不幸的是它成为了安全标记如下所示的wcf auhtentication: -

      <o:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <o:Username></o:Username>
        <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"></o:Password>
      </o:UsernameToken>

这为我的函数调用返回null。 知道如何让它工作吗? 任何建议都将非常感激。

注意:它说Microsoft .net不赞成使用wse并更新为wcf身份验证。但它在配置文件中使用wsse和用户名和密码对我有用,但是我无法在webservice中更改不同函数调用的用户名和密码。

初始化Web服务并调用方法的代码如下: -

  string endpointUri = @"https://my endpoint url";
                var endpoint = new System.ServiceModel.EndpointAddress(endpointUri);

                // Create binding using HTTPS
                var securityElement = System.ServiceModel.Channels.SecurityBindingElement.CreateUserNameOverTransportBindingElement();
                securityElement.IncludeTimestamp = true;
                securityElement.EnableUnsecuredResponse = true;
                securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
                securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
                var encodingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement(System.ServiceModel.Channels.MessageVersion.Soap11, System.Text.Encoding.UTF8);
                var transportElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
                transportElement.MaxReceivedMessageSize = 20000000;
                var binding = new System.ServiceModel.Channels.CustomBinding(securityElement, encodingElement, transportElement);
                QTWebSvcsClient client = new QTWebSvcsClient(binding, endpoint);

                //==========================================================================================================================

                client.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
                client.ChannelFactory.Endpoint.Behaviors.Add(new MyClientCredetnials());
                client.ClientCredentials.UserName.UserName = userName + "@" + comp;
                client.ClientCredentials.UserName.Password = password;

                getDriverDetailsRequest request = new getDriverDetailsRequest();
                request.driverId = "Driver1";

                getDriverDetailsResponse response = new getDriverDetailsResponse();
                response.getDriverDetailsReturn = client.getDriverDetails(request.driverId);

对我的代码返回null,我在这里引用null对象时会遇到异常

Console.WriteLine(response.getDriverDetailsReturn.driverName);

2 个答案:

答案 0 :(得分:2)

看到这篇文章,它解释了如何使用Wcf自定义这种类型的soap调用: http://weblog.west-wind.com/posts/2012/Nov/24/WCF-WSSecurity-and-WSE-Nonce-Authentication

答案 1 :(得分:1)

我决定不遵循艰难的方式,而只是实现我的真正需求 - 通过程序动态更改Web安全凭据。

我刚刚使用了在向C#应用程序添加web服务引用时自动创建的配置文件代码。

然后在代码中起诉

BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
                binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
                CustomBinding customBinding = new CustomBinding(binding);
                SecurityBindingElement element = customBinding.Elements.Find<SecurityBindingElement>();
                element.IncludeTimestamp = false;
                EndpointAddress epadd = new EndpointAddress("https://mycompany.ca:113/tracsWebWS/services/TWebSvcs");
                TWebSvcsClient client = new TWebSvcsClient(customBinding, epadd);
                client.ClientCredentials.UserName.UserName = userName;
                client.ClientCredentials.UserName.Password = password;

然后通过网络服务调用该功能给了我正在寻找的答案。

感谢所有帮助我提出建议的人。