posts - 31, comments - 85, trackbacks - 0

My Links

News

Archives

Post Categories

Tuesday, April 26, 2011

Visual Studio and working with projects on UNC share

This is just a note to myself on what needs to be changed while working on projects that are on a UNC share.

Problem 1: The first problem is the Trust level for Intranet Zone.

Fix: Go to Control Panel\Administrative Tools\  and launch Microsoft .NET Framework 2.0 Configuration Tool.

Click on Runtime Security Policy, then in the right pane, click Adjust Zone Security. Click Local Intranet and change the trust level for this zone to Full Trust.

Then you might get this error:

Problem2: The network BIOS command limit has been reached

Probable Fix: You can try the fix discussed in this Microsoft KB, http://support.microsoft.com/kb/810886. It never worked for me.

Fix: Disable File Change Notification in Registry.

1. Open RegEdit
2. 64-bit, go to HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\ASP.NET
3. 32-bit, go to HKEY_LOCAL_MACHINE\Software\Microsoft\ASP.NET
4. Create a Dword called FCNMode and assign a value of 1.

Note: You might have to restart your michine.

 

 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Tuesday, April 26, 2011 9:47 AM | Feedback (0) | Filed Under [ Visual Studio / Express ]

Wednesday, February 09, 2011

Send Multiple InMemory Attachments Using FileUpload Controls

I wanted to give users an ability to send multiple attachments from the web application. I did not want anything fancy, just a few FileUpload controls on the page and then send the email. So I dropped five FileUpload controls on the web page and created a function to send email with multiple attachments.
Here’s the code:
public static void SendMail(string fromAddress, string toAddress, string subject, string body, HttpFileCollection fileCollection)
    {
        // CREATE THE MailMessage OBJECT
        MailMessage mail = new MailMessage();
 
        // SET ADDRESSES
        mail.From = new MailAddress(fromAddress);
        mail.To.Add(toAddress);
 
        // SET CONTENT
        mail.Subject = subject;
        mail.Body = body;
        mail.IsBodyHtml = false;
              
        // ATTACH FILES FROM HttpFileCollection
        for (int i = 0; i < fileCollection.Count; i++)
        {
            HttpPostedFile file = fileCollection[i];
            if (file.ContentLength > 0)
            {
                Attachment attachment = new Attachment(file.InputStream, Path.GetFileName(file.FileName));
                mail.Attachments.Add(attachment);
            }
        }
 
        // SEND MESSAGE
        SmtpClient smtp = new SmtpClient("127.0.0.1");
        smtp.Send(mail);
    }
And here’s how you call the method:
protected void uxSendMail_Click(object sender, EventArgs e)
    {
        HttpFileCollection fileCollection = Request.Files;
        string fromAddress = "from@abc.com";
        string toAddress = "to@xyz.com";
        string subject = "Multiple Mail Attachment Test";
        string body = "Mail Attachments Included";
        HelperClass.SendMail(fromAddress, toAddress, subject, body, fileCollection);       
    }
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Wednesday, February 09, 2011 10:16 AM | Feedback (1) |

Monday, January 17, 2011

Encrypt / Decrypt Sections of App.Config file in Windows Application

This is just a note to myself on how to Encrypt and Decrypt App.Config (or Web.Config if ASP.NET) in a Windows Application.

Encryption:
1. Rename App.Config to Web.Config
2. %windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "connectionStrings" <Full Path to Web.Config>
3. Succeeded! implies Encryption was successful
4. Rename Web.Config to App.Config

Descryption:
1. Rename App.Config to Web.Config
2. %windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pdf "connectionStrings" <Full Path to Web.Config>
3. Succeeded! implies Decryption was successful
4. Rename Web.Config to App.Config (if needed)

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Monday, January 17, 2011 10:44 AM | Feedback (1) |

Friday, May 07, 2010

Procedure or function has too many arguments specified

This error took me a while to figure out. I was using SqlDataSource with stored procedures for SELECT and UPDATE commands. The SELECT worked fine. Then I added UPDATE command and while trying to update, I would get this error:

