How to use SSIS variable outside Main() method in SSIS Script Task - c#

I am using SSIS script task to send automated e-mail based on a few pre-conditions. As part of that I have a SendAutomatedEmail() method and in this method I am passing two variables mailServer and recipient. In doing so I run into the error "object reference not set to an instance of an object.".
Tried to use a constructor but that did not resolve the problem.
class Program
{
public void Main()
{
string mailServer = Dts.Variables["User::varServer"].Value.ToString();
string recipient = Dts.Variables["User::varRecipient"].Value.ToString();
server msr = new server(mserv, rec);
}
public class server
{
string ms;
string r;
public result(string mserv, string rec)
{
ms = mserv;
r = rec;
}
}
}
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Program
{
public void Main()
{
try
{
//do something
}
catch
{
//catch exception
}
}
public static void SendAutomatedEmail(string htmlString, string recipient = "user#domain.com")
{
try
{
string mailServer = Dts.Variables["User::varServer"].Value.ToString(); //error "object reference not set to an instance of an object."
string recipient = Dts.Variables["User::varRecipient"].Value.ToString(); //error "object reference not set to an instance of an object."
MailMessage message = new MailMessage("it#domain.com", recipient);
message .IsBodyHtml = true;
message .Body = htmlString;
message .Subject = "Test Email";
SmtpClient client = new SmtpClient(mailServer);
var AuthenticationDetails = new NetworkCredential("user#domain.com", "password");
client.Credentials = AuthenticationDetails;
client.Send(message);
}
catch (Exception e)
{
//catch exception
}
}
}
I should be able to pass the value to the variable seamlessly in the SendAutomatedEmail() method.

Simplest way is to declare 2 variables in Program Class, read the values within the Main() function and assign these values to the local variables. Then you can use local variables outside of Main() function.
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Program
{
string mailServer;
string recipient;
public void Main()
{
try
{
mailServer = Dts.Variables["User::varServer"].Value.ToString();
recipient = Dts.Variables["User::varRecipient"].Value.ToString();
}
catch
{
//catch exception
}
}
private class sendEMail
{
public static void SendAutomatedEmail(string htmlString, string recipient = "user#domain.com")
{
try
{
MailMessage message = new MailMessage("it#domain.com", recipient);
message .IsBodyHtml = true;
message .Body = htmlString;
message .Subject = "Test Email";
SmtpClient client = new SmtpClient(mailServer);
var AuthenticationDetails = new NetworkCredential("user#domain.com", "password");
client.Credentials = AuthenticationDetails;
client.Send(message);
}
catch (Exception e)
{
//catch exception
}
}
}
}

Related

HTTP status code 500 when querying an API from a C# program, except the API works

I need to use another company's API to query data using POST requests.
The API works (= I receive all the data with no errors) when I query it from the swagger website using the UI, but when I do it from my C# program I get a 500 Internal Server Error.
Where should I be looking for the problem ? Is there a way to get a more detailed error message ?
Edit (added code) :
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Interception;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization;
using System.Text;
namespace credex_distribution_offers_to_interfaces
{
class Program
{
private const string jsonMediaType = "application/json";
static void Main()
{
FetchJSONAndInsertToDB();
}
private static bool FetchJSONAndInsertToDB()
{
var baseServiceUrl = new Uri("a valid url");
Root rootObject;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonMediaType));
try
{
string token = FetchToken(httpClient, baseServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token);
}
catch (Exception e)
{
return false;
}
try
{
rootObject = FetchDistributionLookupOffers(httpClient, baseServiceUrl, 29612, 29613, 29614, 29617, 29621);
}
catch (Exception e)
{
return false;
}
}
// database related stuff...
// ...
return true;
}
[DataContract]
public class MortgageForDistributionLookupInputDto
{
public int[] OfferNumbers { get; set; }
}
private static Root FetchDistributionLookupOffers(HttpClient aHttpClient, Uri aBaseServiceUrl, params int[] aOfferNumbers)
{
var input = new MortgageForDistributionLookupInputDto()
{
OfferNumbers = aOfferNumbers
};
var lookup = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "v1/MortgageDetails/InvestorLookupOffers"), PayloadFor(input)).Result;
if (lookup.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching investor lookup offers failed with HTTP status code '" + lookup.StatusCode + "' : " + lookup.ReasonPhrase + "}");
}
var obj = ValueFor<Root>(lookup.Content);
return obj;
}
private static HttpContent PayloadFor<T>(T aObject)
{
return new StringContent(aObject.SerializeJson(), Encoding.UTF8, jsonMediaType);
}
private static T ValueFor<T>(HttpContent aHttpContent)
{
//var content = aHttpContent.ReadAsStringAsync();
return aHttpContent.ReadAsStreamAsync().Result.DeSerializeJson<T>();
}
private static string FetchToken(HttpClient aHttpClient, Uri aBaseServiceUrl)
{
var login = new LoginRequest()
{
UserName = "some user name",
Password = "some password"
};
var authResult = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "api/Login"), PayloadFor(login)).Result;
if (authResult.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching authentication token failed. Reason : " + authResult.StatusCode + " -> " + authResult.ReasonPhrase);
}
return authResult.Content.ReadAsStringAsync().Result.Trim('"');
}
}
}

