Shopping Basket Basket (0 Items)
Ginko Solutions Ginko Solutions Enabling innovative solutions since 1999.

TutorialGenius.com Technical Blog

Welcome to the Ginko Solutions blog. This page provides various tips, projects and helping aides for software developers and web developers. The blog is updated weekly and the latest entries appear within this page. To view the full Ginko Solutions blog, please click the following link

How To Remove Packages With RPM "Error: ... Specifies Multiple Packages "
Simple steps to remove multiple packages installed on your linux box


$rpm -qa|grep e2fsprogs*
e2fsprogs-libs-1.39-15.el5
e2fsprogs-libs-1.39-15.el5
e2fsprogs-devel-1.39-15.el5
e2fsprogs-1.39-15.el5
e2fsprogs-devel-1.39-15.el5


You will see a duplicate files e2fsprogs-libs-1.39-15.el5 and gets the following error
error: "e2fsprogs-libs-1.39-15.el5" specifies multiple packages


You can solve this problem with the command below..
$rpm -e --allmatches e2fsprogs-libs-1.39-15.el5



Python - Sending emails using smtplib
Here is a snippet that will send emails to one or more recipients. It will also send the name alongside the FROM email address.

Just plug in the SMTP server details and toggle AUTH if required.


Send an email to one or more recipients

import smtplib
import email.utils
from email.mime.text import MIMEText
from email.utils import formataddr


def emailer():

# Email Settings
MESSAGEBODY = 'Test Email body.'
SUBJECT = 'Test Email Subject'
FROM = ('Some User', 'donotreply@someurl.com')
TO = ['recipient1@someurl.com', 'recipient2@someurl.com']

# SMTP Settings
smtpserver = 'SMTP SERVER ADDRESS'
smtpport = 25
AUTHREQUIRED = 0 # If you need to use SMTP AUTH set to 1
smtpuser = 'foo' # For SMTP AUTH, set SMTP username here
smtppass = 'bar' # For SMTP AUTH, set SMTP password here

# Create the message
msg = MIMEText(MESSAGEBODY)
msg['To'] = ', '.join(TO)
msg['From'] = email.utils.formataddr(FROM)
msg['Subject'] = SUBJECT

try:
smtpObj = smtplib.SMTP(smtpserver, smtpport)

if AUTHREQUIRED:
session.login(smtpuser, smtppass)

smtpObj.sendmail(msg['From'], TO, msg.as_string())

print "Email has been sent successfully to: " + msg['To']
except Exception, err:
print "Error: unable to send error email notification. %s" % str(err)



# Invoke Emailer
emailer()




Python Email Examples
http://docs.python.org/library/email-examples.html



Linux - Installing and configuring Proftpd with SFTP (mod_sftp)
I recently upgraded Proftpd on a CentOS box and added mod_sftp as a static module... This post will explain what the hell I have just said, and also, how to set it setup and running. I will include gotcha's (plenty!) and some general helpful advice along the way.

We will be building from source in this guide, so I recommend grabbing that one from the download site. Download Proftpd from their website Here. Take ProFTPD 1.3.3rc1 or later as this includes mod_sftp.




Prerequisites

1. You will need to install a copy of the OpenSSL source, if you haven't already. If you have it installed, check it's in your PATH. When compiling Proftpd, it requires some header files from the OpenSSL-dev release, so this is a must!

You can download OpenSSL from Here. Grab the latest non-beta if its going to go into production. That's the rule!

Here is a guide on installing OpenSSL



2. You also need the dev libraries for zlib. These can be found Here. Install them using the supplied ReadMe file. It will be something like this...


./configure
make
make install




Things to note


Modules

There are some things to note before we get onto the configuration phase of Proftpd... Proftpd has numerous modules, each which aide different aspects of the FTP server. FOr example, for FTPS we use the mod_tls module.... for SFTP, we iuse mod_sftp module... To integrate FTP user accounts with a backend mysql database, we use mod_mysql and mod_sql_mysql. etc....

Note: Some modules are not compiled by default! mod_sftp being one of them...

While there are a lot of modules included as standard, you can download other modules Here


Static Modules vs. DSO's (Dynamic Shared Objects)

Modules can either be statuc or in DSO form. A static module basically means you are compiling it into the Proftpd compilation. On the other hand, a DSO Will be a seperate physical file of the library that is loaded in dynamically. DSO's allow you to drop modules in quickly- without re-compiling Prtoftpd each time.

Read more on DSO's in Proftpd Here



Installation

1. First we need to configure the installation of Proftpd. This is where you will need to decide

- How you want your modules to be represented (Static or DSO)
- What modules you actually want to include with the installation

I will be including mod_sftp in this installation, and im going to make it static.



2. Browse to the directory where the Proftpd source is, and execute the following command... Check the file paths beforehand though!


./configure --prefix=/usr --with-includes=/usr/local/ssl/include --with-libraries=/usr/local/ssl/lib --enable-openssl --with-modules=mod_sftp --enable-dso



--prefix
Where Proftpd will be installed to. I'm using CentOS as a root user, so it will be placed in /usr/sbin

--with-includes
You need to specify the include directory for the dev installation of OpenSSL. This include directory will include the development library headers which Proftpd requires to build in mod_sftp support. You can add more paths to this parameter as you wish, seperated by a colon.

--with-libraries
Similar to above but these will point to the OpenSSL libraries.

--enable-openssl
Required to enable OpenSSL for mod_sftp

--with-modules=mod_sftp
Include the sftp module. You can specify more by adding a colon after each module name.

--enable-dso
This is for DSO modules only, but I have included it as I already had some modules built with a previous version, and wanted to include them.

Note: If you wish to use DSO's (Shared Modules)... then replace --with-modules with --with-shared and ensure --enable-dso is included. Simple!


More info on compiling can be found Here


3. Produce the Makefile

make



4. Install

make install





Installation - Troubleshooting


In file included from mod_sftp.c:30:
mod_sftp.h:83:18: error: zlib.h: No such file or directory
make: *** [mod_sftp.lo] Error 1


You didn't install the zlib-dev development libraries. See prerequisites above!


/usr/bin/ld: cannot find -lcrypto
collect2: ld returned 1 exit status
make: *** [shared] Error 1


or