"Procedure of function has too many arguments specified"

Apparently, good guys at .NET decided it is necessary to send SELECT parameters with the UPDATE command as well. So when I was sending the required parameters to the UPDATE sp, in reality, it was also getting my SELECT parameters, and thus failing.

I had to add the extra parameters in the UPDATE stored procedure and make them NULLABLE so that they are not required....phew...

Here is piece of SP with unused parameters.

ALTER PROCEDURE [dbo].[UpdateMaintenanceRecord]
       @RecordID INT
    ,@District VARCHAR(255)
    ,@Location VARCHAR(255)
   
    --UNUSED PARAMETERS
    ,@MTBillTo VARCHAR(255) = NULL
    ,@SerialNumber VARCHAR(255) = NULL
    ,@PartNumber VARCHAR(255) = NULL

Update: I was getting that error because unkowingly, I had bound the extra fields in my GridVeiw with Bind() call. I changed all the extra one's, which did not need to be in Update, to Eval() and everything works fine.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Friday, May 07, 2010 9:35 AM | Feedback (2) |

Wednesday, April 21, 2010

User Already Exists in the Current Database - SQL Server

I was moving a lot of databases from one SQL Server to another, and my applications were giving me errors saying "Login failed for <user>". The user was already in the database with appropriate rights to allowed objects in the database. I tried mapping the user to the database and that's when I got this message:

"User Already Exists in the Current Database"...

I googled and found this very useful post about orphaned users when moving databases.

These are the steps you should take to fix this issue:

First, make sure that this is the problem. This will lists the orphaned users:
EXEC sp_change_users_login 'Report'

If you already have a login id and password for this user, fix it by doing:
EXEC sp_change_users_login 'Auto_Fix', 'user'

If you want to create a new login id and password for this user, fix it by doing:
EXEC sp_change_users_login 'Auto_Fix', 'user', 'login', 'password'

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Wednesday, April 21, 2010 7:59 AM | Feedback (0) |

Friday, January 22, 2010

ASP.NET WebForm Page Life Cycle Events

Joe shared a nice list of page life cycle events, very useful when you are trying to figure out where to put what.

Link: http://misfitgeek.com/blog/aspnet/unwinding-the-page-lifecycle-events/
 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Friday, January 22, 2010 8:50 AM | Feedback (0) |

Friday, October 30, 2009

Automated password expiration notice for Active Directory users

When passwords are set to expire after a certain number of days in Active Directory, the remote users suffer because they do not get a notification like the local users do that their password is going to expire.
Eventually, it becomes too late for them to change their passwords and they get locked out. I found this out recently and did not believe that there was no built in support for this. I started researching and indeed, there was no built in support. The solution was to email the users, either through a script or manually before their passwords expire.
There are simple VB Scripts out there, which do this kind of stuff.
I created a C# Console Application which emails users if their password is going to expire, and also emails the report to the administrator. You can schedule it run every day as a Windows Scheduled Task. It will start emailing users when 15 (default) days are left for their passwords to expire.
There are a few things you will need:
1. config.xml file
2. EmailBody.txt file
3. A reference to Active DS Type Library
4. SettingsProvider.cs class
 config.xml settings:
AdministratorEmail: To send reports
MailServer: The mail server used to send emails
Countdown: Used as a threshold to start emailing users
          <?xml version="1.0" encoding="utf-8" ?>
           - <config>
                <AdministratorEmail>Administrator@YourCompany.com</AdministratorEmail>
                <MailServer>YourMailServer</MailServer>
                <Countdown>15</Countdown>
           </config>
 
The SettingsProvider.cs class is used to read values from the config.xml file.
SettingsProvider.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
 