Post a message to slack from c# application

I am trying to post a message on the #general channel and this worked when was doing it through a console app but Now I am using MVC and the message doesn't seem to get posted. Also, earlier I was using the webhook URL and now I am using the access token that I have.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace SlackClient.Controllers
{
public class SlackClient
{
private readonly Uri _uri;
private readonly Encoding _encoding = new UTF8Encoding();
public SlackClient(string urlWithAccessToken)
{
_uri = new Uri(urlWithAccessToken);
}
//Post a message using simple strings
public void PostMessage(string text, string username = null, string channel = null)
{
Payload payload = new Payload()
{
Channel = channel,
Username = username,
Text = text
};
PostMessage(payload);
}
//Post a message using a Payload object
public void PostMessage(Payload payload)
{
string payloadJson = JsonConvert.SerializeObject(payload);
using (WebClient client = new WebClient())
{
NameValueCollection data = new NameValueCollection();
data["payload"] = payloadJson;
var response = client.UploadValues(_uri, "POST", data);
//The response text is usually "ok"
string responseText = _encoding.GetString(response);
}
}
}
//This class serializes into the Json payload required by Slack Incoming WebHooks
public class Payload
{
[JsonProperty("channel")]
public string Channel { get; set; }
[JsonProperty("username")]
public string Username { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
}
And the other class is SlackClientTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace SlackClient.Controllers
{
public class SlackClientTest
{
void TestPostMessage()
{
string urlWithAccessToken = "https://srishti2604.slack.com/services/hooks/incoming-webhook?token=my-tokenHere.";
SlackClient client = new SlackClient(urlWithAccessToken);
client.PostMessage(username: "Mr. Torgue",
text: "THIS IS A TEST MESSAGE! SQUEEDLYBAMBLYFEEDLYMEEDLYMOWWWWWWWW!",
channel: "#general");
}
}
}
Could someone tell me what might me wrong?
My console app looks like this
SlackClient.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace SlackProject1
{
public class SlackCient
{
private readonly Uri _webhookUrl;
private readonly HttpClient _httpClient = new HttpClient();
public SlackCient(Uri webhookUrl)
{
_webhookUrl = webhookUrl;
}
public async Task<HttpResponseMessage> SendMessageAsync(string message,
string channel = null, string username = null)
{
var payload = new
{
text = message,
channel,
username,
};
var serializedPayload = JsonConvert.SerializeObject(payload);
var response = await _httpClient.PostAsync(_webhookUrl,
new StringContent(serializedPayload, Encoding.UTF8, "application/json"));
return response;
}
}
}
And the Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlackProject1
{
class Program
{
static void Main(string[] args)
{
Task.WaitAll(IntegrateWithSlackAsync());
}
private static async Task IntegrateWithSlackAsync()
{
var webhookUrl = new Uri("https://hooks.slack.com/services/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");
var slackClient = new SlackCient(webhookUrl);
while (true)
{
Console.Write("Type a message: ");
var message = Console.ReadLine();
var response = await slackClient.SendMessageAsync(message);
var isValid = response.IsSuccessStatusCode ? "valid" : "invalid";
Console.WriteLine($"Received {isValid} response.");
}
}
}
}

Trying to use SMTP with gmail

I am using smtp with gmail (already setup in my gmail account to allow it). But everytime that a different computer try to do it, gmail says that someone tryed to use my account and ask if it was me (so my confirmation e-mail isn't sended).
using Microsoft.AspNet.Identity;
using System;
using System.Configuration;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
namespace Prac.Services
{
public class EMail : IIdentityMessageService
{
#region Private Fields
private static string FromAddress;
private static string strSmtpClient;
private static string UserID;
private static string Password;
private static string SMTPPort;
private static bool bEnableSSL;
#endregion
#region Interface Implementation
public async Task SendAsync(IdentityMessage message)
{
await configSendGridasync(message);
}
#endregion
#region Send Email Method
public async Task configSendGridasync(IdentityMessage message)
{
GetMailData();
dynamic MailMessage = new MailMessage();
MailMessage.From = new MailAddress(FromAddress);
MailMessage.To.Add(message.Destination);
MailMessage.Subject = message.Subject;
MailMessage.IsBodyHtml = true;
MailMessage.Body = message.Body;
SmtpClient SmtpClient = new SmtpClient();
SmtpClient.Host = strSmtpClient;
SmtpClient.EnableSsl = bEnableSSL;
SmtpClient.Port = Int32.Parse(SMTPPort);
SmtpClient.Credentials = new NetworkCredential(UserID, Password);
try
{
try
{
SmtpClient.Send(MailMessage);
}
catch (Exception ex)
{
}
}
catch (SmtpFailedRecipientsException ex)
{
for (int i = 0; i <= ex.InnerExceptions.Length; i++)
{
SmtpStatusCode status = ex.StatusCode;
if ((status == SmtpStatusCode.MailboxBusy) | (status == SmtpStatusCode.MailboxUnavailable))
{
System.Threading.Thread.Sleep(5000);
SmtpClient.Send(MailMessage);
}
}
}
}
#endregion
#region Get Email provider data From Web.config file
private static void GetMailData()
{
FromAddress = ConfigurationManager.AppSettings.Get("FromAddress");
strSmtpClient = ConfigurationManager.AppSettings.Get("SmtpClient");
UserID = ConfigurationManager.AppSettings.Get("UserID");
Password = ConfigurationManager.AppSettings.Get("Password");
//ReplyTo = System.Configuration.ConfigurationManager.AppSettings.Get("ReplyTo");
SMTPPort = ConfigurationManager.AppSettings.Get("SMTPPort");
if ((ConfigurationManager.AppSettings.Get("EnableSSL") == null))
{
}
else
{
if ((System.Configuration.ConfigurationManager.AppSettings.Get("EnableSSL").ToUpper() == "YES"))
{
bEnableSSL = true;
}
else
{
bEnableSSL = false;
}
}
}
#endregion
}
}
GMAIL defaults to not allowing smtp access
Once you login to your Gmail account, type this into the URL bar:
https://myaccount.google.com/u/1/security?hl=en#connectedapps
At the bottom you'll see a setting "Allow less secure apps" Toggle
that to "ON"

How to use TCP client/listener in multithreaded c#?

I have written this code for my server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
private static bool terminate;
public static bool Terminate
{
get { return terminate; }
}
private static int clientNumber = 0;
private static TcpListener tcpListener;
static void Main(string[] args)
{
StartServer();
Console.Read();
}
private static void StartServer()
{
try
{
Console.WriteLine("Server starting...");
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8000);
terminate = false;
tcpListener.Start();
tcpListener.BeginAcceptTcpClient(ConnectionHandler, null);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Server stopping...");
terminate = true;
if (tcpListener != null)
{
tcpListener.Stop();
}
}
}
private static void ConnectionHandler(IAsyncResult result)
{
TcpClient client = null;
try
{
client = tcpListener.EndAcceptTcpClient(result);
}
catch (Exception)
{
return;
}
tcpListener.BeginAcceptTcpClient(ConnectionHandler, null);
if (client!=null)
{
Interlocked.Increment(ref clientNumber);
string clientName = clientNumber.ToString();
new ClientHandler(client, clientName);
}
}
}
}
class ClientHandler
{
private TcpClient client;
private string ID;
internal ClientHandler(TcpClient client, string ID)
{
this.client = client;
this.ID = ID;
Thread thread = new Thread(ProcessConnection);
thread.IsBackground = true;
thread.Start();
}
private void ProcessConnection()
{
using (client)
{
using (BinaryReader reader=new BinaryReader(client.GetStream()))
{
if (reader.ReadString()==Responses.RequestConnect)
{
using (BinaryWriter writer=new BinaryWriter(client.GetStream()))
{
writer.Write(Responses.AcknowledgeOK);
Console.WriteLine("Client: "+ID);
string message = string.Empty;
while (message!=Responses.Disconnect)
{
try
{
message = reader.ReadString();
}
catch
{
continue;
}
if (message==Responses.RequestData)
{
writer.Write("Data Command Received");
}
else if (message==Responses.Disconnect)
{
Console.WriteLine("Client disconnected: "+ID);
}
else
{
Console.WriteLine("Unknown Command");
}
}
}
}
else
{
Console.WriteLine("Unable to connect client: "+ID);
}
}
}
}
}
class Responses
{
public const string AcknowledgeOK = "OK";
public const string AcknowledgeCancel = "Cancel";
public const string Disconnect = "Bye";
public const string RequestConnect = "Hello";
public const string RequestData = "Data";
}
this code listen for client requests in a multi threaded way. I am unable to understand how can i distinguish between different clients connected to my this server and which client is disconnecting and requesting for different commands.
my client code is:
private static void clietnRequest(string message,ref string response)
{
using (TcpClient client = new TcpClient())
{
if (!client.Connected)
{
client.Connect(IPAddress.Parse("127.0.0.1"), 8000);
using (NetworkStream networkStream = client.GetStream())
{
using (BinaryWriter writer = new BinaryWriter(networkStream))
{
writer.Write(Responses.RequestConnect);
using (BinaryReader reader = new BinaryReader(networkStream))
{
if (reader.ReadString() == Responses.AcknowledgeOK)
{
response = Responses.AcknowledgeOK;
}
}
}
}
}
}
}
this piece of code connects the client to server, but i am unable to send anymore messages. I want in my app if client is connected then he can send commands to server. instead of doing this it every time act as a new client to server. I am missing some thing here, Kindly guide me in right direction. I am totally new to c# networking programming. Kindly help me improve my code. Tcp Listener and Tcp Client is valid for this scenario or do I need to use Sockets?
You are closing the connection every time client side after you send a message, if you want to do that there is nothing wrong with it but you will need to send some form of identification to the server so it can tell that this is not a new connection but a old connection connecting in for a second time. This is EXACTLY what the HTTP protocol is doing and that "identification" are internet cookies.
That first option is fine if you transmit data very infrequently but if you are doing it more often you need to keep the connection open.
Basicly you need to take the act of connecting and disconnecting out of the client request function and pass the open connection in as a argument.
private void MainCode()
{
using (TcpClient client = new TcpClient())
{
client.Connect(IPAddress.Parse("127.0.0.1"), 8000);
while(variableThatRepresentsRunning)
{
//(Snip logic that gererates the message)
clietnRequest(message, ref response, client);
//(Snip more logic)
}
}
}
private static void clietnRequest(string message,ref string response, TcpClient client)
{
if (client.Connected)
{
using (NetworkStream networkStream = client.GetStream())
{
using (BinaryWriter writer = new BinaryWriter(networkStream))
{
writer.Write(Responses.RequestConnect);
using (BinaryReader reader = new BinaryReader(networkStream))
{
if (reader.ReadString() == Responses.AcknowledgeOK)
{
response = Responses.AcknowledgeOK;
}
}
}
}
}
else
{
//Show some error because the client was not connected
}
}
By doing it this way the client object server side represents the client, you will have one instance of it per connected client and will remain associated with that client till he disconnects. If you want to track all of the connected clients you will need to insert them all in to some collection like a List<TcpClient> (either use a Concurrent Collection or use locking because you are multi-threaded) and then you will have a list of all clients (you will need to have the clients clean up after themselves so they remove themselves from the list after a disconnection).

