SmtpClient in C# when need to load Configurations in code not app.config - smtpclient

I have a function in my class to send emails using SmtpClient.
public void Send(System.Net.Mail.MailMessage mail)
{
using (SmtpClient client = new SmtpClient())
{
client.Host = ConfigReader.SmtpHost;
client.Port = ConfigReader.SmtpPort;
client.EnableSsl = ConfigReader.SmtpEnableSsl;
client.UseDefaultCredentials = ConfigReader.SmtpDefaultCredentials;
client.Credentials = new NetworkCredential(ConfigReader.SmtpUserName, ConfigReader.SmtpPassword);
client.Send(mail);
}
}
I need to set Smtp configs using another class in this function. But it does not seem right to set configuration every time this function is called.
What's the better approach for this? If I load the configuration in some other Init function to be called only once, how would SmtpClient will be disposed off in that case?

You create your SmtpClient object locally and more over in using statement as the object disposes out of scope your function. You must configure your object every time when you create them.

Related

unable to access controller functions in command line or console application

I am preparing a console application and making a connection to database using container of entity manager. This works fine. Code is below
protected function execute(InputInterface $input, OutputInterface $output)
{
// get Doctrine
$this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
// find all disc that are not treated by Manager in last week i.e sysdate - 6
$pendingApprovals = $this->em->getRepository('GMRestBundle:TDtlsDisc')->getPendingManagerAppoval();
// for each unapproved disc, start sending emails
$repository = $this->em->getRepository('GMRestBundle:TDtlsDisc');
$emailReminder = new SubmitDisclosureController();
foreach($pendingApprovals as $labManagerReview) {
$tDtlsDiscEntity = $repository->findByDiscId($labManagerReview['DISC_ID']);
$emailReminder->sendMailToLabManager($tDtlsDiscEntity);
}
}
Now, the issue is it is giving error when I call thsi $emailReminder->sendMailToLabManager($tDtlsDiscEntity); which will in turn makes a connection of orm and get some data from database. This sendMailToLabManager is in SubmitDisclosureController and the code is below.
public function sendMailToLabManager($tDtlsDiscEntity)
{
$repository = $this->getDoctrine()->getRepository('GMRestBundle:TXrefDiscSso');
$entityRepository = $this->getDoctrine()->getRepository('GMRestBundle:TDtlsEntity');
$discId = $tDtlsDiscEntity->getDiscId();
.......
In console application, I am no able to use any controller which access DB by making another connection to doctrine object. Same controller if I called through another action controller in web, it works well.
Error: Call to a member function has() on null
I see this above error message now.
You should create a service which provides the function instead of using the controller. After that you have to insert the EntityManager via dependency injection in to the the service.
If your command extends ContainerAwareCommand you can use $this->get() inside your command to retrieve the service you have defined before.

How to set Azure WebJob queue name at runtime?

I am developing an Azure WebJobs executable that I would like to use with multiple Azure websites. Each web site would need its own Azure Storage queue.
The problem I see is that the ProcessQueueMessage requires the queue name to be defined statically as an attribute of the first parameter inputText. I would rather have the queue name be a configuration property of the running Azure Website instance, and have the job executable read that at runtime when it starts up.
Is there any way to do this?
This can now be done. Simply create an INameResolver to allow you to resolve any string surrounded in % (percent) signs. For example, if this is your function with a queue name specified:
public static void WriteLog([QueueTrigger("%logqueue%")] string logMessage)
{
Console.WriteLine(logMessage);
}
Notice how there are % (percent) signs around the string logqueue. This means the job system will try to resolve the name using an INameResolver which you can create and then register with your job.
Here is an example of a resolver that will just take the string specified in the percent signs and look it up in your AppSettings in the config file:
public class QueueNameResolver : INameResolver
{
public string Resolve(string name)
{
return ConfigurationManager.AppSettings[name].ToString();
}
}
And then in your Program.cs file, you just need to wire this up:
var host = new JobHost(new JobHostConfiguration
{
NameResolver = new QueueNameResolver()
});
host.RunAndBlock();
This is probably an old question, but in case anyone else stumbles across this post. This is now supported by passing a JobHostConfiguration object into the JobHost constructor.
http://azure.microsoft.com/en-gb/documentation/articles/websites-dotnet-webjobs-sdk-storage-queues-how-to/#config
A slight better implementation of name resolver to avoid fetching from configuration all time. It uses a Dictionary to store the config values once retrieved.
using Microsoft.Azure.WebJobs;
using System.Collections.Generic;
using System.Configuration;
public class QueueNameResolver : INameResolver
{
private static Dictionary<string, string> keys = new Dictionary<string, string>();
public string Resolve(string name)
{
if (!keys.ContainsKey(name))
{
keys.Add(name, ConfigurationManager.AppSettings[name].ToString());
}
return keys[name];
}
}
Unfortunately, that is not possible. You can use the IBinder interface to bind dynamically to a queue but you will not have the triggering mechanism for it.
Basically, the input queue name has to be hardcoded if you want triggers. For output, you can use the previously mentioned interface.
Here is a sample for IBinder. The sample binds a blob dynamically but you can do something very similar for queues.

Move a file after an email is sent

I am writing a program that looks for files in a folder, attaches the files to the MailMessage and sends an email using SmtpClient.
After the email is sent out successfully, I want to move the emailed files to a different folder.
I get this message "The process cannot access the file because it is being used by another process.". I tried Thread.Sleep() but did not work.
smtpClient.Send(mail);
foreach (var report in reports)
{
string source = Path.Combine(reportsFolder, report);
string destination = Path.Combine(sentReportsFolder, report);
File.Move(source, destination);
}
First, try to dispose your smtpclient class:
smtpClient.Send(mail);
smtpClient.Dispose();
http://msdn.microsoft.com/pt-br/library/system.net.mail.smtpclient.dispose.aspx
But, when creating the class, you could use an using statemant.
Like:
using (SmtpClient smtpClient = new SmtpClent()) {
//attach file
smtpClient.Send();
}
This will ensure that, after send an email, the class will releases any resources that might be locked by the class. So, you not need to call .Dispose() explicitly.
http://msdn.microsoft.com/pt-br/library/system.net.mail.smtpclient.aspx
http://msdn.microsoft.com/en-us/library/yh598w02.aspx

How to Ignore wsit-client.xml when calling web service if exists

The application I am working on calls many webservice. Just recently I have intergrated another web service that requires wsit-client.xml for Soap authentication.
That is working now but all the other SOAP services have stopped working.
Whenever any of them is being called, I see messages like
INFO: WSP5018: Loaded WSIT configuration from file: jar:file:/opt/atlasconf/atlas.20130307/bin/soap-sdd-1.0.0.jar!/META-INF/wsit-client.xml.
I suspect this is what is causing the Service calls to fail.
How can I cause the wsit-client.xml to be ignored for certain soap service calls?
Thanks
Fixed it by Using a Container and a Loader to configure a dynamic location for the wsit-client.xml. This way it is not automatically loaded. To do that, I first implemented a Container for the app as shown below
public class WsitClientConfigurationContainer extends Container {
private static final String CLIENT_CONFIG = "custom/location/wsit-client.xml";
private final ResourceLoader loader = new ResourceLoader() {
public URL getResource(String resource) {
return getClass().getClassLoader().getResource(CLIENT_CONFIG);
}
};
#Override
public <T> T getSPI(Class<T> spiType) {
if (spiType == ResourceLoader.class) {
return spiType.cast(loader);
}
return null;
}
}
Then to use it in the Code I do this
URL WSDL_LOCATION = this.getClass().getResource("/path/to/wsdl/mysvc.wsdl");
WSService.InitParams initParams = new WSService.InitParams();
initParams.setContainer(new WsitClientConfigurationContainer());
secGtwService = WSService.create(WSDL_LOCATION, SECGTWSERVICE_QNAME, initParams);
And it works like magic

Flash Builder (Mobile) - Dynamic Web Service URL

For my Flash Builder 4.6 Project I have a http service defined which looks at a url from our website.
What I'd like to be able to do though is to change the web service url on the fly within the app. i.e. using the existing url as default but having an admin/settings screen to change where the web service points (either stored in our sqlite database or in local memory).
This would be so that we could allow our customers to host their own version of the website/database but still be able to use/download the app through the app stores.
Has anyone had any experience with doing this?
EDIT: Adding some more details after the comments below.
When I created the HTTP Service through the FlashBuilder wizard it creates two web service classes a super class and a sub class which inherits from the super class. All of the code that the wizard populates goes into the super class.
I can assume that the code I need to put in would be in the sub class. But I do not know which function I'd put it in or how.
Below is a sample of the Super's constructor:
// initialize service control
_serviceControl = new mx.rpc.http.HTTPMultiService("websitehere");
var operations:Array = new Array();
var operation:mx.rpc.http.Operation;
var argsArray:Array;
operation = new mx.rpc.http.Operation(null, "loginRequest");
operation.url = "login.php";
operation.method = "GET";
argsArray = new Array("un","pw");
operation.argumentNames = argsArray;
operation.serializationFilter = serializer0;
operation.properties = new Object();
operation.properties["xPath"] = "/";
operation.contentType = "application/x-www-form-urlencoded";
operation.resultType = valueObjects.Data;
operations.push(operation);
_serviceControl.operationList = operations;
I'm not sure what property of the _serviceControl variable I would need to alter.
Also when I search for my website in my code it brings back a .fml file inside a .model directory which seems to get auto refreshed if I change the service url through the wizard. Would this not cause an issue?
I then have the challenge of accessing the user defined url. Within the app we use an sqlite database to store data but I think it would probably be better to use a 'SharedObject' which we also use to know what account they are logged into. How reliable is this? I assume I would be able to access this via the Service?
Though the awkward thing is that we were planning to have this configurable on a settings screen that would have been accessed after logging in. But to log in it would already need to know which server to point to.
if im reading your question correctly then your main ambition is to dynamically change the url for the services based on a user defined variable.
This is very easy to accomplish and even easier to accomplish if you are using parsley / spicelib.
a few points
dont change the code in the super file, this will get overwritten whenever the service gets refreshed. change everything in its generated sub-Class.
Shared Objects are very good for small quantities of data but should never be used for massive datasets i.e storing a big arraycollection.
Anyway here is how i achieve this.
In the SubClass you can change the constructor function.
Here is how i change my urls based on a config variable but you can just as easily use a SharedObject instead.
public function SubClassConstructor(){
if(CONFIG::DOMAIN_IDENT == "development" || CONFIG::DOMAIN_IDENT == "dev" || CONFIG::DOMAIN_IDENT == "d"){
_serviceControl.endpoint = "http://yoururl1";
}
else if(CONFIG::DOMAIN_IDENT == "production" || CONFIG::DOMAIN_IDENT == "prod" || CONFIG::DOMAIN_IDENT == "p"){
_serviceControl.endpoint = "http://yoururl2";
}
}
Of course this isn't exactly what your looking for but its a working solution, of course you can use Bindings to a Global ApplicationModel or direct reference to the SharedObject i guess you already know how to use the SharedObject.
Ask if you need any further help or guidance.
As cghrmauritius' solution didn't quite work for me, I am posting up the final solution that did work in my situation.
public function subConstructor()
{
super();
_serviceControl.baseURL = "http://url1";
}
Obviously for my final solution I need to implement the shareobject as well but overriding the url was my main priority.