Dailycode.info

Short solution for short problems

Service not available, closing transmission channel. The server response was: 4.3.2 Service not available, closing transmission channel

Trying to look up this error only gave 2 results and did not provide the simple solution for this problem I found.

Thsi code worked fine before we changed to a secure Exchange 2007 server.

MailBody.Insert(0, "Dear, <br><br>");
 
            string[] mails = toString.Split(';');
  
            MailAddress from = new MailAddress(sharepoint@dailycode.net);
 
            MailMessage Message = new MailMessage();
 
            foreach (string mailAdress in mails)
            {
                Message.To.Add(mailAdress);
            }
            Message.From = from;
            Message.Subject = "Document needs revising!";
            Message.Body = MailBody.ToString();
            Message.IsBodyHtml = true;
             
            SmtpClient smtpClient = new SmtpClient();
            smtpClient.Host = System.Configuration.ConfigurationSettings.AppSettings["SmtpServer"];
            smtpClient.Send(Message);

Then we changed and I got the beautifull error message: "Service not available, closing transmission channel. The server response was: 4.3.2 Service not available, closing transmission channel". So what did the trick was adding:

            smtpClient.UseDefaultCredentials = true;


You can also pass credentials if the program will run under a local user.  This can be done like this:

      smtpClient.Credentials = GetMailCredentials();
 
private static System.Net.NetworkCredential GetMailCredentials()
        {
            System.Net.NetworkCredential cred = new System.Net.NetworkCredential();
            cred.UserName = ConfigurationSettings.AppSettings["User"];
            cred.Password = ConfigurationSettings.AppSettings["Pwd"];
            cred.Domain = ConfigurationSettings.AppSettings["Dom"];
            return cred;
        }

Reading this makes it seem very logic, secure server disables anonymous login.

 

Sharepoint workflow security error

Working with WSS, I use a lot of simple workflows that are created in SharePoint Designer. Quick and easy creation, deploying and maintaining in normal scenarios. BUT:

Suddenly on my development environment, the workflows where giving following error message: "You do not have permission to do this operation. Ask your Web site administrator to change your permissions and then try again, or log on with a user account that has this permission. To log on with a different user account click OK. " I really had to look hard for a solution. At first I tried everything I could to ensure the users I was using had sufficient rigths. It appeared it had nothing to do with the users I was using. These are the symptoms I was having:

  • When I tried to save a workflow in SharePoint designer after I checked the options: Automatically start this workflow when item is created or changed I got this error: "You do not have permission to do this operation. Ask your Web site administrator to change your permissions and then try again, or log on with a user account that has this permission. To log on with a different user account click OK. "
  • When I tried to run a workflow manually I got an access denied error.

Googling didn't helped me a lot until I ended up here: http://kbalertz.com/947284/declarative-workflow-start-automatically-after-install-Windows-SharePoint-Services-Service.aspx

I set my application pool to run under the system account and then everything worked again. The reason why I started looking there was because on every web application on the server I had the same problems. It's strange that the sites kept on working but only the workflows had problems. After I changed the account for the application pool in the SharePoint administration website, I did a IISRESET /NOFORCE command.

Here's an article of Microsoft about this error: http://support.microsoft.com/kb/289335. The proposed solution could work in some cases, not in this case obviously!


Windows reboot shutdown command

When I'm working with remote desktop it's not always permitted to reboot the computer via the windows inferface. These options are available:

The first time I had to reboot, I tried some dos commands like: reboot or restart, but hat didn't worked. So I used a detour: I opened msconfig and modified something, just clicking on and off again and when I pressed OK the system asked me to reboot the computer. What can I say, I had no time to google...

After I looked for the command to reboot or shutdown a computer. SHUTDOWN was the command and it has some nice parameters:

-r : restart

-s : shutdown

-t : add some time to the shutdown in seconds

-a : cancel the shutdown.

\? will list all the possible parameters.

Here's an example:

Then I wanted to try the cancel command. I ran a shutdown command with 30 seconds delay:

Quickly opened the command prompt and ran this command:

And the shutdown was cancelled.

And another nice option of the shutdown command is the -i. This opens a dailog where you can choose a pc to shutdown, you can even shutdown multiple pc at the same time. If you are in a secured network, be sure to test this. In public places like schools etc. this command is often still enabled. You can shutdown computers remotely. You can imagine the possibilities in a classroom. ;-) Don't abuse it, just use it to point out the security leuks though ;-) Here's an image of the interface:

 