/usr/bin/ld: openssl/crypto.h: No such file or directory
make[1]: *** [support.o] Error 1
make[1]: Leaving directory `/src/proftpd-1.3.2b/src'
make: *** [src] Error 2



You didn't install the OpenSSL development libraries. See prerequisites above! Ensure the libraries AND headers are present.




Configuration

1. Check proftpd has registered itself correctly and that your static modules have been installed. Execute the following command...


proftpd -l


mod_sftp should be included in the list here.



2. Check the correct version has been installed and verify the location of the proftpd configuration file. Execute the following command...


proftpd -V


The version should match (Just incase an upgrade went wrong!) and you can see which configuration file Proftpd is using here... It should reside within the /etc directory of the --prefix specified when configuration the installation. I.e. /usr/etc/proftpd.conf



3. Open proftp.conf with your favourite text editor. The config file has the same syntax as Apache server configs, so it's easier to get to grips with.

View sample configurations Here

If you take a look at the Complex Virtual example, you can see how different VirtualHosts are configured.

Note: The Global tag contains settings that wiull be included across all VirtualHost's within the configuration file. Therefore, there is only ever one instance of the Global tag.



4. Take a copy of this file, and setup your Virtual hosts based on this format. You can even use the simple config file to start with. However, it is useful to understand what is possible here.



5. Save your proftpd.conf file and restart the proftpd service.
See this link for restarting services on various distros of Linux: http://theos.in/desktop-linux/tip-that-matters/how-do-i-restart-linux-network-service/

This ensures the latest config is read and is compatible before we continue.

[root@servername proftpd]# service proftpd restart
Shutting down proftpd: [ OK ]
Starting proftpd: [ OK ]




6. Keep the proftpd.conf file open and add the following for SFTP support.

<IfModule mod_sftp.c><VirtualHost xx.xx.xx.xx>
SFTPEngine on
SFTPLog /etc/proftpd/sftp/sftp.log

# Configure the server to listen on port
Port 2222

# Configure both the RSA and DSA host keys, using the same host key
# files that OpenSSH uses.
SFTPHostKey /etc/ssh/ssh_host_rsa_key
SFTPHostKey /etc/ssh/ssh_host_dsa_key


# Configure the file used for comparing authorized public keys
SFTPAuthorizedUserKeys file:/root/.ssh/authorized_keys

# Enable compression
SFTPCompression delayed

# Allow the same number of authentication attempts as OpenSSH.
#
# It is recommended that you explicitly configure MaxLoginAttempts
# for your SSH2/SFTP instance to be higher than the normal
# MaxLoginAttempts value for FTP, as there are more ways to authenticate
# using SSH2.
MaxLoginAttempts 6

</VirtualHost></IfModule>



Note: Replace xx.xx.xx.xx with IP or hostname on which to accept incoming connections.

Note: Set the port for SFTP. If you have OpenSSH installed, you will either need to change the port OpenSSH uses, or change the port within this VirtualHost. I have opted for the latter, and use port 2222 for SFTP connections. You can't have two things on one port! Check what is running on certain ports using netstat.


netstat -tulpn



Note: The SFTPAuthorizedUserKeys attribute points to an authorized_keys file or public key authentication. Huh?? See my guide here on what it is and how to get setup

Note: You will notice the VirtualHost is wrapped within an IfModule tag. This is a condition that will granted true if the mod_sftp loaded correctly.



7. Restart the Proftpd service and test the connectivity using an FTP client.


lftp sftp://user@server:port (I.e. lftp sftp://sean@server:2222)

or

sftp user@server:port (I.e. sftp sean@server:2222)



You can also use FileZilla by setting the connectivity type to SFTP and specifying your configured port (I.e. 2222).





OPTIONAL: Module Configuration (DSO Configuration Only)

If you would like to include DSO's into the proftpd configuration, then open the Proftpd.conf file and add the following line...

Include                         /path/to/modules.conf


This path should point to an empty file called modules.conf. You can create this using your favourite text editor.

Now open up your newly created modules.conf file and add the following...


# This is the directory where DSO modules reside
ModulePath /usr/libexec/proftpd

# Allow only user root to load and unload modules, but allow everyone
# to see which modules have been loaded
ModuleControlsACLs insmod,rmmod allow user root
ModuleControlsACLs lsmod allow user *

# Load the modules
LoadModule MODULENAMEHERE1.c
LoadModule MODULENAMEHERE2.c
LoadModule MODULENAMEHERE3.c


The directory you specified within the ModulePath attribute should point to the directory where your DSO's reside. Now replace MODULENAMEHERE with the name of your modules.
Once you have done this, you may need to restart the Proftpd service for the changes to take effect.






Useful features and Debugging help



Proftpd Debug mode

You can place Proftpd in debugging mode using the following command...

ptoftpd -nd10


Please note, that you will have to stop the Proftpd service first, or you will get an 'address in use' error. Makes sense!

How to stop a service: http://theos.in/desktop-linux/tip-that-matters/how-do-i-restart-linux-network-service/

This is level 10 debugging and will show you connecting clients and all activity within the console output. Very useful to troubleshoot connectivity issues and auth.

Full documentation on debugging Here




Trace Logging
The mod_sftp module supports different forms of logging. The main module logging is done via the SFTPLog directive. For debugging purposes, the module also uses trace logging, via the module-specific "scp", "sftp", and "ssh2" log channels. Thus for trace logging, to aid in debugging, you would use the following in your proftpd.conf:


TraceLog /path/to/sftp-trace.log
Trace scp:20 sftp:20 ssh2:20


This trace logging can generate large files; it is intended for debugging use only, and should be removed from any production configuration.



mod_sftp Documentation Here





Logging

See the official guide on how logging can help you debug Proftpd. Logging documentation can be viewed Here





Where is proftpd?
which -a proftpd





Any problems or issues, please leave a comment and I will assist you where I can. I wrote this up from my notes, and im confident I have included most of the vital parts!


Shoutouts for the 200th BLOG POST!!!



Unix/Linux - Setting up public key authentication [SFTP/SSH/SCP etc]
Today I had the task of setting up public key authentication onto an existing system. The primary task was to ensure that you could send a file via SFTP without a password (password authentication). Joy!


Public key authentication - What the...?
This is basically an authentication method, just like specifying a username and a password (password auth).... The only difference is that a 'key' (some long encrypted string) is generated on a client machine, and the server is made aware of this in a config file. So when the client attempts to connect, the server will check the config, realise its the client, match it against the username, and we're in! Sounds easy I guess.... The basic aim is to get in without a password, while still maintaining security....


Let's start with the client (The machine you want to connect from)



Client Configuration


Note: Firstly, use the user which you wish to allow public key authentication for. We will be storing the keys in the $HOME directory, so make sure you've switched to the correct user from the start.


1. Generate a public and private key. Run this command...
ssh-keygen -t dsa



Example

[root@someserver ~]# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa): /root/.ssh/id_dsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
blah:blah:blah:blah:blah:blah:blah:blah:blah:blah root@someserver

Note:
- I am using the root user here... root will be replaced by the name of your user.
- I used the same path with was hinted by the ssh-keygen utility. The keys should be generated within your $HOME dir under the .ssh directory. I would maybe rename id_dsa to something else, as this is the default name. Just a security consideration as somebody could search for your keys using the default name.
- Leave passphrase blank for getting this up and running. It just means you would have to provide the phrase in future.


In this example....
Private Key: /root/.ssh/id_dsa
Public Key: /root/.ssh/id_dsa.pub


You public key is the one you advertise... the private key, never let out of your sight! It's as good as a password to gain entry! But you know that already right?



2. Set permissions if you haven't already... security is number 1!

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub



3. Open the public key file and copy the contents. I recommand not using 'more' to copy because it puts new lines in where the console window wraps. Use something like vi text editor.


4. Keep this public key content handy because we'll need to tell the server about it!



Server Configuration

Note: I will assume you are logged in as a root user here.

1. First of all, lets enable publickey authentication! Open the sshd_config file for editing. I personally use vi. sshd_config is either in /etc/ , /etc/ssh/ or /etc/conf.d/

Mine is here: /etc/ssh/sshd_config


2. You need to enable RSAAuthentication and PubkeyAuthentication... You may need to uncomment those lines. Also, set the AuthorizedKeysFile to point to the authorized_keys file on the server. This file sits in the .ssh directory with the $HOME dir (Just like in the client config). However, we are using the root user, so it should be here: /root/.ssh or simply: ~/.ssh. Check the path is correct before you save.


RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile ~/.ssh/authorized_keys



3. Save changes and close sshd_config. I usually restart the sshd service just incase.

service sshd restart


See this link for restarting services on various distros of Linux: http://theos.in/desktop-linux/tip-that-matters/how-do-i-restart-linux-network-service/


4. Now lets tell the server about our client's public key! Exciting right? Navigate to the .ssh directory (as discussed in step 2). Either open or create the file authorized_keys. This will contain various public keys for connecting clients. Edit this file and add the public key from step 3 in the client configuration. One entry per line if you already have content within there. Save the file.


5. Lets test!



Testing

1. Go back to your client and attempt to SSH onto your server.


ssh username@servername


You can also force ssh to use publickey auth (you may have various types of auth enabled).


ssh -vvv -o PreferredAuthentications=publickey username@servername



2. Simple SFTP test.

sftp username@servername




Any problems, please comment and I can assist where necessary! Have fun I guess....



Unix/Linux - Packet Analyzers - snoop and tcpdump
snoop
snoop is a very flexible command line packet analyzer included as part of Sun Microsystems' Solaris operating system.


tcpdump

tcpdump is a common packet analyzer that runs under the command line. It allows the user to intercept and display TCP/IP and other packets being transmitted or received over a network to which the computer is attached.


Examples

Troubleshoot a host
snoop -v -d qfe0 -x0 host 192.168.1.87
tcpdump -i en0 host 192.168.1.87


Exclude the host you're connected from

snoop -x0 -d hme0 not host 192.168.1.20
tcpdump -i eth0 not host 192.168.1.20

View only SSL packets
snoop -x0 port 443
tcpdump port 443


For more examples, view the man pages.



Linux - Manually and automatically adding system users
Please view this link for an indepth guide on how to add system users to /etc/passwd
http://floppix.ccai.com/adduser.html



Please Note

[root@server seantest]# passwd seantest
Changing password for user seantest.
passwd: Authentication token manipulation error


If u are running shadowed passwords there might be no entry for this user.


1. Make a backup of /etc/shadow (cp /etc/shadow /etc/shadow.backup)

2. Delete /etc/shadow (rm /etc/shadow)

3. Convert /etc/passwd using password convert (pwconv)


And the same for groups...

1. Make a backup of /etc/gshadow (cp /etc/gshadow /etc/gshadow.backup)

2. Delete /etc/gshadow (rm /etc/gshadow)

3. Convert /etc/group using group convert (grpconv)



Full path of service and service temporary directory when running
Execute the following command to view all processes and do a search of a service name (The service your searching for)
ps auxwwwe | grep SERVICENAMEHERE



This will give you back some info about the service. We are really only interested in the ProcessID (PID). This will be an integer.


Example return
root 24466 0.0 0.0 1476 280 ? S 2009 0:00 supervise sshd


PID will be: 24466


So now navigate to /proc and view the contents. You will see a directory for your PID. View the contents of this directory to see the info for the service.

The file path is located @ exe in this example: exe -> /usr/sbin/servicename



proftpd - Adding FTPS Support
This guide assumes you have proftpd installed with OpenSSL libs. If not, follow this guide


Firstly, I will quickly say....


FTPS or SFTP

People intend to mix FTPS and SFTP together, but both are actually completely differend.

FTPS is a normal FTP server but using SSL encrytion.
SFTP is a ftp kind of session over SSH (so everything is encrypted just like in SSH).



Notes
Users Guide: http://proftpd.org/localsite/Userguide/linked/userguide.html


Steps

*** Ensure mod_tls module is available within your proftpd installation.
*** Ensure you are a root user


1. Open proftpd.conf and add an include to a config file we are going to create (tls.conf). Add the following line below...

Include         /etc/proftpd/tls.conf




2. Now use vi to create the config file in the specified location...

vi /etc/proftpd/tls.conf




3. Enter the following information into the file (How to use vi)


# Proftpd sample configuration for FTPS connections.

#

# Note that FTPS impose some limitations in NAT traversing.

# See http://www.castaglia.org/proftpd/doc/contrib/ProFTPD-mini-HOWTO-TLS.html

# for more information.

#

 

 

<IfModule mod_tls.c>

TLSEngine                               on

TLSLog                                  /var/log/proftpd/tls.log

TLSProtocol                             SSLv23

TLSRSACertificateFile                   /etc/proftpd/ssl/proftpd.cert.pem

TLSRSACertificateKeyFile                /etc/proftpd/ssl/proftpd.key.pem

#

# Avoid CA cert and allow client renegotiation (to overcome 1.3.2c bug 3324)

#TLSOptions                             NoCertRequest AllowClientRenegotiation

#

# Authenticate clients that want to use FTP over TLS?

#

TLSVerifyClient                         off

#

# Are clients required to use FTP over TLS when talking to this server?

#

TLSRequired                             on

#

# Allow SSL/TLS renegotiations when the client requests them, but

# do not force the renegotations.  Some clients do not support

# SSL/TLS renegotiations; when mod_tls forces a renegotiation, these

# clients will close the data connection, or there will be a timeout

# on an idle data connection.

#

TLSRenegotiate                          required off

</IfModule>




4. Generate certificate using OpenSSL

openssl req -new -x509 -days 365 -nodes -out /etc/proftpd/ssl/proftpd.cert.pem -keyout /etc/proftpd/ssl/proftpd.key.pem





5. Save and close the file.


6. Now restart proftpd for the changes to take effect.

/etc/init.d/proftpd restart




7. Test FTPS connectivity with the server. See below...
Note: if there are any issues with the connection process, check the log file within the tls.conf file we created: /var/log/proftpd/tls.log


Testing FTPS with lftp

1. Execute following command

lftp -u USERNAMEHERE -e 'set ftp:ssl-force true,ftp:ssl-protect-data true' SERVERNAMEHERE




2. Enter password for user.


3. Perform a simple command. I.e. ls -l



Solaris 9 [SunOS 5.9] - Installing Python [This example uses 2.7.2 and Optional SSL]
This is a simple guide on how to install python on a Solaris 9 system. There are a few gotcha's which I am sharing and writing for future use.

1. Download Python. I took the compressed source tarball (.tgz). You are essentially compiling the source on your system.

2. Optional: Transferring it to the server. I had to transfer it to the server to install, so if you need to do that, see my previous post

3. Unzip the package using the following command. It will unzip, then untar.

gunzip -c PYTHONFILENAME.tgz |tar xvf -

4. You now need to configure the source. This will produce a Makefile based on your system. Navigate to the Python source directory, and execute the following command...

./configure --prefix=/usr/local

5. Now we need to compile our Makefile that has been created.


make


6. Ensure you are a root user before this step ("su root" - to change). Execute the following command to install Python.


make -i install


7. If everything went well (it probably didn't - see below!). Add Python to your system PATH variable. This way, you don't need to refer to /usr/local everytime you execute a script. See my previous blog post on how to do this.

8. Simply execute the following command to check Python has set itself up correctly... Do this outside of the source directory, so you can test the PATH variable aswell.

python --version

9. Get an ice cold beerski in!




Troubleshooting


During the make procedure, you receive the following...

./Parser/asdl_c.py -c ./Python ./Parser/Python.asdl
/usr/bin/env: No such file or directory
make: *** [Python/Python-ast.c] Error 127


Simply touch the libraries it requires (see below), and re-try... (Run make clean before re-try)

touch Include/Python-ast.h Python/Python-ast.c




During the install procedure, you receive the following...

make: ar: Command not found

You need to add ar to your PATH variable. This is located in /usr/ccs/bin. See my previous blog post on how to do this.


Note: If you are receiving an error while re-trying or you wish to remove temporary install files, simply execute the following command... "make clean"



Optional: Adding SSL Support to Python
Python needs to be compiled with SSL support... You can enable this by firstly installing the OpenSSL development libraries (libssl-dev download here) before the initial Python installation. Ensure you can open the OpenSSL console by typing openssl... If not, add it to your PATH. You then uncomment a few lines from the Modules/Setup.dist file.

Open the 'Modules/Setup.dist' file for editing, and uncomment the following lines (Assuming you installed OpenSSL to the default location)...


204:# Socket module helper for SSL support; you must comment out the other
205:# socket line above, and possibly edit the SSL variable:
206:SSL=/usr/local/ssl
207:_ssl _ssl.c \
208: -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
209: -L$(SSL)/lib -lssl -lcrypto</pre>


Save and close the file... then copy the file to /Setup. Otherwise Python will warn you this this file is newer than the Setup copy. You can now proceed to install Python with the instructions as above.

You can verify the installation by running the following test script...


python /usr/local/lib/python2.5/test/test_socket_ssl.py
test_rude_shutdown ...
test_basic ...
test_timeout ...



Bash/sh/csh/tcsh - Updating PATH environment variable in session and on logon
When updating your PATH varible, it's usually because an installation requires programs and utilities within a directory, and the knowledge of the full path is not known. Either that, or you would like to refer to a command program within specifying the full path. You will usually receive the following error message if a program cannot be found...

xxx: Command not found



So lets check our current PATH using the following command...

echo $PATH


We can now view the current directories included in our PATH variable.
Example: /usr/sysmgr/bin:/bin:/usr/sbin:/usr/bin:/usr/ucb:/usr/sysmg/bin:/etc:/usr/local/bin:.


For example, we may wish to install a program, and it requires the ar tool (A tool to aid archiving). It is unaware of the full system path, so we need to add the directory it resides in to our environment variable.

We can either do this temporarily or permanently... It also depends on which shell you are using.


Note: To find out which shell you are using, execute the following command.

echo $SHELL



Temporarily


tcsh/csh Shell
(Seperate by spaces and use set command)
set path=(/usr/sysmgr/bin /bin /usr/sbin /usr/bin /usr/ucb /usr/sysmg/bin /etc /usr/local/bin .)


bath/sh Shell
(Seperate by colon and use export command)
export PATH=$PATH:/path/to/dir1:/path/to/dir2



Permanently

Bash Shell (Edit /.bash_profile or /.bash_profile files)
http://www.cyberciti.biz/faq/change-bash-profile/

tcsh/csh Shell (Edit /.login or /.cshrc files)
http://osr507doc.sco.com/en/OSUserG/_The_C-shell_login_and_cshrc.html

In both cases, you are simply adding the command into a login/shell startup script to that the variable is always set with the extra paths. To edit these files, I recommend using vi (text editor).

vi Help
vi in Solaris help
vi in Unix help



Transfer Files From One UNIX Server To Another using ssh scp
In Unix, you can use the scp command to copy files and directories securely between remote hosts without starting an FTP session or logging into the remote systems explicitly. The scp command uses SSH to transfer data, so it requires a password or passphrase for authentication. Unlike rcp or FTP, scp encrypts both the file and any passwords exchanged so that anyone snooping on the network can't view them.

Warning: Be careful when copying between hosts files that have the same names; you may accidently overwrite them.



From Server to Local
scp -r user@server1:/directory/files /localDirectory


From Local to Server
scp -r /localDirectory user@server1:/directory/files



Python SUDS (SOAP API) full example with WSSE and complex types
I began this task in Perl originally, then decided to switch to Python and have an easier ride. I will upload the Perl example when I sort out a few minor issues with the SOAP::Lite library.


Anyway, in this example, you can specify a WSDL and WSSE (Web Service Security Extensions) username and password (sent in clear text btw), and it will send a SOAP request out and get a sample response back.

I have purposely consumed a service that has some complex types available (basically not just strings and ints). You can see how it is to work with the library and consume your own methods with this example.


Here are some useful things to note
- There have been problems with SUDS generating empty tags for optional properties for complex types. If this is the case, you will receive this error in your SOAP Body's response... "Server was unable to read request. ---> There is an error in the XML document. ---> Instance validation error: '' is not a valid value for PROPERTY_HERE."... To get around this, simply specify those properties (example below)

- client.factory.create() is used to let Python know about the complex types.

- "print client" (Using the example below) will tell you everything you need to know about your service (namespaces, types, methods, properties etc).

- The logger is your friend! Don't be a hero! Start out small and go big! The technique is to analyze the SOAP response and query the errors. If you can get a hold of what the correct SOAP envelope should look like, then compare this against the SOAP request you are sending out. This is the easiest way to solve any problems.

- Coming from a .NET background, I added a service reference and made a simple call with C#. You can then write more code to analyze the SOAP Request, or simply install Fiddler2 (If you haven't got it already, only 600kb and very useful!) to get the correct SOAP envelope to compare against.


The code

#!/usr/bin/python
#
# Sean Greasley. TutorialGenius.com 2012.
#
# Creates a portfolio object using the exacttarget SOAP API. An image must exist at the specified URN
# before alerting the system that the image is ready to be processed,
#
# USAGE:
# -portfolio <Display Name> <URN> <File Name> <Optional: CustomerKey>
# -portfoliowsdl <WSDL Address> <WSSE Username> <WSSE Password> <Display Name> <URN> <File Name> <Optional: CustomerKey>
#
#
# Imports
from suds.client import Client
from suds.wsse import *

# Logging Options
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.wsdl').setLevel(logging.DEBUG)
logging.getLogger('suds.wsse').setLevel(logging.DEBUG)


# Define usage options
def printUsage():
print ""
print "[USAGE]"
print "------------------------------------------------------------------------"
print " " + sys.argv[0] + " -portfolio <Display Name> <URN> <File Name> <Optional: CustomerKey>"
print " " + sys.argv[0] + " -portfoliowsdl <WSDL Address> <WSSE Username> <WSSE Password> <Display Name> <URN> <File Name> <Optional: CustomerKey>"
print ""
return


# Validate argument input
if (len(sys.argv) <= 1):
print "Invalid usage options..."
printUsage()
sys.exit(1)
elif (sys.argv[1] == "-portfolio" and (len(sys.argv) == 5 or len(sys.argv) == 6)):
print "Setting up a portfolio"
elif (sys.argv[1] == "-portfoliowsdl" and (len(sys.argv) == 8 or len(sys.argv) == 9)):
print "Setting up a portfolio with WSDL options"
else:
print "Invalid usage options..."
printUsage()
sys.exit(1)



# Setup variables
WSDL_URL = "https://webservice.s4.exacttarget.com/etframework.wsdl"
WSSE_USERNAME = "Username here!"
WSSE_PASSWORD = "Password here!"
PORTFOLIO_DISPLAYNAME = "Test Sean Display Name1"
PORTFOLIO_URN = "http://www.ct4me.net/images/dmbtest.gif"
PORTFOLIO_FILENAME = "dmbtest.gif"
PORTFOLIO_CUSTOMERKEY = ""

if (sys.argv[1] == "-portfoliowsdl"):
WSDL_URL = sys.argv[2]
WSSE_USERNAME = sys.argv[3]
WSSE_PASSWORD = sys.argv[4]
PORTFOLIO_DISPLAYNAME = sys.argv[5]
PORTFOLIO_URN = sys.argv[6]
PORTFOLIO_FILENAME = sys.argv[7]

try:
PORTFOLIO_CUSTOMERKEY = sys.argv[8]
except:
print "No Customer key specified. Using default..."
elif (sys.argv[1] == "-portfolio"):
PORTFOLIO_DISPLAYNAME = sys.argv[2]
PORTFOLIO_URN = sys.argv[3]
PORTFOLIO_FILENAME = sys.argv[4]

try:
PORTFOLIO_CUSTOMERKEY = sys.argv[5]
except:
print "No Customer key specified. Using default..."


# URL Detail
client = Client(WSDL_URL)


# WSSE Security
security = Security()
token = UsernameToken(WSSE_USERNAME, WSSE_PASSWORD)
security.tokens.append(token)
client.set_options(wsse=security)


# Build up portfolio
# 'Portfolio' is a complex type... so we use the create method to expose the properties to us. We can then populate the properties as normal.
portfolio = client.factory.create('Portfolio')
portfolio.DisplayName = PORTFOLIO_DISPLAYNAME
portfolio.CustomerKey = PORTFOLIO_CUSTOMERKEY
portfolio.Source = client.factory.create('ResourceSpecification')
portfolio.Source.URN = PORTFOLIO_URN
portfolio.FileName = PORTFOLIO_FILENAME


# For some reason the SUDS library tends to generate empty SOAP tags for optional properties. Here I have manually specified the defaults here. Just be aware of that!
createOptions = client.factory.create('CreateOptions')
createOptions.RequestType = "Synchronous"
createOptions.QueuePriority= "High"


# Attach Portfolio to array - Need to set at pos 0, as it returns 1 by default.
apiObject = [client.factory.create('APIObject')] # Remember [ ], its an array!
apiObject[0] = portfolio


# Create portfolio
# This method also had 'out' parameters exposed
print client.service.Create(createOptions, apiObject)


# Uncomment this next line to find out useful information about your service.
# print client



WSDL and SOAP: Test and Invoke WSDL online!
Really good website for service discovery
http://www.service-repository.com


They also have a WSDL tester and invoker... displays the SOAP messages and response. It also builds the HTML forms dynamically. Great stuff!
http://www.service-repository.com/client/start



Perl: SOAP::Lite - 500 Can't connect to webservice.service.com:443 (Invalid argument) https
I had a problem recently with trying to call a HTTPS Web Service using Perl's SOAP::Lite library, and I was receiving this error "500 Can't connect to webservice.service.com:443 (Invalid argument)"...

Note: Port 443 ssl. This is the default port for HTTPS/SSL. This is the encrypted form of HTTP that normally runs over port 80.


Okay, so problem identified... Cannot communicate with service over 443... What next?


We use cpan to install another library called "Crypt::SSLeay"... sounds spooky! But don't worry, it simply provides support for the HTTPS protocol in LWP (Library for WWW in Perl).

cpan - what the heck? View my previous post on cpan here

Simply issue this command, and cpan will do the rest...

sudo perl -MCPAN -e "install Crypt::SSLeay"



Perl: SOAP::Lite Simple .NET Service Call
Ever wondered how to call a .NET web service using the SOAP::Lite library?
I didn't think so, but just incase you did!....


#!/usr/bin/perl
use SOAP::Lite 'trace', 'debug'; # adds debug and tracing to view SOAP msgs
use SOAP::WSDL;
use strict;
use warnings;

my $soap = SOAP::Lite
-> uri('http://services.aonaware.com/webservices')
-> on_action( sub {sprintf '%s/%s', @_} )
-> proxy('http://services.aonaware.com/DictService/DictService.asmx');


print $soap->ServerInfo()->result;




Key Points to note
1. Use the tracing and debugging options, this will tell you what is wrong (trust me, it will happen!)
2. URI - This is a reference to the NAMESPACE.... Simple view your WSDL or ASMX service, and view the 'targetNamespace' attribute for the base node.... This references the namespace... This is required when making SOAP calls.
3. PROXY - This is the actual URL to the service or WSDL.
4. on_action - What to do when the action is raised.... similar to an event.... In the example, its simply printing the response. I am also manually printing the response in the code... so you will see output twice.



For reference, there is a really good post here that troubleshoots these issues further.
Microsoft also did a good post here



Perl: Can't locate [Library Here] in @INC - (CPAN Usage)
So i've been looking into Perl this week and I came across an error... quite simple when you know how... this post explains in !English! the options you can take to tackle this... CPAN is utilised and explained in this post.


The Error

SeanMAC:tmp localhome$ perl test.pl
Can't locate SOAP/Lite.pm in @INC (@INC contains: /Library/Perl/Updates/5.8.8/darwin-thread-multi-2level /Library/Perl/Updates/5.8.8 /System/Library/Perl/5.8.8/darwin-thread-multi-2level /System/Library/Perl/5.8.8 /Library/Perl/5.8.8/darwin-thread-multi-2level /Library/Perl/5.8.8 /Library/Perl /Network/Library/Perl/5.8.8/darwin-thread-multi-2level /Network/Library/Perl/5.8.8 /Network/Library/Perl /System/Library/Perl/Extras/5.8.8/darwin-thread-multi-2level /System/Library/Perl/Extras/5.8.8 /Library/Perl/5.8.6 /Library/Perl/5.8.1 .) at test.pl line 17.
BEGIN failed--compilation aborted at test.pl line 17.



So I created a test script and attempted to execute it. It threw up an error at Line 17 complaining that I didn't have the SOAP::Lite library. I.e. "Can't locate SOAP/Lite.pm"

In .NET we would probably either Google the library or use NuGet (NuGet.org - NuGet is a Visual Studio extension that makes it easy to install and update open source libraries).

If we would ever try to compare Perl to the .NET world, we could relate CPAN to NuGet in terms of what it does for us. That is, gets third party libraries, unpacks them and installs them for us.



CPAN
CPAN, the Comprehensive Perl Archive Network, is an archive of over 100,000 modules of software written in Perl, as well as documentation for it.

To use cpan, open up a terminal or command window, and use the following command. This will run cpan as ROOT user. This is sometimes necessary as it requires access to shared library directories.

perl -MCPAN -e 'shell'


You will then be in the cpan shell. Type 'h' for help....














commandargumentdescription
a,b,d,mWORD or /REGEXP/ about authors, bundles, distributions, modules
iWORD or /REGEXP/ about anything of above
rNONEreinstall recommendations
lsAUTHORabout files in the author's directory
getdownload
makemake (implies get)
testMODULESmake test (implies make)
installDISTS, BUNDLESmake install (implies test)
cleanmake clean
lookopen subshell in these dists' directories
readmedisplay these dists' README files






If we wish to install our library (This includes get/download, make, test and install) then we simply issue the command....

install [Library Name]

with example

install SOAP::Lite


You will be asked a few options, mostly regarding ideal location to download from, connection timeouts etc... You can simply keep hitting enter to use the defaults.

If all is successful, your library will be installed and included within the @INC array (Containing paths to libraries used by Perl).

Happy Scripting!



iOS - Viewing hidden files and directories
Write the following into a terminal window....

defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder


This will show you all of the hidden files and folders on your operating system. If you want to reverse the command replace TRUE with FALSE.



REST Web Services
Good article on RESTful Web Service Architecture



LINQ to SQL vs. ADO.NET Entity Framework
LINQ to SQL and the Entity Framework have a lot in common, but each have features targeting different scenarios in the Orcas timeframe.

LINQ to SQL has features targeting “Rapid Development” against a Microsoft SQL Server database. Think of LINQ to SQL as allowing you to have a strongly-typed view of your existing database schema. LINQ to SQL supports a direct, 1:1 mapping of your existing database schema to classes; a single table can be mapped to a single inheritance hierarchy (i.e. , a table can contain persons, customers, and employees) and foreign keys can be exposed as strongly-typed relationships. You can build LINQ queries over tables/views/table valued functions and return results as strongly typed objects, and call stored procedures that return strongly typed results through strongly typed methods.

A key design principle of LINQ to SQL is that it “just work” for the common cases; so, for example, if you access a collection of orders through the Orders property of a customer, and that customer’s orders have not previously been retrieved, LINQ to SQL will automatically get them for you.

LINQ to SQL relies on convention, for example default insert, update, and delete logic through generated DML can be overwritten by exposing appropriately named methods (for example, “InsertCustomer“, “UpdateCustomer“, “DeleteCustomer“). These methods may invoke stored procedures or perform other logic in order to process changes.

The Entity Framework has features targeting “Enterprise Scenarios“. In an enterprise, the database is typically controlled by a DBA, the schema is generally optimized for storage considerations (performance, consistency, partitioning) rather than exposing a good application model, and may change over time as usage data and usage patterns evolve. With this in mind, the Entity Framework is designed around exposing an application-oriented data model that is loosely coupled, and may differ significantly, from your existing database schema. For example, you can map a single class (or “entity”) to multiple tables/views, or map multiple classes to the same table/view. You can map an inheritance hierarchy to a single table/view (as
in LINQ to SQL) or to multiple tables/views (for example, persons, customers, and employees could each be separate tables, where customers and employees contain only the additional columns not present in persons, or repeat the columns from the persons table). You can group properties into complex (or “composite”) types (for example, a Customer type may have an “Address” property that is an Address type with Street, City, Region, Country and Postal code properties).

The Entity Framework lets you optionally represent many:many relationships directly, without representing the join table as an entity in your data model, and has a new feature called “Defining Query” that lets you expose any native query against the store as a “table” that can be mapped just as any other table (except that updates must be performed through stored procedures). This flexible mapping, including the option to use stored procedures to process changes, is specified declaratively in order to account for the schema of the database evolving over time without having to recompile the application.

The Entity Framework includes LINQ to Entities which exposes many of the same features as LINQ to SQL over your conceptual application data model; you can build queries in LINQ (or in “Entity SQL”, a canonical version of SQL extended to support concepts like strong typing, polymorphism, relationship navigation and complex types), return results as strongly typed CLR objects, execute stored procedures or table valued functions through strongly-typed methods, and process changes by calling a single save method.

However, the Entity Framework is more than LINQ to Entities; it includes a “Storage Layer” that lets you use the same conceptual application model through low-level ADO.NET Data Provider interfaces using Entity SQL, and efficiently stream results as possibly hierarchical/polymorphic DataReaders, saving the overhead of materializing objects for read-only scenarios where there is no additional business logic.

The Entity Framework works with Microsoft SQL Server and 3rd party databases through extended ADO.NET Data Providers, providing a common query language against different relational databases through either LINQ to Entities or Entity SQL.

So while there is a lot of overlap, LINQ to SQL is targeted more toward rapidly developing applications against your existing Microsoft SQL Server schema, while the Entity Framework provides object- and storage-layer access to Microsoft SQL Server and 3rd party databases through a loosely coupled, flexible mapping to existing relational schema.

I know this is a confusing area, and we’re trying to figure out how best to describe these differences to help customers make the appropriate choices. Please let me know if this helps, or if there are still areas of confusion…

Thanks,
Michael Pizzo
Principal Architect
Microsoft Data Programmability



I want SQL Management Studio Express (The GUI!!) After installing VS 2010
So I re-installed VS 2010 the other day and as usual, it installs about 50 versions of SQL Server with it (urgh!)... after seeing copious amount of SQL Server names in "Add/Remove Programs", I still didn't have the nice GUI to work with (SQL Management Studio Express)... gees!

So I found a link where a few people have had the same issue, check it here

If anybody knows of a minimal version or a better suggestion, please comment!



How To: Unlock and Activate iPhone on iOS 5 [teathered]
So i spent some time the other day trying to unlock and activate an iPhone 3GS (also works for other models and iPad)... So rather than letting this be forgotten forever (because it took a while!) I'd thought i'd make a blog about my findings.


Preliminaries
- Latest version of iTunes
- Redsn0w [Which version?]
- Tiny Umbrella (Used to find out the firmware version)
- The Target Firmware [Files here]



!!Things to note!!

Teathered vs. Unteathered?
This simply means, weather you need a computer to start your phone. If a release of redsn0w offers a Teathered solution, then !everytime! your phone turns off (out of battery, new app install etc.) you will need to plug it into your computer and use redsn0w to boot the phone! The batteries are pretty decent, so you probably don't even care or it's no big deal.

Which firmware shall I get?
Currently, if you want an UNTEATHERED solution (basically the phone can boot by itself) then firmware 4.3.3 is what you need. Currently there is no unteathered solution for the latest firmware (including: 4.3.4, 4.3.5 and 5).

I want UNTEATHERED, but, I have later than 4.3.3 on my iPhone!?
Most website will tell you that you need SHSH Blobs in order to do this. If you don't know what they are or you didn't upgrade your iPhone before, chances are you won;t have them.
Apparently there IS solution to do this, I have not tried it personally. You can find it here



OK enough preliminaries, lets do it!....

1. Ok this guide is for iOS 5 and TEATHERED, so lets get iOS 5 on the iPhone. If your not sure weather you have it already, connect the iPhone to the computer and open TinyUmbrella. This will tell you your current firmware version. If you already have iOS 5, skip steps 3-5.

2. Put iPhone in DFU mode HOWTO VIDEO HERE

3. Connect iPhone to computer, and use 'Restore', this will prompt you to install the latest firmware (iOS 5).

4. You now have the latest and greatest firmware!

5. Ok, now, lets jailbreak.... download firmware for iOS 5 (links above or here). If you already did an update through iTunes, this will already be in your downloaded directory. See below to find this...

On Windows XP :
Documents and Settings\\Application Data\Apple Computer\iTunes\iPhone Software Updates

On Windows Vista/Windows 7:
Users\\AppData\Roaming\Apple Computer\iTunes\iPhone Software Updates

On Mac:
~/Library/iTunes/iPhone Software Updates

6. Now you have the firmware handy, open redsn0w for your current firmware version. Currently, 0.9.9b4 for windows or 0.9.9b5 for mac.

7. Click extras and specify firmware manually. Point to the iOS 5 firmware (*.ispw).

8. Go back and hit the jailbreak button. Select 'Install Cydia', continue to next dialog which will ask you to put the phone into DFU mode. HOWTO VIDEO HERE

9. Redsn0w will do all its business, don't touch the iPhone until it finishes, it stops on the spinner (which has probably stopped spinning).

10. Ok the jailbreak is done, but like I said, its teathered. So open redsn0w, click extras, and we just want to boot the iPhone. Click the button, and prepare to enter DFU mode again. This is a bit trickier with a phone that won't turn off.

Note: If your jailbreak left you on the crashed spinner, don't worry its fine. Simply hold the power and home buttons for 10secs until the phone does a hard reset. Once the phone resets, proceed with the DFU instructions!

11. Ok you should see a pineapple logo on the iPhone if done correctly, and the iPhone will boot up. You should be able to use the iPhone to its full extent, unless you need to unlock your iPhone to any network, then only your calls will not work. If you need to unlock as well, follow the rest of this guide....

12. Next step (for the unlock), you need a WIFI connection! It'll probably say 'No Service' in the top left corner.

13. Open Cydia (now on dashboard) and search for ultrasn0w. Download and install this and it will ask you to reboot when you are done. (Don't forget you need to boot using redsn0w as its teathered!)

14. When you re-boot, your iPhone should is unlocked and ready to party!



OK i've done all of this, but still 'No Service'!?

1. Ok first, disabled 3G (general settings > Network > Enable 3G)
2. Toggle airplane mode (this will refresh the signal).

If this does not work, then you may need to update your base band (basically a firmware update for your inbuilt modem). We will update this to match the iPad's baseband (currently v06.15.00), works just as well. There are somethings you should be aware of before doing this though!! - Personally, I needed to do this myself!


OK i've decided to update my base band, how do I do this?!

1. First, double check you actually don't already have v06. (Settings > General > About > Modem Firmware).
2. Re-run the jailbreak process again, but when you check 'Install Cydia', also check 'Install iPad base band'... this will do the jailbreak, but also update your modem firmware.
3. Check on iPhone that the modem firmware was updated to v06.
4. Repeat the process above to unlock the phone with ultrasn0w.
5. Awesome!



OK I DON'T WANT THIS JAILBREAK STUFF ANYMORE, HELP!?

1. Plug into Computer via. USB.
2. Put phone in DFU mode.
3. Click 'Restore' in iTunes.
4. Sorted!



MVC3/Razor - Global Error Handling
Here is a technique you can use within your MVC application to control global error handling. The technique is quite similar to aspx pages where you populate the Application_Error function within Global.asax, however, the routing is completely new!


Global.asax
/// <summary>
/// Handle application error on a global level.
/// Passes handling off to the ErrorController
/// </summary>
protected void Application_Error()
{
    var exception = Server.GetLastError();
    var httpException = exception as HttpException;
    Response.Clear();
    Server.ClearError();
    var routeData = new RouteData();
    routeData.Values["controller"] = "Errors";
    routeData.Values["action"] = "General";
    routeData.Values["exception"] = exception;
    Response.StatusCode = 500;
    if (httpException != null)
    {
        Response.StatusCode = httpException.GetHttpCode();
        switch (Response.StatusCode)
        {
            case 403:
                routeData.Values["action"] = "Http403";
                break;
            case 404:
                routeData.Values["action"] = "Http404";
                break;
        }
    }
 
    IController errorsController = new ErrorController();
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    errorsController.Execute(rc);
}


Note: This will route our errors to the ErrorController. Lets take a look at the error controller...


ErrorController.cs
// <copyright file="ErrorController.cs" company="GinkoSolutions.com">
// Copyright (c) 2011 All Right Reserved
// </copyright>
// <author>Sean Greasley</author>
// <email>sean@ginkosolutions.com/sean@tutorialgenius.com</email>
// <summary>Controller for handling errors within the application.</summary>
namespace MVCEmailExample.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MVCEmailExample.Models;
 
    /// <summary>
    /// Controller for handling errors within the application.
    /// </summary>
    public class ErrorController : Controller
    {
        public ActionResult General(Exception exception)
        {
            return View("Error", new ErrorModel() { ErrorTitle = "General Error", ExceptionDetail = exception });
        }
 
        public ActionResult Http404()
        {
            return View("Error", new ErrorModel() { ErrorTitle = "Not found" });
        }
 
        public ActionResult Http403()
        {
            return View("Error", new ErrorModel() { ErrorTitle = "Forbidden" });
        }
    }
}


So now were handling our errors and throwing them out to the Error View (in Views/Shared!). However, were now using a strongly typed view and passing a custom class into it. This custom class contains details of our error!


ErrorModel.cs (Our custom error class!)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace MVCEmailExample.Models
{
    public class ErrorModel
    {
        public string ErrorTitle { get; set; }
        public Exception ExceptionDetail { get; set; }
    }
}


Very simple! All it does it holds information really.
Now lets take a look at our error view...


Error View (This will already exist with a new MVC3 application) P.s. I'm using Razor syntax!
@using MVCEmailExample.Models
@model ErrorModel
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
 
<h2>@Model.ErrorTitle</h2>
 
Sorry, an error occurred while processing your request.
<br />
@if (Model.ExceptionDetail != null)
{
      @Model.ExceptionDetail.Message
}


This is our strongly typed view (Hint: @model ErrorModel). We simply extract the error info here and display it in a very (unstylish) form!


This sample below is for a sample email application. This uses the code described above. Just hit the button without entering any information and (assuming you don't have local mail server) u'll see some errors appearing!

MVC3 Razor - Global Error Handling



C# - Sending HTML Email template with linked resources and plain text fallback
Hi all,

If your reading this, then chances are you've looked how to create a simple email with C# and added some HTML in there. You might have then looked for including images and the documentation on the internet for this is kinda poor/bad/doesn't work. Well here's how!!

In this example, I have created a class library that can be used with any C# application. So it doesn't matter what kinda application you have (MVC, ASPX Web App, Client App, Command Line etc...).

Lets let on with it!! I've created this project in .NET 4.0 at time of writing and included a VS2010 MVC3 Web App with it for full example. I have also included some global MVC3 error handling!


Class Library
// <copyright file="EmailHelper.cs" company="GinkoSolutions.com">
// Copyright (c) 2011 All Right Reserved
// </copyright>
// <author>Sean Greasley</author>
// <email>sean@ginkosolutions.com/sean@tutorialgenius.com</email>
// <summary>Email helper class. Allows sending of html and plain text emails to a target email address.</summary>
namespace MVCEmailExample.Helpers
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Configuration;
    using System.Linq;
    using System.Net.Mail;
    using System.Net.Mime;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using MVCEmailExample.Exceptions;
    using MVCEmailExample.Models;
 
    /// <summary>
    /// Email helper class.
    /// Allows sending of html and plain text emails to a target email address.
    /// </summary>
    public class EmailHelper
    {
        /// <summary>
        /// Sends an email to a recipient. Provides HTML and plain text views.
        /// The recipient will receive which one their client supports.
        /// </summary>
        /// <param name="templateDir">Directory of where the HTML email template is stored.</param>
        /// <param name="recipient">Receipient information</param>
        public static void SendEmail(string templateDir, Recipient recipient)
        {
            try
            {
                // Build message
                MailMessage message = new MailMessage();
                message.To.Add(new MailAddress(recipient.Email));
                message.Subject = ConfigurationManager.AppSettings["EmailSubject"];
 
                // Create plain text mode for alternative view
                AlternateView plainView = AlternateView.CreateAlternateViewFromString(ConfigurationManager.AppSettings["PlainTextEmail"], null, "text/plain");
                message.AlternateViews.Add(plainView);
 
                // Create HTML email version
                MailDefinition mailDef = new MailDefinition();
                mailDef.BodyFileName = string.Format(@"{0}\{1}", templateDir, @"Email.html");
                mailDef.IsBodyHtml = true;
                mailDef.Subject = ConfigurationManager.AppSettings["EmailSubject"];
 
                // Build replacement collection to replace fields in Email.htm file
                // Use fields anywhere in the template file. I.e.   <%FRIENDNAME%>
                ListDictionary replacements = new ListDictionary();
                replacements.Add("<%NAME%>", recipient.Name);
 
                // Use dummy control as owner (I.e. new System.Web.UI.Control()) as were in a class library.
                // It's only use to determine where the access templates from as a relative base.
                MailMessage msgHtml = mailDef.CreateMailMessage(recipient.Email, replacements, new System.Web.UI.Control());
                AlternateView htmlView = AlternateView.CreateAlternateViewFromString(msgHtml.Body, null, "text/html");
 
                // Add linked resources
                AddLinkedResources(templateDir, ref htmlView);
                
                // Add HTML view
                message.AlternateViews.Add(htmlView);
 
                // Send message
                SmtpClient client = new SmtpClient();
                client.Send(message);
            }
            catch (Exception mailEx) { throw new MailerException("Error sending email.", mailEx); }
        }
 
        /// <summary>
        /// Adds linked resources to the email
        /// Email template must contain the resource IDs in the following format: <img src="cid:CONTENTID" />
        /// </summary>
        /// <param name="templateDir">Directory of where the HTML email template images are stored.</param>
        /// <param name="htmlView">A reference to the HTML view.</param>
        private static void AddLinkedResources(string templateDir, ref AlternateView htmlView)
        {
            LinkedResource logo1 = new LinkedResource(string.Format(@"{0}\{1}", templateDir, @"Images\email.jpg"), MediaTypeNames.Image.Jpeg);
            logo1.ContentId = "email";
            htmlView.LinkedResources.Add(logo1);
        }
    }
}



Note: This will attempt to send a HTML email with an embedded image (linked resource). If the client does not support HTML, then a plain text email will be used as backup. boom! (I've defined this in the application settings, as well as the email subject and "from" email address).


Configuration - App Settings (Optional, just didn't want to hard code them) [Web/App.config]
<appSettings>
    <!-- Email App Settings -->
    <add key="EmailSubject" value="GinkoSolutions.com Email Example"/>
    <add key="PlainTextEmail" value="Hi There, You currently don't support HTML emails, but thats ok! I'm just saying hello anyway!"/>
</appSettings>



Configuration - Email server [App/Web.config]
<system.net>
    <mailSettings>
        <smtp from="Admin &lt;admin@ginkosolutions.com&gt;">
            <network host="localhost" port="25"  />
        </smtp>
    </mailSettings>
</system.net>


Note: This won't work unless you have a local email server. Please provide the details to an SMTP email server here.


Create a sample recipient class (Just for storing recipient details)
public class Recipient
{
    public string Name { get; set; }
    public string Email { get; set; }
}



Invoke the email static class
// Construct recipient from form
Recipient recipient = new Recipient() { Name = FriendName, Email = FriendEmail };
 
// Send email
EmailHelper.SendEmail(Server.MapPath("~/EmailTemplate"), recipient);



Note: I have added an email template path as a parameter. This is so that if you execute the email helper from a web application, it knows where to find the templates!


Sample HTML Template File
<body style="background: #000000;">
Hello <%NAME%>,
<br /><br />
I thought i'd send you a picture of some guy holding an envelope.
<br /><br />
<img src="cid:email" />
<br /><br />
I have no idea why though!
<br /><br />
Thanks!
</body>


Note:
Notice the cid prefix for the images. This indicates a contentID for a linked resource. If you look in the code for the email helper, you will notice that I am created 1 linked resource and setting the contentID to 'email'. This will simply embed the image.
Again, in this template, you will notice I have used a custom tag for the friend's name called NAME. This is replaced within the email helper when we construct a ListDictionary and add our replacements to it.


and thats it!!

If you stuck, or can't get it to compile, then download the full sample here

MVC3 Web Application - Full Email Example with Fallback



MVC3 JQuery Client Validation using Entity Model Framework 4.1 auto generated classes
Hi all,

This is a quick tutorial on how to perform client validation using the MVC framework with auto generated classes in the backend. You might have these auto-generated classes by using a data modelling framework such as: Entity Framework or Linq-To-Sql.

Prerequisites
Creating an MVC 3 Web Application with the Razor View Engine, HTML5 and IIS Express 7.5


Creating an entity model using EMF 4.1
1. Create a new Entity Data Model (.edmx) file within your Modules folder. Right click Modules and add a "ADO.NET Entity Data Model" item. Call this "MembershipModel.edmx"
2. If you have a database already, seelct "Generate from database". This will automatically create entities based on your tables. If not, select "Empty model".
3. Open the entity designer file (.edmx).
4. If you selected "Empty model", Right click the designer > Add > Entity...
5. Name the entity "User"
6. OK to create!
7. Right click the new entity > Add > Scalar Property
8. Call the property "Name"
9. Right click the new entity > Add > Scalar Property
10. Call the property "Email"
11. You can generate your database from your model. Once you have created your entities, right click the designer and select "Generate Database from Model". Don't worry if you need to update these at a later date, EMF does a good job of syncing these later.
12. Setup a new connection to your database
13. You will be presented with an SQL script for your entities, cool huh?
14. Execute this against your datastore.

Note: If you open the designer oce behind file (MembershipModel.Designer.cs), you can see that the classes have been created for us (one per entity), aswell as some properties and a method to create a new user (in our example). By default, the designer uses a code generater called T4 (Text Template Transformation Toolkit). You will notice that all classes using the default template implement the EntityObject base class. These classes provide a lot of functionality, but are quite cumbersome to work with. So we are going to use a different generator! (DbContext Generator)


Using the DbContext Generator
1. Right click the Entity Model .edmx designer > "Add Code generation"
2. Select "ADO.NET DbContext Generator" from the dialog and name it "Model1.tt".
3. OK to create!
4. You will receive a warning because template can potentially contain harmful content. Just click ok!

Note: You will notice that two files have been created under the Models folder: Model1.tt and Model1.Context.tt. Underneath the Model1.tt file, you will be a custom class representing your entity "User.cs". This is the class you will be using throughout this sample application to represent users! If you don't see this class here, then you have created your database!



ok, im a master at EMF, show me the validation already!

With MVC, a simple way to perform validation is to use the [Required] atrribute for properties of our class. Now the problem lies with the way our classes are generated by the code generator (We cannot change the designer fiels because we'll lose our changes, plus its stupid!). An easy way around this is to use Metadatatype!

Metadatatype and T4 class validation
1. Right click the Models folder > Add > Class..
2. Call it "UserValidation.cs"
3. Enter the following code...

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
 
namespace MvcApplication1.Models
{
    [MetadataType(typeof(UserValidation))]
    public partial class User
    {}
 
    public class UserValidation
    {
        [Required(ErrorMessage = "Your Full Name is required")]
        public string Name { get; set; }
 
        [Required(ErrorMessage = "Your Email Address is required")]
        [RegularExpression(@"^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$", ErrorMessage = "Your Email Address is invalid")]
        public string Email { get; set; }
    }
}



Note: You will notice that Metadatatype allows us to specify another class on behalf of an existing partial class, to append attribues to. These attributes will be our validation attributes! I have chosen the Name and the Email properties of our user entity to apply validation to.


Configuring the Controller
1. Add a new controller. I.e. HomeController
2. In the Index method, return the view with a new copy of the EMF generated User class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
 
namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View(new User());
        }
    }
}



Creating the configuring the view
1. Right click the Index method in the controller and add the view.
2. Make this strongly typed, or we will have a problem with the dynamic operations we will be using in the view (Example error: CS1963: An expression tree may not contain a dynamic operation)
3. Enter the following form information into the view...

@using MvcApplication1.Models
@model User
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>Sample EMF Class Validation</h2>
 
@using (Html.BeginForm())
{
    <fieldset>
    <p>
        @Html.LabelFor(Model => Model.Name)
        @Html.TextBoxFor(Model => Model.Name)
        @Html.ValidationMessageFor(Model => Model.Name)
    </p>
    <p>
        @Html.LabelFor(Model => Model.Email)
        @Html.TextBoxFor(Model => Model.Email)
        @Html.ValidationMessageFor(Model => Model.Email)
    </p>
    <p>
        <input type="submit" value="Submit" />
    </p>
    </fieldset>
}


We are almost there, but one more thing!! We need to add a reference to the jquery validation libraries. You can either do this in your view (using sections from the main layout page) or simply add the following into the head on the _Layout.cshtml page...

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>



Download Sample Files Here


Enjoy!



Creating an MVC 3 Web Application with the Razor View Engine, HTML5 and IIS Express 7.5
This was originally going to be a few simple steps, but I decided to go the whole hog. Good first read if your getting started with MVC3! (Rough knowledge required, when I say rough, I mean VS, aspx and O-O knowledge)


Creating new MVC 3 Web Application in VS 2010
1. Create a new MVC 3 Web Application
2. Select an Empty template from the templates dialog (the others ship with authentication that were not goign to use).
3. View engine, select Razor (This will allow us to use the Razor view engine which has slightly different markup and uses .cshtml files rather than .aspx pages). Note: Razor view can be rendered inside unit tests, something that aspx pages cannot.
4. Use HTML5 semantic markup, check it!
5. OK to create.

Note: You can see that quite a lot of libraries are included by default. You will also notice that JQuery (JS and CSS) is included as standard and we have a good base setup to begin developing our web application.



WHAT IS MVC and Order of execution

Init
Within an MVC application, you have a list of routes and filters defined when the application starts. These are defined the the Global.asax.cs file (yes it still exists!). The routes are referenced everytime a page is requested (URL is entered that is associated with the application). The routes describe which Controller will serve the view's content.

Controller
The Controller is responsible for all the business logic. This is the "C" part of MVC. The Controller may utilise the Model ("M" in MVC) to manipulate the datastore is some way (basically ask the database to grab something). The Controller may do some casting or validation on the data, then render the View (may also pass data to the view when rendering).

Model
The Model is all about the database and the database layer. Usually you will have a framework here for managing access and control to your database. In this example, we are using the entity framework. So we will have our .edmx files and our template files here. Our classes will also be defined here as they will be generated automatically from our database content!

View
The "V" in MVC. View's should know nothing about how the data is constructed and how the data works internally. The view should be essentially be dumb and told nothing about the data, other than anything required to display the data to the user. The reason for this aides the seperation of concerns principle of O-O programming. This allows us to clearly seperate are busienss logic. The rewards consist of: Unit testable busienss layer, designers can work with views without worrying about learning C#/VB etc.


Razor View Engine
I don't want to explain everything in this post or were gonna be writing a novel. Here is a good link by ScottGu on the Razor view engine. Either than, or you can just trust me that it's great!


Note about Razor 'master' pages and entry points
_ViewStart.cshtml - Does what it says! This is executed first and initialises the view.
_Layout.cshtml - Razor's answer to aspx master pages.



Creating a Controller
1. Right click the Controllers directory.
2. Add > Controller.
3. Name the controller HomeController (We already have a route defined in the Global.asax as default that points to a Home Controller - So there is no extra work required to link it up yet).
4. Set the template as an empty template
5. OK to create!
6. You will notice that you controller contains an Index method. Will will be executed by default when the user hits the 'Home' directory for your application. I.e. http://localhost/Home


Creating a View based off the Controller
1. Each method in our controller can map to its own view page. This is what we will be doing in this example. Once the controller is created, then creating a view is simple!
2. Open the HomeController, and right click on the Index method.
3. Select 'Add View...'
4. The view name will be Index by default. This is fine...
5. THe view engine will be Razor, this again is fine...
6. Creating a strongly typed view just means that this view will only accept classes of a single type. So if you are ALWAYS passing a TEST class to this view, then it should be strongly typed.
7. Partial view can be compared to an aspx user control. It's a partial view, not a complete one! This can be re-used throughout the web application. We are not creatign one of these now...
8. "Use layout or master page". We are using this (as describes before). Set this as the _Layout.cshtml file. It will reside in the Shared folder within Views (~/Views/Shared/_Layout.cshtml).
9. OK to create!



Setting up test server and launching application

Note: I recommend using IIS Express (7.5 latest at time of writing) or something different to the visual studio server for this application. MVC uses URL Routing (aka URL rewriting before MVC), so sometimes the routing gets a little confusing with the visual studio development server. IIS7 handles URL routing out of the box (Whereas more steps were requried for IIS 6, and you can't install IIS7 on windows XP). However, IIS Express 7.5 solves all of these problems becaue it performs both nicely!


Setting up IIS Express 7.5
1. If you don't have it, its a lightweight seperate install. Simply get it via the web platform intaller
2. Right click the web application in Visual Studio > Properties.
3. Web tab
4. Use local IIS Web server
5. Check "Use IIS Express".
6. Click create virtual directory button
7. OK to execute application!


Now, simply execute the application and you'll be presented with a very blank dull webpage. Congratulations, you did it! It's the start of something good, trust me!



Reference Links
Building an MVC 3 App with Database First and Entity Framework 4.1
Creating an MVC3 Application with Razor and JS