namespace PasswordNotification
{
    class SettingsProvider
    {
        private const string CONFIG_FILE = "config.xml";
        private static XmlDocument _xmlDoc = null;
 
 
        private static string ConfigPath
        {
            get { return Directory.GetCurrentDirectory() + @"\" + CONFIG_FILE; }
        }
 
 
        public static void Save(string key, string value)
        {
            XmlNode node = _xmlDoc.SelectSingleNode("./config/" + key);
 
            if (node != null)
            {
                node.InnerText = value;
                Save();
            }
            else
            {
                // XML node doesnt exist thus create a new one
                Get(key, value);
            }
        }
 
        ///<summary>
        /// Gets a value of the settings. If the setting does not exist, defaultValue is returned.
        ///</summary>
        public static string Get(string key, string defaultValue)
        {
            if (_xmlDoc == null)
            {
                _xmlDoc = new XmlDocument();
 
                // Load config.xml
                string fullPath = SettingsProvider.ConfigPath;
 
                if (!File.Exists(fullPath))
                {
                    // Xml declaration
                    XmlDeclaration declaration = _xmlDoc.CreateXmlDeclaration("1.0", null, null);
                    _xmlDoc.AppendChild(declaration);
 
                    // Root node <config>
                    XmlElement rootNode = _xmlDoc.CreateElement("config");
                    _xmlDoc.AppendChild(rootNode);
 
                    Save();
                }
                else
                {
                    _xmlDoc.Load(fullPath);
                }
            }
 
            XmlNode node = _xmlDoc.SelectSingleNode("./config/" + key);
 
            if (node != null)
            {
                return node.InnerText;
            }
            else
            {
                // Add default value
                XmlElement newSetting = _xmlDoc.CreateElement(key);
                newSetting.InnerText = defaultValue;
                _xmlDoc.ChildNodes[1].AppendChild(newSetting);
 
                Save();
 
                return defaultValue;
            }
        }
 
        public static void Save()
        {
            if (_xmlDoc != null)
            {
                _xmlDoc.Save(SettingsProvider.ConfigPath);
            }
        }
    }
}
 
Then there’s a text file called EmailBody.txt which stores a template email. It contains parameters like [USERNAME] and [DAYCOUNT] which I use to plug in custom values in code.
EmailBody.txt
<html><title></title><head></head><body style="font-size:0.7em;color:#666666;">
 [USERNAME]
Your password is going to expire in [DAYCOUNT] days.
Please change your password to avoid account lockout.
The steps to change your password are as follows:
1) Log in to your machine
2) (If you are remote) Connect to YOURCOMPANY using the VPN Client
3) Once connected, press Ctrl / Alt / Del
4) From the menu, select Change Password
5) Enter your old password, then your new password twice.
6) Press OK
Administrator.
 </body></html>
And here’s the main code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using ActiveDs;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
using System.Configuration;
using System.Net.Mail;
using System.Resources;
using System.Reflection;
using System.Security.Principal;
 
namespace PasswordNotification
{
    class Program
    {
        public static string GetAdministratorEmail()
        {
            return SettingsProvider.Get("AdministratorEmail", "");
        }
        public static string GetMailServer()
        {
            return SettingsProvider.Get("MailServer", "");
        }
        public static string GetCountdown()
        {
            return SettingsProvider.Get("Countdown", "15");
        }
 
        static void Main(string[] args)
        {
            try
            {
                GetPasswordExpirationSendEmailNotifications();
            }
            catch (System.Exception ex)
            {
                SendEmail("<AdminEmail>", "<AdminEmail>", "Exception: Password Notification", ex.Message, MailPriority.High);
            }
        }
 
 // This method checks for flags like PasswordDoesNotExpire      
        private static bool CheckAdsFlag(AdsUserFlags flagToCheck, DirectoryEntry user)
        {
            AdsUserFlags userFlags = (AdsUserFlags)user.Properties["userAccountControl"].Value;
 
            return userFlags.ToString().Contains(flagToCheck.ToString());        }
 
