Sunday, May 26, 2013

SharePoint Workflow : Custom form fundamentals

Three types of tools are available in SharePoint to build custom forms: (1)out-of-thebox
forms (auto-generated), (2) InfoPath forms, and (3) ASP.NET forms.

InfoPath Form
 if you want check boxes instead of radio buttons? Or, you need more detailed instructions, logos, or graphics on the form to make it more graphically appealing? Or, the data in the dropdowns may need to come from an external line-of-business application.Requirements such as pulling business data out of web services, dynamic filtering of controls, and advanced validation of form fields upon submission can all be easily accomplished with InfoPath.

An InfoPath form may reside as a document in what’s called a Form Library within a SharePoint site,the form itself was uploaded into the form library as an attachment, and that attachment contained the data as XML.

Another way in which InfoPath interacts with SharePoint lists is through the customization of a list or library’s New and Edit forms. When you customize the out-ofthe-box forms, the data in those forms is always mapped to columns in the list or library.

So how do you know when to customize the out-of-the-box forms versus using a form library? Consider how much data you’ll be interacting with. If you customize out-of-thebox forms, you need a column for every piece of data you want to save. If you use a form library, that data is stored as XML in the form itself, so you don’t need to have any extra columns on the document. A good rule of thumb is 15. If your form needs to save more than 15 pieces of data, it’s better to use a form library than create 15 columns on a list.

PROS
Drag-and-drop functions and wizard-based experience. You don’t have to be a programmer. Supports advanced form customizations like connecting to external data, rules, and conditions.
CONS
Requires a SharePoint Server Enterprise license to host the form in the browser; otherwise, the InfoPath client application is needed to fill out a form.



ASP.NET forms built in Visual Studio
you can replace the New and Edit out-of-the-box forms with a custom ASP.NET form. You can write a custom ASP.NET form and embed that form within a web part. When a user submits that form, you can use the SharePoint object model to add a new list item in a list and start a workflow on that item.

Saturday, May 25, 2013

Console Applivation write text log for each print/printline

public static void GenerateUniqueLogFile()
        {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            FileInfo fileInfo = new FileInfo(executingAssembly.Location);

            string logFileName = fileInfo.Name + "_" + DateTime.Now.ToString("dd_MMM_yyyy_hh_mm") + ".log";
            string logFileFullPath = Path.Combine(fileInfo.DirectoryName, logFileName);
            StreamWriter logWriter = new StreamWriter(logFileFullPath);
            TextWriterTraceListener listener = new TextWriterTraceListener(logWriter);
            Trace.Listeners.Add(listener);
            Trace.AutoFlush = true;
        }

Call GenerateUniqueLogFile() function on first line of Main function :-)


Console Application string extension to print/printline with color

public static class Extensions
    {

        public static string Print(this string content)
        {
            content.Print(null);
            return content;
        }

        public static string PrintLine(this string content)
        {
            content.PrintLine(null);
            return content;
        }

        public static string Print(this string content, ConsoleColor? fontColor)
        {
            if (fontColor.HasValue)
            {
                Console.ForegroundColor = fontColor.Value;
            }

            Console.Write(content);
            Console.ResetColor();

            Trace.Write(content);
            return content;
        }

        public static string PrintLine(this string content, ConsoleColor? fontColor)
        {
            if (fontColor.HasValue)
            {
                Console.ForegroundColor = fontColor.Value;
            }
            Console.WriteLine(content);
            Console.ResetColor();
            Trace.WriteLine(content);
            return content;
        }

        public static string Print(this string content, ConsoleColor? fontColor, ConsoleColor? backgroundColor)
        {
            if (fontColor.HasValue)
            {
                Console.ForegroundColor = fontColor.Value;
            }

            if (backgroundColor.HasValue)
            {
                Console.BackgroundColor = backgroundColor.Value;
            }
            Console.Write(content);
            Console.ResetColor();
            Trace.Write(content);
            return content;
        }

        public static string PrintLine(this string content, ConsoleColor? fontColor, ConsoleColor? backgroundColor)
        {
            if (fontColor.HasValue)
            {
                Console.ForegroundColor = fontColor.Value;
            }

            if (backgroundColor.HasValue)
            {
                Console.BackgroundColor = backgroundColor.Value;
            }


            Console.WriteLine(content);
            Console.ResetColor();
            Trace.WriteLine(content);
            return content;
        }

        public static byte[] GetBytes(this string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }

        public static string GetString(this byte[] bytes)
        {
            char[] chars = new char[bytes.Length / sizeof(char)];
            System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
            return new string(chars);
        }
       
    }