Simple security in ASP.Net pages

Just use a Masterpage and add this to the page load of the masterpage:

protected void Page_Load(object sender, EventArgs e)
    {
        //Login check
        if (Session["USERObj"] == null)
        {
            Response.Redirect(@"~\login.aspx");
        }
        else
        {
            lnkLogOff.Text = "Logoff " +  ((User)Session["USERObj"]).Name;
            BuildMenu((User)Session["USERObj"]);
        }
    }
 
private void BuildMenu(CCUser cCUser)
    {
	//Here I can build the navigation menu for this user.
 

On the login page you only have to check the users credentials and write the user object to the session.

Take note of the title, its a simple solution with high flexability. There are millions of way to secure a website, this is one of the most simple ways, especially when you want to implement active directory security:

This function checks username and pasword in AD:

public bool IsAuthenticated(string domain, string username, string pwd)
    {
      string domainAndUsername = domain + @"\" + username;
      string path = "";
      DirectoryEntry entry = new DirectoryEntry(path, domainAndUsername, pwd);
      
      try
      {
          DirectorySearcher search = new DirectorySearcher(entry);
 
          search.Filter = "(SAMAccountName=" + username + ")";
          search.PropertiesToLoad.Add("cn");
          SearchResult result = search.FindOne();
 
          if (null == result)
          {
              return false;
          }
      }
      catch (Exception ex)
      {
          throw ex;
      }
 
      return true;
    }

If username and pasword are validated, then write a User object to the session. The masterpage will perform the login check. I created multiple masterpages, if a page is public, I use a different masterpage, this is not needed, but has a lot of advantages. You can enforce a differtent look for public pages and non-public pages, ...

In the public masterpage I still check for a logged in user but there will be no redirect:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["USERObj"] == null)
        {
            lnkLogOff.Text = "Login";
        }
        else
        {
            lnkLogOff.Text = "Logoff " +  ((CCPL.CC_Objects.User)Session["USERObj "]).Name;
        }
    }

Tip, make sure the login page uses the public masterpage, else it would keep rederecting or you'll have to write dirty code.


Print multiple pages with PrintDocument class

When you just want to print a single page, it very easy and all you need is a couple of lines of code:

Declare the instance:

private PrintDocument printDoc = new PrintDocument();
 

Add the eventhandler to the printdocument object:

printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);

Then you can start printing your document in the event handler:

int yPosition = e.MarginBounds.Bottom - 10;
int xPosition = e.MarginBounds.Right - 150;
string toPrint = string.Format("Printed on {0:dd-MMM-yyyy}", DateTime.Now);
e.Graphics.DrawString(toPrint, _normalFont, new SolidBrush(Color.Black), xPosition, yPosition);
 

But when you start writing more and more lines on the page, you will notice that it will only print one page. In order to print several pages, we need to set the HasMorePages flag. What you have to understand is that setting this flag will fire a new print page event after this event is handled.

In this example I have to print a dataset with data from a database. In my loop I have to check: whether the height of the current line is not greater then the page bottom bound. If so, I will have to remember which line I'm in, set the hasmorepages flag and exit the loop. Here is the code:

private int countline = 0;
... 
private void printDoc_PrintPage(Object sender, PrintPageEventArgs e)
{
...
for (int i = countLine; i < ds.Tables[0].Rows.Count;i++)
{
	DataRow dt = ds.Tables[0].Rows[i];
	x = 20;
	e.Graphics.DrawString(dt["Study_number"].ToString(), _normalFont, Brushes.Black, x, y);
	x = x + 130;
        e.Graphics.DrawString(dt["tube"].ToString(), _normalFont, Brushes.Black, x, y);
        x = x + 130;
        e.Graphics.DrawString(dt["total"].ToString(), _normalFont, Brushes.Black, x, y);
        x = x + 130;
        y = y + 20;
        if (y + 20 > e.MarginBounds.Bottom)
        {
        	countLine = i+1;
                e.HasMorePages = true;
                break;
	}
}
 

The countline variable is declare in the class and keeps track of the record I'm handling. When a page is full, the event is ended. When a new printpage event is fired the loop starts where the last page stopped. The printdocument is a performant way to pint documents. I think its perfect for printing data tables in a simple and fast way. If you start adding style to it, you'll better look for open source or 3rd party software, because you can loose to much time.