WCF server/client callbacks, reply from client to server

In my client/server application, I want count other value in everyone client.
I made application using callbacks, but something is wrong. I get Exception, when I want call method pipeproxy.polacz(S); Which get value to server and write in server console now.
Exception is:
This operation would deadlock because the reply cannot be received until the current Message completes processing. If you want to allow out-of-order message processing, specify ConcurrencyMode of Reentrant or Multiple on CallbackBehaviorAttribute.
Other problem is, how sum resault in this funkction from all clients.
example;
client 1: S = 1;
client 2: S = 2;
client 3: S = 3;
And this function take result from all clients and sum it. So server will write 6 in server console.
My application code:
server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Interface;
namespace WCFapp
{
class Program
{
static void Main(string[] args)
{
Klienci cust = new Klienci();
cust.Connect();
}
}
}
.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Interface;
namespace WCFapp
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class Klienci : IMessage
{
private static List<ImessageCallback> subscribers =
new List<ImessageCallback>();
public void lista()
{
string nm = Console.ReadLine();
if (nm == "1")
{
Console.WriteLine("Number of conected clients: " + subscribers.Count());
funkcja();
}
}
public void Connect()
{
using (ServiceHost host = new ServiceHost(
typeof(Klienci), new Uri("net.tcp://localhost:8000")))
{
host.AddServiceEndpoint(typeof(IMessage),
new NetTcpBinding(), "ISubscribe");
try
{
host.Open();
lista();
Console.ReadLine();
host.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
public bool Subscribe()
{
try
{
ImessageCallback callback = OperationContext.Current.GetCallbackChannel<ImessageCallback>();
if (!subscribers.Contains(callback))
subscribers.Add(callback);
Console.WriteLine("Client is conected ({0}).", callback.GetHashCode());
return true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
}
public bool Unsubscribe()
{
try
{
ImessageCallback callback = OperationContext.Current.GetCallbackChannel<ImessageCallback>();
if (subscribers.Contains(callback))
subscribers.Remove(callback);
Console.WriteLine("Client is unconected ({0}).", callback.GetHashCode());
return true;
}
catch
{
return false;
}
}
public void funkcja()
{
int a = 1; int b = 3;
subscribers.ForEach(delegate(ImessageCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
Console.WriteLine("a= {0} , b= {1}", a, b);
callback.klient_licz(a, b);
a++;
b++;
}
});
}
public void polacz(int S)
{
Console.WriteLine("Sum: {0}", S);
}
}
}
Interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Interface
{
[ServiceContract(CallbackContract = typeof(ImessageCallback), SessionMode = SessionMode.Required)]
public interface IMessage
{
[OperationContract]
void funkcja();
[OperationContract]
void polacz(int S);
[OperationContract]
bool Subscribe();
[OperationContract]
bool Unsubscribe();
}
[ServiceContract]
public interface ImessageCallback
{
[OperationContract]
void klient_licz(int a, int b);
}
}
Client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Interface;
namespace Client
{
class Program
{
static void Main(string[] args)
{
clients cl = new clients();
if (cl.Conect() == true)
{
string tmp = Console.ReadLine();
while (tmp != "EXIT")
{
cl.SendMessage(tmp);
tmp = Console.ReadLine();
}
}
cl.Close();
Environment.Exit(0);
}
}
}
.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Interface;
namespace Client
{
class clients : ImessageCallback, IDisposable
{
IMessage pipeProxy = null;
public bool Conect()
{
DuplexChannelFactory<IMessage> pipeFactory =
new DuplexChannelFactory<IMessage>(
new InstanceContext(this),
new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:8000/ISubscribe"));
try
{
pipeProxy = pipeFactory.CreateChannel();
pipeProxy.Subscribe();
return true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
}
public void Close()
{
pipeProxy.Unsubscribe();
}
public void klient_licz(int a, int b)
{
int S = a + b;
Console.WriteLine("Sum= {0}", S);
pipeProxy.polacz(S); //ERROR
}
}
}
The issue here is that inside your callback method klient_licz (which is called by the server) you are making another server call. This is not allowed the way your contracts are currently setup.
Check you really need this behaviour. Do you really need to make a server call INSIDE a method on the callback interface (klient_licz).
If you do need this behaviour then you might be able to fix things by marking the klient_licz call OneWay on the callback interface. That will mean that server call to the callback will not block until the client returns (which is what is currently causing your issue because the server is waiting for the client call to return but the client call is waiting on a call to the server):
[ServiceContract]
public interface ImessageCallback {
[OperationContract(IsOneWay = true)]
void klient_licz(int a, int b);
}
Alternatively you could mark the callback implimentation with a concurrancy mode other than the default mode Single. Eg Reentrant as follows - but bear in mind that this means that calls to callback will not long be marshalled to the UI thead ie will be on threadpool threads so you would have to dispatch to update the UI from method on the callback interface:
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class clients : ImessageCallback, IDisposable {
...
}
If you want to understand ConcurrencyMode and how it effects execution then you will really need to do someback ground reading as it does get a little complicated - but if you dont have that background it is difficult to really understand what is happen when you change the ConcurrencyMode. This dasBlonde blog post has a good summary of the different modes and behaviour - but you might want to start with some tutorials that are a bit more beginner orientated.

Categories