Monday, May 6, 2013

SetState Activity in SharePoint Sequential Workflow


Workflow has some built in values like, “In Progress”, “Failed on Start”, Error Occurred”, etc. The integer value for MAX is 15. The values from 0 to 14 are reserved for internal and built-in values such as InProgress, Completed, Error Occurred etc. 

First we must open the Elements.xml file and place the code below:
<ExtendedStatusColumnValues>
        <StatusColumnValue>Pending</StatusColumnValue>
        <StatusColumnValue>Started</StatusColumnValue>
        <StatusColumnValue>Phase First Completed</StatusColumnValue>
        <StatusColumnValue>On Last Stage</StatusColumnValue>
        <StatusColumnValue>Completed</StatusColumnValue>
  </ExtendedStatusColumnValues>

Let us assume that your "SetState" activity name is "InitialState". When you double click on the "SetState" activity, insert the line below in the code window:
InitialState.State = (Int32)SPWorkflowStatus.MAX;
The integer value for MAX is 15.

Friday, May 3, 2013

Restore Database SQL script


Restore Database SQL script

USE [master]
RESTORE FILELISTONLY
FROM DISK = N'D:\Biraj\TestDB.bak'
GO
ALTER DATABASE TestDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
RESTORE DATABASE [TestDB20130513] FROM  DISK = N'D:\Biraj\TestDB.bak' WITH  FILE = 1,
MOVE N'TestDB' TO N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\TestDB20130513.mdf',
MOVE N'TestDB_log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\TestDB_log20130513.ldf',  NOUNLOAD,  STATS = 5
GO
ALTER DATABASE TestDB SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO

Friday, April 26, 2013

Send email asynchronously second time in case of first time failure


public class Mailer : ComposeMail
{
public StringBuilder m_ExecutionStack = null;
public StringBuilder ExecutionStack
{
get
{
if (m_ExecutionStack == null)
{
m_ExecutionStack = new StringBuilder();
}
return m_ExecutionStack;
}
}

public bool IsSecondAttemptDone { get; set; }

public SmtpClient SMTPClient
{
get;
set;
}

public bool IsMailSent
{
get;
set;
}

public MailMessage Message
{
get;
set;
}

public Mailer(string siteUrl)
: base(siteUrl)
{
try
{
ExecutionStack.AppendLine("Initilizing Mailer Object");
Message = new MailMessage();
SMTPClient = new SmtpClient(base.SMTP);
SMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);

ExecutionStack.AppendLine("Initilizing Mailer Object Done");
}
catch (Exception ex)
{
ExecutionStack.AppendLine("Error : Initilizing Mailer Object");
throw ex;
}
}

public void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;
ExecutionStack.AppendLine("Send Mail completed event :" + token);

if (e.Error != null)
{
IsSecondAttemptDone = true;

ExecutionStack.AppendLine("Error Sending Mail");
ExecutionStack.AppendLine("Details : " + token + " ->" + e.Error.InnerException.ToString());

System.Diagnostics.EventLog.WriteEntry("Application", "Mailer : Send Mail completed event :  -> " + ExecutionStack.ToString(), System.Diagnostics.EventLogEntryType.Error);

ExecutionStack.AppendLine("Trying to re send mail ");
SMTPClient.SendAsync(Message, token);
ExecutionStack.AppendLine("Re send mail code execution done");
}

IsMailSent = true;
}

public void SendMail(string from, string to)
{
ExecutionStack.AppendLine("Inside SendMail Function");

try
{
if (!String.IsNullOrEmpty(FROMEMAIL))
{
ExecutionStack.AppendLine("Setting From Email");
Message.From = new MailAddress(FROMEMAIL);
Message.Priority = EmailPriority;
string[] toAddresses = to.Split(';');
for (int i = 0; i < toAddresses.Length; i++)
{
if (toAddresses[i] != string.Empty)
{
string[] nameID = toAddresses[i].Split(',');
if (nameID.Length == 2)
Message.To.Add(new MailAddress(nameID[0], nameID[1]));
else
Message.To.Add(new MailAddress(toAddresses[i]));
}
}
if (CC != null)
{
ExecutionStack.AppendLine("Setting CC");
string[] ccAddresses = CC.Split(';');
for (int i = 0; i < ccAddresses.Length; i++)
{
if (ccAddresses[i] != string.Empty)
{
string[] nameID = ccAddresses[i].Split(',');
if (nameID.Length == 2)
Message.CC.Add(new MailAddress(nameID[0], nameID[1]));
else
Message.CC.Add(new MailAddress(ccAddresses[i]));
}
}
}

if (BCC != null)
{
ExecutionStack.AppendLine("Setting BCC");
string[] bccAddresses = BCC.Split(';');
for (int i = 0; i < bccAddresses.Length; i++)
{
if (bccAddresses[i] != string.Empty)
{
string[] nameID = bccAddresses[i].Split(',');
if (nameID.Length == 2)
Message.Bcc.Add(new MailAddress(nameID[0], nameID[1]));
else
Message.Bcc.Add(new MailAddress(bccAddresses[i]));
}

}
}

ExecutionStack.AppendLine("Setting Subject, Body ");
Message.Subject = Subject;
Message.Body = Body;
Message.IsBodyHtml = ISBODYHTML;

if (ISIMAGEEMBED)
{
ExecutionStack.AppendLine("Setting Embedded Images");
try
{
AlternateView aView = AlternateView.CreateAlternateViewFromString(Body, null, MediaTypeNames.Text.Html);
Message.IsBodyHtml = true;

LinkedResource[] linkedResources = new LinkedResource[IMAGEPATH.Count];
for (int i = 0; i < IMAGEPATH.Count; i++)
{
linkedResources[i] = new LinkedResource(IMAGEPATH[i].ToString());
linkedResources[i].ContentId = CONTENTID[i].ToString();
}
for (int i = 0; i < IMAGEPATH.Count; i++)
{
aView.LinkedResources.Add(linkedResources[i]);
}
Message.AlternateViews.Add(aView);
}
catch (Exception ex1)
{
System.Diagnostics.EventLog.WriteEntry("Application", "Mailer : Error: Inside SendMail Function : Setting Embedded Images : " + ex1.Message + " -> " + ExecutionStack.ToString(), System.Diagnostics.EventLogEntryType.Error);
ExecutionStack.AppendLine("Error Setting Embedded Images");
throw ex1;
}
}

if (ISATTACHMENTS)
{
ExecutionStack.AppendLine("Setting Attachments");
try
{
StreamReader fileReader = new StreamReader(ATTACHMENTPATH);
if (ValidateAttachment(fileReader.BaseStream))
{
Attachment attachment = new Attachment(fileReader.BaseStream, ATTACHMENTNAME);
Message.Attachments.Add(attachment);
}
}
catch (Exception ex2)
{
ExecutionStack.AppendLine("Error Setting Attachments");
throw ex2;
}
}

ExecutionStack.AppendLine("SMTP Server :" + SMTP);
if (!String.IsNullOrEmpty(SMTP))
{
ExecutionStack.AppendLine("Sending mail in SMTP Server :" + Message.Headers);
SMTPClient.Timeout = int.MaxValue;

SMTPClient.Send(Message);
IsMailSent = true;
ExecutionStack.AppendLine("Sending mail done" + Message.Headers);
}
}
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Application", "Mailer : Error: Inside SendMail Function " + ex.Message + " -> " + ExecutionStack.ToString(), System.Diagnostics.EventLogEntryType.Error);
ExecutionStack.AppendLine("Error: Inside SendMail Function" + ex.InnerException.ToString());
ExceptionHandler.Publish(ex, ex.Message, Severity.Fatal);
IsMailSent = false;
//throw ex;
}
}

private bool ValidateAttachment(Stream attachmentStream)
{
bool status = false;
try
{
if (attachmentStream.Length >= ATTACHMENTSIZE * 1024)
{
status = false;
}
else
{
status = true;
}
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Application", "Mailer : ValidateAttachment Method " + ex.Message, System.Diagnostics.EventLogEntryType.Error);
//throw ex;
}
return status;
}
}

Sunday, April 21, 2013

Received-SPF: SoftFail


Received-SPF: SoftFail (msc1-1-bnov.domainname.net: domain of
transitioning abc@anotherdomain.com discourages use of 127.0.0.0 as permitted sender)

The SoftFail is being thrown because of an invalid address in the FROM field of the message. SPF is a specialized check email servers do to protect themselves from being used as spam relays

Solution:
$list = (Get-ContentFilterConfig).BypassedSenders
$list.add("mail@domain.com")
Set-ContentFilterConfig -BypassedSenders $list

Monday, March 4, 2013

XML to XSD to CS Code generator


1) Generate XML with desired tags

<?xml version="1.0"?>
<FLSecurity>
    <MainForm Type="CoreForm" Name="EmployeeDetails.aspx" DisplayName="Employee Details Management">
        <SubForms>
            <SubForm Name="EmployeeDetails.ascx" DisplayName="Employee Details">
                <Controls>
                    <Control Type="DataBound" DisplayName="Business Unit" ID="OrgStructureName" ParentControl="Grid" AssociateControl="lblOrgStructure">                       
                            <UserRoles>
                                <Role ID="1" DisplayName="BC Admin">
                                    <IsVisible>True</IsVisible>
                                    <IsEnabled>True</IsEnabled>
                                </Role>
                            </UserRoles>                       
                    </Control>                   
                </Controls>
            </SubForm>
        </SubForms>
    </MainForm>    
</FLSecurity>
        
2) Generate XSD from XML
xsd file.xml {/classes | /dataset} [/element:element]
             [/language:language] [/namespace:namespace]
3)Create XSD to Code
               http://xsd2code.codeplex.com/

Wednesday, October 10, 2012

Branding Master Page SharePoint 2010 - center fix contents


Remove scroll="no" from body tag

body
{
overflow:auto !important;
}
/* start : make ribbon fix and keep in center*/
#s4-ribbonrow
{
width:1003px !important;
margin:auto !important;
float:none;
height:100% !important;
}
#s4-ribboncont
{
background-color:rgb(33, 55, 76) !important;
z-index:1000;
width:1003px;
}
/* end : make ribbon fix and keep in center*/
#s4-bodyContainer, #s4-statusbarcontainer, #s4-mainarea
{
width:1003px;
margin:auto;
float:none !important;
}
.s4-ca {
margin-left:0px !important;
}
body #s4-workspace {
left:0;
overflow:visible;
position:relative;
}

html.ms-dialog body #s4-workspace {
overflow-x:auto;
overflow-y:scroll;
}

Tuesday, September 25, 2012

MOSS 2007 Sequential WorkFlow Findings / Errors / Challenges

Sharepoint 2007 Workflow – Failed on start (retrying)
change service account as Administrator for application pool from Admin Settings 

To update task list columns values on createTask1_MethodInvoking use TaskProperties.ExtendedProperties["OffsiteParticipant"]

onTaskChanged1_Invoked
AfterProperties.ExtendedProperties["TaskStatus"]  as string == "#" - Task Approved
AfterProperties.ExtendedProperties["TaskStatus"]  as string == "@" - Task reejcted
onTaskChanged1.AfterProperties.ExtendedProperties["Comments"] - Get Approvers Comments

Always use separate task token for task than Workflow token, also use separate task token if generating second task

Workflow task: Value does not fall within the expected range
 1)  approver should have Contributor permission on tasklistitem
 2)  approver should have Read permission on workflowItem (user web.ensureuser to add user to site if doc lib inherit permission from parent web)