Good day. Please help. I work in Visual Studio 2015. I added a link to the WSDL I needed, a structure was automatically created in the Service reference folder to access this service. The bottom line is that I need to connect to another service that uses validation through WS-Security. If you run the project now, it displays the error "No WS-Security header found".

This is how the service is connected to Web.config

<system.serviceModel> <bindings> <basicHttpBinding> <binding name="WsdlPortSoap111"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Basic" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://iais-test.kemsu.ru:80/DekanatService-0_1_1/ws" binding="basicHttpBinding" bindingConfiguration="WsdlPortSoap111" contract="kemsu.services.p.WsdlPort" name="WsdlPortSoap111"> </endpoint> </client> 

Here is the method I use to send a request:

 WsdlPortClient client; List<Specialities> specialities = new List<Specialities>(); GetSpecialitiesResponse resp = new GetSpecialitiesResponse(); GetSpecialitiesRequest req = new GetSpecialitiesRequest(); req.institute_id = instid; resp = client.GetSpecialities(req); Diplom.kemsu.services.p.speciality[] spec = resp.list; 

I tried to do this, but the title I need does not add it:

 client = new WsdlPortClient(); client.ClientCredentials.UserName.UserName = "user"; client.ClientCredentials.UserName.Password = "pass"; 

Full error code:

 No WS-Security header found Описание: Необработанное исключение при выполнении текущего веб-запроса. Изучите трассировку стека для получения дополнительных сведений о данной ошибке и о вызвавшем ее фрагменте кода. Сведения об исключении: System.ServiceModel.FaultException: No WS-Security header found 

Source error (these lines are from the automatically generated Reference.cs file in the connected service):

 [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] Diplom.kemsu.services.p.GetInstitutesResponse1 Diplom.kemsu.services.p.WsdlPort.GetInstitutes(Diplom.kemsu.services.p.GetInstitutesRequest1 request){ return base.Channel.GetInstitutes(request); } 

UPD. Found the right solution. If someone came across this question, then that's how I decided it:

To start, added two classes:

The first:

  namespace YourProj.Infrastructure { public class InspectorBehavior : IEndpointBehavior { public string LastRequestXML { get { return myMessageInspector.LastRequestXML; } } public string LastResponseXML { get { return myMessageInspector.LastResponseXML; } } private MyMessageInspector myMessageInspector = new MyMessageInspector(); public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add(myMessageInspector); } } public class MyMessageInspector : IClientMessageInspector { public string LastRequestXML { get; private set; } public string LastResponseXML { get; private set; } public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { LastResponseXML = reply.ToString(); } public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) { //LastRequestXML = request.ToString(); MessageHeader messageHeadersElement = new SecurityHeader("user", "pass"); request.Headers.Add(messageHeadersElement); LastRequestXML = request.ToString(); return request; } } } 

Second:

 namespace YourProj.Infrastructure { public class SecurityHeader : System.ServiceModel.Channels.MessageHeader { public string userName; public string password; static object locker = new object(); static Guid Generate15UniqueDigits() { return Guid.NewGuid(); } public SecurityHeader(string n,string p) { userName = n; password = p; } protected override void OnWriteStartHeader(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion) { writer.WriteStartElement("wsse", Name, Namespace); writer.WriteAttributeString("xmlns", "wsu", null, Namespace); } protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion) { DateTime time = new DateTime(); time = DateTime.UtcNow; var timeexp = time.AddMinutes(1); string Created = time.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); string Expires = timeexp.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); //TimeStamp ts = new TimeStamp(); UsernameToken userToken = new UsernameToken(userName, password, PasswordOption.SendHashed); writer.WriteStartElement("wsse", "UsernameToken", Namespace); writer.WriteAttributeString("xmlns", "wsu", null, userToken.Id); writer.WriteStartElement("wsse", "Username", Namespace); writer.WriteValue(userToken.Username); writer.WriteEndElement(); writer.WriteStartElement("wsse", "Password", Namespace); writer.WriteValue(userToken.Password); writer.WriteEndElement(); writer.WriteStartElement("wsse", "Nonce", Namespace); writer.WriteValue(userToken.Nonce); writer.WriteEndElement(); writer.WriteStartElement("wsu", "Created", null); writer.WriteValue(userToken.Created.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'")); writer.WriteEndElement(); Guid g = Generate15UniqueDigits(); writer.WriteEndElement(); writer.WriteStartElement("wsu", "Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); writer.WriteAttributeString("wsu", "Id", null, "TS-" + g); writer.WriteStartElement("wsu", "Created", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); writer.WriteValue(Created); writer.WriteEndElement(); writer.WriteStartElement("wsu", "Expires", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); writer.WriteValue(Expires); writer.WriteEndElement(); writer.WriteEndElement(); } public override string Name { get { return "Security"; } } public override string Namespace { get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; } } } } 

These two classes are needed to intercept the message and make the changes you need. Namely, this is what the BeforeSendRequest method does in the InspectorBehavior class (which is what its name actually says). The edits themselves are made in the OnHriteHeaderContents method of the SecurityHeader class. Then you should add it to the port through which you connect to the server you need. I do this as follows:

  client = new WsdlPortClient(); // объявляем переменную порта var requestInterceptor = new InspectorBehavior(); //создаем перехватчик запроса client.Endpoint.Behaviors.Add(requestInterceptor); // добавляем перехватчик запроса, чтобы записать в header security заголовок client.ClientCredentials.UserName.UserName = "user"; // вносим имя пользователя client.ClientCredentials.UserName.Password = "pass"; // и пароль 

After that, everything worked for me. All these dances with a tambourine, as I understood it, were needed because The server to which I connect does not support HTTPS connections. Therefore, he got out like this, maybe he can help someone.

  • try instead TransportCredentialOnly insert TransportWithMessageCredential - Ruslan_K
  • @Ruslan_K If I change TransportCredentialOnly to TransportWithMessageCredential, another error comes out: "The presented URI scheme 'HTTPS' is invalid; Expected, 'HTTP'. Parameter name: via" - Vitaly Vashchenko

0