 // This method gets the password expiration and sends email to
        // the users and a report to the Administrator
      
 
        private static void GetPasswordExpirationSendEmailNotifications()
        {
            string adminEmail = GetAdministratorEmail();            
           
      // Get the DOMAIN        
            //ActiveDs.ADSystemInfoClass objUserInformation = new ActiveDs.ADSystemInfoClass();
            //string sDomain = objUserInformation.DomainDNSName;
 
            string sDomain = Environment.UserDomainName;

// Since maxPwdAge is the Domain policy, it has to be retrieved for the
// domain
 
            TimeSpan maxPwdAge = TimeSpan.MinValue;
            int maxPwdAgeDays = 0;
            using (DirectoryEntry domain = new DirectoryEntry("LDAP://" + sDomain))
            {
                DirectorySearcher ds = new DirectorySearcher(
                    domain,
                    "(objectClass=*)",
                    null,
                    SearchScope.Base
                    );
 
                SearchResult sr = ds.FindOne();
 
                if (sr.Properties.Contains("maxPwdAge"))
                {
                    maxPwdAge = TimeSpan.FromTicks((long)sr.Properties["maxPwdAge"][0]);
                    maxPwdAgeDays = maxPwdAge.Days;
                }
                // maxPwdAge is in negative, make it positive      
                if (maxPwdAgeDays < 0)
                {
                    maxPwdAgeDays *= -1;
                }
            }
 
            //Define the filter for your LDAP query
            string filter = "(&(objectCategory=person)(objectClass=user))";
 
            DirectorySearcher search = new DirectorySearcher(filter);
            StringBuilder sb = new StringBuilder();
            sb.Append("<u>User Password Expiration Report</u><br/><br/>");
            int count = 0;
            bool sendReport = false;
 
            // Read file EmailBody.txt
            string filePath = String.Format("{0}\\EmailBody.txt", Directory.GetCurrentDirectory());
            string fileContents = TextFileReader(filePath);
 
            foreach (SearchResult result in search.FindAll())
            {
                // Do work with data returned for each address entry               
                DirectoryEntry entry = result.GetDirectoryEntry();
               
          // ActiveDs.LargeInteger needs to be used to manipulate pwdLastSet value
                LargeInteger liAcctPwdChange = entry.Properties["pwdLastSet"].Value as LargeInteger;
 
                string mailValue = "";
 
                if (entry.Properties["mail"].Value != null)
                {
                    mailValue = entry.Properties["mail"].Value.ToString();
                }
               
          // Skip the user if there is no email id
                if (string.IsNullOrEmpty(mailValue))
                {
                    continue;
                }
 
          // Skip the user if PasswordDoesNotExpire is set
                if(CheckAdsFlag(AdsUserFlags.PasswordDoesNotExpire, entry))
               {
                    continue;
                }
 
          // Manipulate LargeInteger liAcctPwdChange
 
                long dateAcctPwdChange = (((long)(liAcctPwdChange.HighPart) << 32) + (long)liAcctPwdChange.LowPart);
                // Convert FileTime to DateTime and get what today's date is.
                DateTime dtNow = DateTime.Now;
                // Add maxPwdAgeDays to dtAcctPwdChange
                DateTime dtAcctPwdChange = DateTime.FromFileTime(dateAcctPwdChange).AddDays(maxPwdAgeDays);
               
                // Calculate the difference between the date the pasword was changed, and
                // what day it is now.
                TimeSpan timeRemaining;
                timeRemaining = dtAcctPwdChange - dtNow;
               
                // Send email to users if their password is going to expire
 
                int countdown = Convert.ToInt32(GetCountdown());
                int daysRemaining = timeRemaining.Days;
               
                if (daysRemaining <= countdown)
                {
                    sendReport = true;
                    count++;
                    string displayName = "";
 
                    if (entry.Properties["displayname"].Value != null)
                    {
                        displayName = entry.Properties["displayname"].Value.ToString();
                    }
                                       
                    // DisplayName, Email, DaysRemaining
                    sb.AppendFormat("{0}. {1} {2}: {3} days remaining.{4}", count.ToString(), displayName, mailValue, daysRemaining.ToString(), "<br/>");
                                                           
                    string toEmail = mailValue;                   
                    string subject = String.Format("Password Expiration in {0} days", daysRemaining.ToString());                   
                    string body = fileContents.Replace("[DAYCOUNT]", daysRemaining.ToString());
                    body = body.Replace("[USERNAME]", displayName);
                    body = body.Replace("\r\n", "<br />");
                   
                    Console.Write(String.Format("Sending email to {0}...", toEmail));
                    SendEmail(adminEmail, toEmail, subject, body, MailPriority.High);
                    Console.WriteLine("Done.");
                }
            }
 
            // Only send email report to Administrator if required
            if (sendReport)
            {
                Console.Write(String.Format("Sending email to {0}...", adminEmail));
                SendEmail(adminEmail, adminEmail, "User Password Expiration Report", sb.ToString(), MailPriority.Normal);
                Console.WriteLine("Done.");
            }           
        }
 
