I have created a self hosted service with a proxy
Service and Contracts
Namespace ECDBDatabase.Service
Public Class DatabaseService
<ServiceContract(Name:="DatabaseService", Namespace:="net.tcp://localhost:9010/ECDBDatabase.Service")> _
Public Interface IRPMSDatabaseService
<OperationContract()> _
Function GetHandover(ByVal Username As String, ByVal Password As String) As DataSet
End Interface
Public Function GetHandover(ByVal Username As String, ByVal Password As String) As DataSet Implements IRPMSDatabaseService.GetHandover
'Connection string to Database
Dim ReadConnectionString As String = "data source =localhost;" + "User ID=" & Username + ";Password=" & Password + ";Database=somedatabase"
ReadConnection = New SqlConnection(ReadConnectionString)
'Fill and return the dataset
Try
dbScriptFile = "some sql file"
objReader = New StreamReader(dbScriptFile)
cmd.CommandText = objReader.ReadToEnd.Replace("Go", ";")
scriptArr = cmd.CommandText.Split(";")
cmd.Connection = ReadConnection
HandoverDataset = New DataSet
HandoverAdapter = _
New SqlDataAdapter(cmd)
For i = 0 To scriptArr.Length - 1
cmd.CommandText = scriptArr.GetValue(i)
'Fill the dataset
HandoverAdapter.Fill(HandoverDataset)
Next
'Return the dataset.
Return HandoverDataset
Catch ex As Exception
Throw ex
End Try
End Function
End Class
End Class
End Namespace
My host is as follows:
Sub Main()
'Instantiate the service address
Dim baseAddress As Uri = New Uri("net.tcp://localhost:9010/ECDBDatabase.Service")
'Create the servicehost
Using ECDBHost As New ServiceHost(GetType(ECDBService.ECDBDatabase.Service.DatabaseService.RPMSDatabaseService), baseAddress)
Dim smb As New ServiceMetadataBehavior
Dim debug As New ServiceDebugBehavior
smb.HttpGetEnabled = False
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
debug.IncludeExceptionDetailInFaults = True
ECDBHost.Description.Behaviors.Add(smb)
ECDBHost.Open()
'Execute commands on console application
Console.WriteLine("Service has started at {0}", baseAddress)
Console.ReadLine()
End Using
End Sub
My Proxy is as follows;
Public Function GetHandover(ByVal UserName As String, ByVal Password As String) As DataSet
Try
HandoverDataset = New DataSet
tempBinding = New NetTcpBinding()
tempAddress = New EndpointAddress(New Uri("net.tcp://localhost:9010/ECDBDatabase.Service"), New SpnEndpointIdentity(""))
With tempBinding
End With
With tempAddress
End With
'Instantiating the channel for the proxy and setting the proxy up to communicate
tempFactory = New ChannelFactory(Of ECDBService.ECDBDatabase.Service.DatabaseService.IRPMSDatabaseService)(tempBinding, tempAddress)
With tempFactory
tempProxy = .CreateChannel()
End With
'Setting the contracts to the channel
With tempProxy
HandoverDataset = .GetHandover(UserName, Password)
End With
Return HandoverDataset
Catch ex As Exception
Throw ex
End Try
End Function
I call the proxy which in turns access the service and it is as follows:
Private Sub frmHandover_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Load the dataset and bind the controls.
Try
HandoverData = New DatabaseProxyClass.ECDBDatabase.Service.DatabaseProxy
User = frmEhawkRPMS.UserN
Pass = frmEhawkRPMS.PassW
HandoverSet = New DataSet
HandoverSet = HandoverData.GetHandover(User, Pass)
My problem starts when I attempt to access the service from the proxy I get the following error: "Data Error: The server was unable to process the request due to an internal error.
For more information about the error, either turn on IncludeExceptionDetailInFaults(either from servicebahviorattribute or from the configuration behaviour) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft.net Framework 3.0 SDk documentation and inspect the server trace logs."
I've attemtped to enable the exceptions but get an error that says there is already a service behavior and it doesn't allow me to add the exceptiondetailfaults to the service behavior and there are not too many if any examples for adding this in a self hosted WCF with VB.
I'm looking for some advice on adding the exception in VB or if someone notice what my problem is to begin with and can point it out that would be greatly appreciated as well.
Also here is my app config that is in my console application that starts the service.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="ECDBService.ECDBDatabase.Service.RPMSDatabaseService">
<endpoint address="net.tcp://localhost:9010/ECDBDatabase.Service"
binding="netTcpBinding"
contract="ECDBService.ECDBDatabase.Service.IRPMSDatabaseService" />
<endpoint address ="" binding="wsHttpBinding" contract="ECDBService.ECDBDatabase.Service.RPMSDatabaseService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
</configuration>
Related
When i make third party request to some URL then IIS gives me error:
The request was aborted: Could not create SSL/TLS secure channel.
however i am able to make request to same URL from console application and Postman.
Dim certificates As X509Certificate2 = New X509Certificate2()
Dim uriPath As String = "D:\CertificateFolder\MyCert.cer"
Dim localPath As String = New Uri(uriPath).LocalPath
certificates.Import(localPath)
Dim sResult As String = ""
Dim activeProtocol As SecurityProtocolType =
ServicePointManager.SecurityProtocol
Try
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or
SecurityProtocolType.Tls11
Dim oRequest As HttpWebRequest =
WebRequest.Create("https://test.com/router.dll")
oRequest.KeepAlive = False
oRequest.Method = "POST"
oRequest.ContentType = "text/xml"
Dim Test As String = "some xml"
Dim bytes As Byte() = Text.Encoding.UTF8.GetBytes(Test)
oRequest.ContentLength = bytes.Length
oRequest.ClientCertificates = New X509CertificateCollection({certificates})
Dim oWriter As StreamWriter
Try
Dim streamToSend As Stream = oRequest.GetRequestStream()
oWriter = New StreamWriter(oRequest.GetRequestStream())
streamToSend.Write(bytes, 0, bytes.Length)
streamToSend.Close()
Catch up As Exception
Return
Finally
End Try
Dim oResponse As HttpWebResponse = oRequest.GetResponse()
Dim oReader As New StreamReader(oResponse.GetResponseStream())
sResult = oReader.ReadToEnd
oReader.Close()
Catch
' do nothing for now
Finally
ServicePointManager.SecurityProtocol = activeProtocol
End Try
Note* Method in URL is not file. Method name has .dll just as name of method.
I am using .net framework 4.5
Do you have access to the server management?
Could you first try to connect without providing the client certificate?
Remove the corresponding part from your code and turn off the client certificate requirement in the IIS management console.
If the error still persist, find out which cipher suits the client supports and which the server. If they don't much an error similar to yours would occur.
To check the client, rewrite your code to connect to the following site:
"https://howsmyssl.com/a/check"
If your server you are connection to is public (internet visible), you can use the following site to check its supported cipher suits:
https://www.ssllabs.com/ssltest/
I'm not new to web services or wcf but currently I'm stuck in a problem I couldn't find a solution for yet. I tried everything I've found searching stack overflow, but nothing solved the problem.
I'm trying to write a very small service using WCF that should return the result as XML, Json or CSV. For this I wrote the following code:
<ServiceContract()>
Public Interface IPortalExchangeService
<OperationContract()> _
<WebGet(BodyStyle:=WebMessageBodyStyle.Wrapped, ResponseFormat:=WebMessageFormat.Xml, UriTemplate:="belegungskalender/xml/{anbieter}/{subD}")> _
Function XMLData(ByVal anbieter As String, ByVal subD As String) As String
<OperationContract()> _
<WebGet(BodyStyle:=WebMessageBodyStyle.Wrapped, ResponseFormat:=WebMessageFormat.Json, UriTemplate:="belegungskalender/json/{anbieter}/{subD}")> _
Function JSONData(ByVal anbieter As String, ByVal subD As String) As String
<OperationContract()> _
<WebGet(UriTemplate:="belegungskalender/csv/{anbieter}/{subD}")> _
Function CSVData(anbieter As String, subD As String) As System.IO.Stream
End Interface
Now the class implementing the interface
Imports System.IO
Public Class CalendarExchangeService
Implements IPortalExchangeService
Public Sub New()
End Sub
Public Function XMLData(ByVal anbieter As String, ByVal subD As String) As String Implements IPortalExchangeService.XMLData
Return String.Format("You entered: {0}", subD)
End Function
Public Function JSONData(ByVal anbieter As String, ByVal subD As String) As String Implements IPortalExchangeService.JSONData
Return String.Format("You entered: {0}", subD)
End Function
Public Function CSVData(ByVal anbieter As String, ByVal subD As String) As Stream Implements IPortalExchangeService.CSVData
Dim ms As New MemoryStream
Dim enc As New UTF8Encoding
Dim arrBytData() As Byte = enc.GetBytes("Hallo;" + anbieter + ";hier;sind;die;Daten;von;" + subD)
ms.Write(arrBytData, 0, arrBytData.Length)
ms.Position = 0
WebOperationContext.Current.OutgoingResponse.ContentType = "text/csv"
Return ms
End Function
End Class
The web.config looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="PortalExchangeService" behaviorConfiguration="pesBehavior">
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration=""
behaviorConfiguration="restfulBehavior"
contract="IPortalExchangeService">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="pesBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
And last not least the Client Code:
Dim url As String = "http://localhost:24642/PortalExchangeService.svc/belegungskalender/xml/testanbieter/subDomain"
Dim myRequest As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
myRequest.ContentType = "application/xml"
myRequest.Method = "GET"
Dim myResponse As HttpWebResponse
myResponse = CType(myRequest.GetResponse(), HttpWebResponse)
Dim streamResponse As Stream = myResponse.GetResponseStream()
Dim streamRead As StreamReader = New StreamReader(streamResponse)
Dim readBuffer(255) As Char
Dim count As Integer = streamRead.Read(readBuffer, 0, 256)
Dim result As String = String.Empty
Do While (count > 0)
Dim resultData As String = New String(readBuffer, 0, count)
count = streamRead.Read(readBuffer, 0, 256)
result &= resultData
Loop
streamRead.Close()
streamResponse.Close()
myResponse.Close()
This all looked good to me, but running the client code I'm getting a "400 Bad Request" with no further information in the line
"myResponse = CType(myRequest.GetResponse(), HttpWebResponse)"
Testing the Service with WCF-Client Tool works fine, but calling with HTTP GET never.
Any ideas what I'm doing wrong?
Thank in advance for your tips!!
Best regards,
Henner
I have the following simple REST service running based on the code found on MSDN - code below.
How can I modify this to be able to use transport security - SSL ?
I've been googling around for a solution, but it seems that most examples are mentioning to modify web.config file, but this example doesn't even have that... Thanks for any help with this one!
Imports System
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Web
Imports System.Text
<ServiceContract()> _
Public Interface IService
<OperationContract()> _
<WebGet()> _
Function EchoWithGet(ByVal s As String) As String
<OperationContract()> _
<WebInvoke()> _
Function EchoWithPost(ByVal s As String) As String
end interface
Public Class Service
Implements IService
Public Function EchoWithGet(ByVal s As String) As String Implements IService.EchoWithGet
Return "You said " + s
End Function
Public Function EchoWithPost(ByVal s As String) As String Implements IService.EchoWithPost
Return "You said " + s
End Function
End Class
Module program
Sub Main()
Dim host As WebServiceHost = New WebServiceHost(GetType(Service), New Uri("http://localhost:8000/"))
Try
Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "")
host.Open()
Using cf As New ChannelFactory(Of IService)(New WebHttpBinding(), "http://localhost:8000")
cf.Endpoint.Behaviors.Add(New WebHttpBehavior())
Dim channel As IService = cf.CreateChannel()
Dim s As String
Console.WriteLine("Calling EchoWithGet via HTTP GET: ")
s = channel.EchoWithGet("Hello, world")
Console.WriteLine(" Output: {0}", s)
Console.WriteLine("")
Console.WriteLine("This can also be accomplished by navigating to")
Console.WriteLine("http://localhost:8000/EchoWithGet?s=Hello, world!")
Console.WriteLine("in a web browser while this sample is running.")
Console.WriteLine("")
Console.WriteLine("Calling EchoWithPost via HTTP POST: ")
s = channel.EchoWithPost("Hello, world")
Console.WriteLine(" Output: {0}", s)
Console.WriteLine("")
End Using
Console.WriteLine("Press <ENTER> to terminate")
Console.ReadLine()
host.Close()
Catch cex As CommunicationException
Console.WriteLine("An exception occurred: {0}", cex.Message)
host.Abort()
End Try
End Sub
End Module
Adding the following solved my problem and all traffic goes through HTTPS. I hope this will help someone in the future.
Dim binding As New WebHttpBinding
binding.Security.Mode = WebHttpSecurityMode.Transport
Dim store As New X509Store(StoreName.My, StoreLocation.LocalMachine)
store.Open(OpenFlags.ReadWrite)
Dim cert = store.Certificates.Find(X509FindType.FindBySubjectName, "localhost", False)(0)
store.Close()
Dim bindPortToCertificate As New Process
bindPortToCertificate.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "netsh.exe")
bindPortToCertificate.StartInfo.Arguments = String.Format("http add sslcert ipport=0.0.0.0:{0} certhash={1} appid={{{2}}}", 22370, cert.Thumbprint, Guid.NewGuid())
bindPortToCertificate.Start()
bindPortToCertificate.WaitForExit()
I am trying to extend a classic ASP site by connecting to some WCF web services using SOAP 1.2 messages. So on the client end, there is no binding I am just using XMLHTTP.
I am getting the dreaded "The message with To '' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher." error.
My client is using a self-signed SSL cert, and the service end has an SSL cert set up as well.
Most of the solutions to this problem involve ServiceBehavior config on the client to turn off the Address Filter but that's not applicable in this case. Any help?
Code
I created a class in VBScript
Class SOAPRequest
Private objXMLHttp, webServiceURL, contentType
Public servicePath, XmlNS, action, SOAPRequest, SOAPResponse
Private Sub Class_Initialize
set objXMLHttp = Server.CreateObject("MSXML2.XMLHTTP")
webServiceURL = Application("Web Service URL")
contentType = "application/soap+xml;charset=UTF-8"
End Sub
Public Function SendRequest
'Open HTTP connection
objXMLHttp.Open "POST", webServiceURL & "/wcf/" & servicePath, False
'Setting request headers
objXMLHttp.setRequestHeader "Content-Type", contentType
objXMLHttp.setRequestHeader "SOAPAction", webServiceURL & "/wcf/" & servicePath & "?wsdl"
dim SOAPEnvelopeStart, SOAPEnvelopeEnd
SOAPEnvelopeStart = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:urn='" & XmlNS & "'><soap:Header/><soap:Body>"
SOAPEnvelopeEnd = "</soap:Body></soap:Envelope>"
'Send SOAP request
objXMLHttp.Send SOAPEnvelopeStart & SOAPRequest & SOAPEnvelopeEnd
'Get XML Response
SOAPResponse = objXMLHttp.ResponseText
End Function
Public Function Close
Set objXMLHttp = Nothing
End Function
End Class
and then I call it as such
set objSOAP = New SOAPRequest
'set up the request
with objSOAP
.servicePath = "myservice.svc"
.XmlNS = "urn:MyNamespace"
.action = "Action"
.SOAPRequest = "<urn:GetMyData></urn:GetMyData>"
end with
objSOAP.SendRequest
I need to change the connectionstring area of my aap.config file in vb.net. I have tried several codes but nothing worked for me. I was suggested following code
Dim config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
Dim connectionStringsSection = DirectCast(config.GetSection("connectionStrings"), ConnectionStringsSection)
connectionStringsSection.ConnectionStrings("Blah").ConnectionString = "Data Source=blah;Initial Catalog=blah;UID=blah;password=blah"
config.Save()
ConfigurationManager.RefreshSection("connectionStrings")
But I do not understand what will be "Blah" in my code? Also how does this change the text?
Secondly, if I use Readalltext and replacetext and then writealltext, will it be ok or it can cause any problems?
Thanks
To store and retrieve connection string from app.config use the following method:
Create a key in app.config:
<appSettings>
<add key="ConnectionString" value=""/>
</appSettings>
To set value of connection string:
Dim config As System.Configuration.Configuration
Dim fileMap As New ExeConfigurationFileMap()
fileMap.ExeConfigFilename = "Path of app.config"
config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None)
' Sets values to config file.
If config.HasFile() Then
config.AppSettings.Settings.Item("ConnectionString").Value = "Data Source=blah;Initial Catalog=blah;UID=blah;password=blah"
config.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("AppSettings")
End If
To get the value of Connection String:
Dim config As System.Configuration.Configuration
Dim fileMap As New ExeConfigurationFileMap()
fileMap.ExeConfigFilename = "Path of app.config"
config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None)
' Sets values to config file.
If config.HasFile() Then
strConnString = config.AppSettings.Settings.Item("ConnectionString").Value
End If
Here strConnString is a string variable which will store connection string value.