Does .NET Web Service/WCF Supports file transfer between SFTP Servers? - wcf

I want to create a service in .NET to transfer files between SFTP servers.
What will be the best way to choose as I know WCF doesn't support SFTP, does SFTP is supported by .NET Core.
Thanks & Regards
Supratik De

I have had good experience with Renci.SshNet (https://github.com/sshnet/SSH.NET, or as NuGet package). I used it in some projects transferring files between Windows and Linux.
I did not use it with .NET Core, but it should be supported.
For a first start, you can try:
...
using System.IO;
using Renci.SshNet;
using Renci.SshNet.Sftp;
...
...
var sftpClient = new SftpClient(host, user, password);
sftpClient.Connect();
// download
using (FileStream localStream = new FileStream(localPath, FileMode.Create))
{
sftpClient.DownloadFile(hostPath, localStream);
}
// upload
using (FileStream localStream = new FileStream(localPath, FileMode.Open, FileAccess.Read))
{
sftpClient.UploadFile(localStream, hostPath);
}
...

Related

Facing issue while create the events using MS graph API

I have tried this code to generate the token:
public async Task Authenticate() {
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new StringContent(_clientId), "client_id");
content.Add(new StringContent(_clientSecret), "client_secret");
content.Add(new StringContent("client_credentials"), "grant_type");
content.Add(new StringContent(".default"), "scope");
try {
var task = _client.PostAsync(new Uri(string.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", _tenantId)), content);
var res = task.GetAwaiter().GetResult();
if (res.StatusCode == System.Net.HttpStatusCode.OK) {
JsonDocument resJSON = await JsonDocument.ParseAsync(await res.Content.ReadAsStreamAsync());
_accessToken = resJSON.RootElement.GetProperty("access_token").GetString();
lock(this) {
_expiresAt = DateTime.UtcNow.AddSeconds(resJSON.RootElement.GetProperty("expires_in").GetInt16());
}
} else
throw new Exception(res.ReasonPhrase);
} catch (WebException ex) {
// handle web exception
}
}
But I got the error like
error_description=AADSTS1002016: You are using TLS version 1.0, 1.1 and/or 3DES cipher which are deprecated to improve the security posture of Azure AD. Your TenantID is: 334xxxx. Please refer to https://go.microsoft.com/fwlink/?linkid=2161187 and conduct needed actions to remediate the issue. For further questions, please contact your administrator.
Trace ID: c8a502xxxx
Correlation ID: 325a1dxxxxx
Timestamp: 2022-08-04 13:35:23Z
But the same code works in console application.While using this code inside the dll it throws the exception.All the versions are same - .net framework,System.text.json,system.memory etc.
Please help me to sort out this.
According to this page the default TLS version that is used, depends on the targeted .net version and the used operating system.
Targeting .net framework 4.8 should default to TLS1.2 on Windows 10/11
Any change that you are using an older version of either? Or that you are setting the tls version explicitly somewhere in your application?
Also using lock inside an asynchronous method is bad practice and might deadlock your code.
When I use .NET Framework 4.6.1, I encounter the same problem. After I switched the version to 4.7.2, the problem was not solved until I explicitly specified the version in Web.config.
<httpRuntime targetFramework="4.7.2" />

Can you please provide - Google Bigquery dependency latest Dotnet NUGET package names, because the Bigquery example programs are not working

Need help to get
Google Bigquery dependency latest Dotnet NUGET package names, because the Bigquery example programs are not working and it is giving the dependecy reference expections at IAuthorizationState
eError 1 The type 'DotNetOpenAuth.OAuth2.IAuthorizationState' exists in both 'c:\Echelon\GoogleDownloads\google-api-dotnet-client-1.8.1.source\Src\GoogleApis.Authentication.OAuth2.Tests\bin\Release\DotNetOpenAuth.dll' and 'c:\Users\Srinivasa\Documents\Visual Studio 2013\Projects\BigQueryConsole1\packages\DotNetOpenAuth.OAuth2.Client.4.3.4.13329\lib\net40-full\DotNetOpenAuth.OAuth2.Client.dll' c:\users\srinivasa\documents\visual studio 2013\Projects\BigQueryConsole1\BigQueryConsole1\Program.cs 37 24 BigQueryConsole1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Bigquery.v2;
using Google.Apis.Util;
namespace BigQueryConsole1
{
class Program
{
public static void Main(string[] args)
{
// Register an authenticator.
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
// Put your client id and secret here (from https://developers.google.com/console)
// Use the installed app flow here.
provider.ClientIdentifier = "asdfasd";
provider.ClientSecret = "asdfasdf";
// Initiate an OAuth 2.0 flow to get an access token
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
// Create the service.
var service = new BigqueryService(auth);
// Do something with the BigQuery service here
// Such as... service.[some BigQuery method].Fetch();
}
private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
// Get the auth URL:
IAuthorizationState state = new AuthorizationState(new[] { BigqueryService.Scopes.Bigquery.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
Uri authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString());
Console.Write(" Authorization Code: ");
string authCode = Console.ReadLine();
Console.WriteLine();
// Retrieve the access token by using the authorization code:
return arg.ProcessUserAuthorization(authCode, state);
}
}
}
You are using an old version of the library.
The latest NuGet package is available in: http://www.nuget.org/packages/Google.Apis.Bigquery.v2/
Take a look in our samples repository for samples on Google APIs (Unfortunately, we don't have a sample for BigQuery)
You should also take a look in our Getting Started guide and to be more specific in the OAuth 2.0 page.
Good luck!
[UPDATE]
We improved the OAuth 2.0 library significantly. Take a look in our blog announcement from
October 2013 - http://google-api-dotnet-client.blogspot.com/2013/10/announcing-release-of-160-beta-new.html.
In the OAuth 2.0 page I mentioned above there are the exact details of how to set your application to work with Google authorization. The library supports the OAuth 2.0 flows in Windows Phone, Windows 8 application and regular .NET 4.0 and higher.

Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC'

I'm using Sap Jco to connect to SAP database with the front end being Java(JSF), When I connect to SAP with:
try {
mConnection =JCO.createClient("400", // SAP client
"c3026902", // userid
"********", // password
"EN", // language
"iwdf5020", // host name
"00"); // system number
mConnection.connect();
}
catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
Problem I'm facing is when run the application for the first time, data is displayed but when I re-run it says "Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC' "
Can any one help me in resolving the issue?????
This sounds like the API cannot load the native driver files.
The SAP Java Connector consists of a native runtime part, that does the actuall communication and a Java API that wraps this functionality with a java api.
The Java API is inside the sapjco.jar and the native drivers are e.g on windows inside librfc32.dll and sapjcorfc.dll.
Place these dll's into your system path (e.g. windows: C:\WiNDOWS\system32) and it should run.
Cheers
Sebastian
Are your DLLs located in the Windows system32 folder? If so, are you probably using the wrong architecture? (x64 DLL on 32 bit or vice versa)
Also, are the DLLs the same version as the java api? If you have SAP GUI installed there could be older DLLs around.
Defining SAP connection:
For the Version 3,0 of the sapjco library there exists plenty of useful information. To create a connection following the instructions in:
http://www.browseye.com/linkShare.html?url=http://help.sap.com/saphelp_nwpi711/helpdata/en/46/fb807cc7b46c30e10000000a1553f7/content.htm?bwsCriterion=%22Setting%20Up%20Connection%22&bwsMatch=1&bwsCriterion=%22Setting%20Up%20Connection%22&bwsMatch=1
There are a few thing that you should take into account:
Place the dll file in the same place that the jar.
The dll must be the right version for your operating system and architecture otherwise you will get a native library error.
Example of code to create a connection to the server.
public class StepByStepClient
{
static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL";
static String DESTINATION_NAME2 = "ABAP_AS_WITH_POOL";
static
{
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "ls4065");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "85");
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "homofarber");
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "laska");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
createDestinationDataFile(DESTINATION_NAME1, connectProperties);
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");
createDestinationDataFile(DESTINATION_NAME2, connectProperties);
}
static void createDestinationDataFile(String destinationName, Properties connectProperties)
{
File destCfg = new File(destinationName+".jcoDestination");
try
{
FileOutputStream fos = new FileOutputStream(destCfg, false);
connectProperties.store(fos, "for tests only !");
fos.close();
}
catch (Exception e)
{
throw new RuntimeException("Unable to create the destination files", e);
}
}
public static void step1Connect() throws JCoException
{
JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
System.out.println("Attributes:");
System.out.println(destination.getAttributes());
System.out.println();
}
}
In SAPJco 3.0 connections are build from the info contained in a “Destination”.
The documentation example use a properties file to save the “Destination”. However it is a non-secure way to keep connection info. As is indicated on the documentation in the hightlighted paragraph you can see on next link.
http://help.sap.com/saphelp_nwpi711/helpdata/en/48/5fb9f9b523501ee10000000a421937/content.htm?bwsCriterion=%22In%20practice%20you%20should%20avoid%20this%20for%20security%20reasons.%22&bwsMatch=1
You can keep connection info on a database or any other storage system if you create a custom “DestinationDataProvider” In the Examples provided with the SAPJco library there is an example of how to create a custom DestinationDataProvider.

How to programmatically generate WSDL from WCF service (Integration Testing)

I am looking to write some integration tests to compare the WSDL generated by WCF services against previous (and published) versions. This is to ensure the service contracts don't differ from time of release.
I would like my tests to be self contained and not rely on any external resources such as hosting on IIS.
I am thinking that I could recreate my IIS hosting environment within the test with something like...
using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS), new Uri("http://localhost:8000/Omega")))
{
host.AddServiceEndpoint(typeof(NSTest.IMy_NS), new BasicHttpBinding(), "Primary");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
}
Does anyone else have any better ideas?
EDIT:
Obviously this code is simply creating a host for the service, I am still missing the client code to obtain the WSDL definition.
Just use WebClient and ?wsdl sufix in URL
using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS),
new Uri("http://localhost:8000/Omega")))
{
host.AddServiceEndpoint(typeof(NSTest.IMy_NS), new BasicHttpBinding(), "Primary");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
string wsdl = null;
using (WebClient wc = new WebClient())
{
using (var stream = wc.OpenRead("localhost:8000/Omega?wsdl"))
{
using (var sr = new StreamReader(stream))
{
wsdl = sr.ReadToEnd();
}
}
}
Console.Write(wsdl);
}
Check out the WsdlExporter on MSDN. Its used to generate wsdl in WCF.
You could also have a look in svcutil with reflector to see how its generating the wsdl information, since the tool can generate wsdl from a dll-file.
Another way to do your comparison would be to use the svcutil tool to generate the wsdl and compare it to a saved/baselined version of the service. Run the svcutil in your test and verify the output against the old files. Not really self-contained test since you'll need the svcutil...
How about something like this?
Creating a WSDL using C#
One thing you need to be careful of is to compare the entire WSDL. WCF breaks up WSDLs, unlike classic web services (asmx) WSDLs. This means that the core of the info is on the ?WSDL page, however, there will also be multiple XSDs (.svc?XSD=XSD0, 1, 2 ...) and possibly multiple WSDL pages (?WSDL and ?WSDL=WSDL0 for example).
One way to accomplish this would be to generate a webrequest to get the data from the root wsdl. Then you can search the WSDL for anything like (yourServicename).svc?WSDL=WSLD0 and (yourServicename)?XSD=XSD0 and so on, spawning additional webrequests for each WSDL and XSD.
You might be better off using SoapUI to test the WSDL rather than relying on NUnit directly.
If you want to call SoapUI from NUnit, it's possible, but a little clunky. See http://enthusiasm.soapui.org/forum/viewtopic.php?f=2&t=15 for more information.
Same answer translated to VB
Using host = New ServiceHost(GetType(MyHelloWorldWcfLib.HelloWorldServer), New Uri("http://localhost:8000/Omega"))
host.AddServiceEndpoint(GetType(MyHelloWorldWcfLib.IHelloWorld), New BasicHttpBinding(), "Primary")
Dim behavior = New ServiceMetadataBehavior()
behavior.HttpGetEnabled = True
host.Description.Behaviors.Add(behavior)
host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex")
host.Open()
Dim wsdl As String = Nothing
Using wc = New System.Net.WebClient()
Using stream = wc.OpenRead("http://localhost:8000/Omega?wsdl")
Using sr = New IO.StreamReader(stream)
wsdl = sr.ReadToEnd()
End Using
End Using
End Using
Console.Write(wsdl)
End Using

Self updating .net CF application

I need to make my CF app self-updating through the web service.
I found one article on MSDN from 2003 that explains it quite well. However, I would like to talk practice here. Anyone really done it before or does everyone rely on third party solutions?
I have been specifically asked to do it this way, so if you know of any tips/caveats, any info is appreciated.
Thanks!
This is relatively easy to do. Basically, your application calls a web service to compare its version with the version available on the server. If the server version is newer, your application downloads the new EXE as a byte[] array.
Next, because you can't delete or overwrite a running EXE file, your application renames its original EXE file to something like "MyApplication.old" (the OS allows this, fortunately). Your app then saves the downloaded byte[] array in the same folder as the original EXE file, and with the same original name (e.g. "MyApplication.exe"). You then display a message to the user (e.g. "new version detected, please restart") and close.
When the user restarts the app, it will be the new version they're starting. The new version deletes the old file ("MyApplication.old") and the update is complete.
Having an application update itself without requiring the user to restart is a huge pain in the butt (you have to kick off a separate process to do the updating, which means a separate updater application that cannot itself be auto-updated) and I've never been able to make it work 100% reliably. I've never had a customer complain about the required restart.
I asked this same question a while back:
How to Auto-Update Windows Mobile application
Basically you need two applications.
App1: Launches the actual application, but also checks for a CAB file (installer). If the cab file is there, it executes the CAB file.
App2: Actual application. It will call a web service, passing a version number to the service and retrieve a URL back if a new version exists (). Once downloaded, you can optionally install the cab file and shut down.
One potiencial issue: if you have files that one install puts on the file system, but can't overwrite (database file, log, etc), you will need two separate installs.
To install a cab: look up wceload.exe http://msdn.microsoft.com/en-us/library/bb158700.aspx
private static bool LaunchInstaller(string cabFile)
{
// Info on WceLoad.exe
//http://msdn.microsoft.com/en-us/library/bb158700.aspx
const string installerExe = "\\windows\\wceload.exe";
const string processOptions = "";
try
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = installerExe;
processInfo.Arguments = processOptions + " \"" + cabFile + "\"";
var process = Process.Start(processInfo);
if (process != null)
{
process.WaitForExit();
}
return InstallationSuccessCheck(cabFile);
}
catch (Exception e)
{
MessageBox.Show("Sorry, for some reason this installation failed.\n" + e.Message);
Console.WriteLine(e);
throw;
}
}
private static bool InstallationSuccessCheck(string cabFile)
{
if (File.Exists(cabFile))
{
MessageBox.Show("Something in the install went wrong. Please contact support.");
return false;
}
return true;
}
To get the version number: Assembly.GetExecutingAssembly().GetName().Version.ToString()
To download a cab:
public void DownloadUpdatedVersion(string updateUrl)
{
var request = WebRequest.Create(updateUrl);
request.Credentials = CredentialCache.DefaultCredentials;
var response = request.GetResponse();
try
{
var dataStream = response.GetResponseStream();
string fileName = GetFileName();
var fileStream = new FileStream(fileName, FileMode.CreateNew);
ReadWriteStream(dataStream, fileStream);
}
finally
{
response.Close();
}
}
What exactly do you mean by "self-updating"? If you're referring to configuration or data, then webservices should work great. If you're talking about automatically downloading and installing a new version of itself, that's a different story.
Found this downloadable sample from Microsoft- looks like it should help.
If you want to use a third-party component, have a look at AppToDate developed by the guys at MoDaCo.