        private static void SendEmail(string fromEmail, string toEmail, string subject, string body, MailPriority priority)
        {  
            string mailServer = GetMailServer();
 
            //create the mail message
            MailMessage mail = new MailMessage();
 
            //set the addresses
            mail.From = new MailAddress(fromEmail);
            mail.To.Add(toEmail);
 
            //set the content
            mail.Subject = subject;
            mail.Body = body;
            mail.IsBodyHtml = true;
            //send the message
            SmtpClient smtp = new SmtpClient(mailServer);
            smtp.Send(mail);
        }
 
        private static string TextFileReader(string filePath)
        {
            string fileContents = "";
            // create reader & open file
            using (TextReader tr = new StreamReader(filePath))
            {
                // read a line of text
                fileContents = tr.ReadToEnd();
            }
            return fileContents;
        }
 
        [Flags]
        internal enum AdsUserFlags
        {
            Script = 1,                          // 0x1
            AccountDisabled = 2,                 // 0x2
            HomeDirectoryRequired = 8,           // 0x8
            AccountLockedOut = 16,               // 0x10
            PasswordNotRequired = 32,            // 0x20
            PasswordCannotChange = 64,           // 0x40
            EncryptedTextPasswordAllowed = 128, // 0x80
            TempDuplicateAccount = 256,          // 0x100
            NormalAccount = 512,                 // 0x200
            InterDomainTrustAccount = 2048,      // 0x800
            WorkstationTrustAccount = 4096,      // 0x1000
            ServerTrustAccount = 8192,           // 0x2000
            PasswordDoesNotExpire = 65536,       // 0x10000
            MnsLogonAccount = 131072,            // 0x20000
            SmartCardRequired = 262144,          // 0x40000
            TrustedForDelegation = 524288,       // 0x80000
            AccountNotDelegated = 1048576,       // 0x100000
            UseDesKeyOnly = 2097152,              // 0x200000
            DontRequirePreauth = 4194304,         // 0x400000
            PasswordExpired = 8388608,           // 0x800000
            TrustedToAuthenticateForDelegation = 16777216, // 0x1000000
            NoAuthDataRequired = 33554432        // 0x2000000       
        }
    }
}
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Friday, October 30, 2009 8:44 AM | Feedback (9) |

Tuesday, September 22, 2009

SQL Server: DateTime and Indexes

A nice post about handling DateTime fields and indexing.

http://itknowledgeexchange.techtarget.com/sql-server/dates-can-easily-be-the-hardest-datatype-to-work-with/

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Tuesday, September 22, 2009 12:52 PM | Feedback (1) |

Tips n Tricks - Visual Studio

1. Disable HTML Navigation bar.

Tools -> Options -> Text Editor -> HTML -> Unckeck Navigation Bar option

2. Auto insert quotes when typing.

Tools -> Options -> Text Editor -> HTML -> Format -> Check "Insert attribute value quotes when typing"

3. Format HTML on paste

Tools -> Options -> Text Editor -> HTML -> Miscellaneous -> Format HTML on Paste

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Tuesday, September 22, 2009 7:37 AM | Feedback (5) |

Auto-Start in .NET 4.0

Here Scott talks about the new feature Auto-Start included in .NET 4.0 and IIS 7. This can prove really helpful in avoiding the initial delay experienced by the first visitor of a web ASP.NET application.

Here's the post.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Posted On Tuesday, September 22, 2009 7:25 AM | Feedback (1) |

Powered by: