Sunday, January 26, 2014

How to generate the invoice form as PDF file using iTextSharp

We often generate the invoice form as PDF format and send the customer as reference. Microsoft Crystal Report and Telerik Report are handy but expensive for small business. There are other API. Among them, I prefer iTextSharp since it is widely used and lot of examples online. You can download here. I show you how to used iTextSharp for generating PDF as below :
Invoice PDF
Our interface has textboxs and gridview for accepting and displaying Data. It has two options (Download PDF and Send PDF with email). If select the first radio and press "Create PDF" button, it downloads the PDF. Otherwise, it gets the byte array of invoice PDF in code-behind. Web interface should be as below :

User Input Data
First, we download the "itextsharp.dll" and add reference at web site as below:
We need the following namespace in web page as below:
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Data;
Copy the following code into form tag for interface :
<form id="form1" runat="server">
<div>
    <asp:Label ID="Label1" runat="server" Text="Order No :" Width="120px"></asp:Label>
    <asp:TextBox ID="txtOrderNo" runat="server"></asp:TextBox><br/>
    <asp:Label ID="Label2" runat="server" Text="Customer Name :" Width="120px"></asp:Label>
    <asp:TextBox ID="txtCustomerName" runat="server">John Willion</asp:TextBox><br />
    <asp:Label ID="Label3" runat="server" Text="Address :" Width="120px"></asp:Label>
    <asp:TextBox ID="txtAddress" runat="server" Height="74px" TextMode="MultiLine" Width="249px">No. 123, New Panasin Street, Ramkhamkeang 24/1, Bangkapi, Bangkok, 10200.</asp:TextBox>
</div>
<div>
    <asp:RadioButton ID="rdoDownload" runat="server" Checked="True" GroupName="pdf" Text="Download PDF" />
    <asp:RadioButton ID="rdoSendEmail" runat="server" GroupName="pdf" Text="Send PDF with email" />
</div>
<div>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" Font-Names="Arial"
        Font-Size="11pt" AlternatingRowStyle-BackColor="#C2D69B" HeaderStyle-BackColor="green"
        AllowPaging="true" PageSize="10" OnPageIndexChanging="GridView1_PageIndexChanging">
        <Columns>
            <asp:BoundField ItemStyle-Width="150px" DataField="NO" HeaderText="NO" />
            <asp:BoundField ItemStyle-Width="150px" DataField="ITEM" HeaderText="ITEM" />
            <asp:BoundField ItemStyle-Width="150px" DataField="QUANTITY" HeaderText="QUANTITY" />
            <asp:BoundField ItemStyle-Width="150px" DataField="AMOUNT" HeaderText="AMOUNT(IDR)" />
        </Columns>
    </asp:GridView>
</div>
<div>
    <asp:Button ID="Button1" runat="server" Text="Create PDF" OnClick="Button1_Click" />
</div>
</form>

Copy the following code to code-behind for class variables and data binding for gridview :
//Class Variables
string orderNo = DateTime.Now.Ticks.ToString().Substring(0, 6);
string orderDate = DateTime.Now.ToString("dd MMM yyyy");
decimal totalAmtStr;
string accountNo = "0123456789012";
string accountName = "John Willion";
string branch = "Phahon Yothin Branch";
string bank = "Kasikorn Bank";

// for Gridview
DataTable dt = new DataTable();

protected void Page_Load(object sender, EventArgs e)
{
    //This sample used iTextShart.dll - 4.1.6.0
    // DataTable binding
    txtOrderNo.Text = orderNo;
    dt.Columns.Add("NO", Type.GetType("System.String"));
    dt.Columns.Add("ITEM", Type.GetType("System.String"));
    dt.Columns.Add("QUANTITY", Type.GetType("System.String"));
    dt.Columns.Add("AMOUNT", Type.GetType("System.String"));

    for (int i = 0; i < 10; ++i)
    {
        dt.Rows.Add();
        dt.Rows[i]["NO"] = (i + 1).ToString();
        dt.Rows[i]["ITEM"] = "Item " + i.ToString();
        dt.Rows[i]["QUANTITY"] = (i + 1).ToString();
        dt.Rows[i]["AMOUNT"] = (i + 1).ToString();
        totalAmtStr += (i + 1);
    }

    //GridView 
    GridView1.DataSource = dt;
    GridView1.DataBind();
}
Let's create "CreatePDF()" function in code-behind as below:
protected MemoryStream CreatePDF()
{
    // Create a Document object
    Document document = new Document(PageSize.A4, 70, 70, 70, 70);

    //MemoryStream
    MemoryStream PDFData = new MemoryStream();
    PdfWriter writer = PdfWriter.GetInstance(document, PDFData);

    // First, create our fonts
    var titleFont = FontFactory.GetFont("Arial", 14, Font.BOLD);
    var boldTableFont = FontFactory.GetFont("Arial", 10, Font.BOLD);
    var bodyFont = FontFactory.GetFont("Arial", 10, Font.NORMAL);
    Rectangle pageSize = writer.PageSize;

    // Open the Document for writing
    document.Open();
    //Add elements to the document here

    #region Top table
    // Create the header table 
    PdfPTable headertable = new PdfPTable(3);
    headertable.HorizontalAlignment = 0;
    headertable.WidthPercentage = 100;
    headertable.SetWidths(new float[] { 4, 2, 4 });  // then set the column's __relative__ widths
    headertable.DefaultCell.Border = Rectangle.NO_BORDER;
    //headertable.DefaultCell.Border = Rectangle.BOX; //for testing
    headertable.SpacingAfter = 30;
    PdfPTable nested = new PdfPTable(1);
    nested.DefaultCell.Border = Rectangle.BOX;
    PdfPCell nextPostCell1 = new PdfPCell(new Phrase("ABC Co.,Ltd", bodyFont));
    nextPostCell1.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
    nested.AddCell(nextPostCell1);
    PdfPCell nextPostCell2 = new PdfPCell(new Phrase("111/206 Moo 9, Ramkhamheang Road,", bodyFont));
    nextPostCell2.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
    nested.AddCell(nextPostCell2);
    PdfPCell nextPostCell3 = new PdfPCell(new Phrase("Nonthaburi 11120", bodyFont));
    nextPostCell3.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
    nested.AddCell(nextPostCell3);
    PdfPCell nesthousing = new PdfPCell(nested);
    nesthousing.Rowspan = 4;
    nesthousing.Padding = 0f;
    headertable.AddCell(nesthousing);

    headertable.AddCell("");
    PdfPCell invoiceCell = new PdfPCell(new Phrase("INVOICE", titleFont));
    invoiceCell.HorizontalAlignment = 2;
    invoiceCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(invoiceCell);
    PdfPCell noCell = new PdfPCell(new Phrase("No :", bodyFont));
    noCell.HorizontalAlignment = 2;
    noCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(noCell);
    headertable.AddCell(new Phrase(orderNo, bodyFont));
    PdfPCell dateCell = new PdfPCell(new Phrase("Date :", bodyFont));
    dateCell.HorizontalAlignment = 2;
    dateCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(dateCell);
    headertable.AddCell(new Phrase(orderDate, bodyFont));
    PdfPCell billCell = new PdfPCell(new Phrase("Bill To :", bodyFont));
    billCell.HorizontalAlignment = 2;
    billCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(billCell);
    headertable.AddCell(new Phrase(txtCustomerName.Text + "\n" + txtAddress.Text, bodyFont));
    document.Add(headertable);
    #endregion

    #region Items Table
    //Create body table
    PdfPTable itemTable = new PdfPTable(4);
    itemTable.HorizontalAlignment = 0;
    itemTable.WidthPercentage = 100;
    itemTable.SetWidths(new float[] { 10, 40, 20, 30 });  // then set the column's __relative__ widths
    itemTable.SpacingAfter = 40;
    itemTable.DefaultCell.Border = Rectangle.BOX;
    PdfPCell cell1 = new PdfPCell(new Phrase("NO", boldTableFont));
    cell1.HorizontalAlignment = 1;
    itemTable.AddCell(cell1);
    PdfPCell cell2 = new PdfPCell(new Phrase("ITEM", boldTableFont));
    cell2.HorizontalAlignment = 1;
    itemTable.AddCell(cell2);
    PdfPCell cell3 = new PdfPCell(new Phrase("QUANTITY", boldTableFont));
    cell3.HorizontalAlignment = 1;
    itemTable.AddCell(cell3);
    PdfPCell cell4 = new PdfPCell(new Phrase("AMOUNT(USD)", boldTableFont));
    cell4.HorizontalAlignment = 1;
    itemTable.AddCell(cell4);

    foreach (DataRow row in dt.Rows)
    {
        PdfPCell numberCell = new PdfPCell(new Phrase(row["NO"].ToString(), bodyFont));
        numberCell.HorizontalAlignment = 0;
        numberCell.PaddingLeft = 10f;
        numberCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(numberCell);

        PdfPCell descCell = new PdfPCell(new Phrase(row["ITEM"].ToString(), bodyFont));
        descCell.HorizontalAlignment = 0;
        descCell.PaddingLeft = 10f;
        descCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(descCell);

        PdfPCell qtyCell = new PdfPCell(new Phrase(row["QUANTITY"].ToString(), bodyFont));
        qtyCell.HorizontalAlignment = 0;
        qtyCell.PaddingLeft = 10f;
        qtyCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(qtyCell);

        PdfPCell amtCell = new PdfPCell(new Phrase(row["AMOUNT"].ToString(), bodyFont));
        amtCell.HorizontalAlignment = 1;
        amtCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(amtCell);

    }
    // Table footer
    PdfPCell totalAmtCell1 = new PdfPCell(new Phrase(""));
    totalAmtCell1.Border = Rectangle.LEFT_BORDER | Rectangle.TOP_BORDER;
    itemTable.AddCell(totalAmtCell1);
    PdfPCell totalAmtCell2 = new PdfPCell(new Phrase(""));
    totalAmtCell2.Border = Rectangle.TOP_BORDER; //Rectangle.NO_BORDER; //Rectangle.TOP_BORDER;
    itemTable.AddCell(totalAmtCell2);
    PdfPCell totalAmtStrCell = new PdfPCell(new Phrase("Total Amount", boldTableFont));
    totalAmtStrCell.Border = Rectangle.TOP_BORDER;   //Rectangle.NO_BORDER; //Rectangle.TOP_BORDER;
    totalAmtStrCell.HorizontalAlignment = 1;
    itemTable.AddCell(totalAmtStrCell);
    PdfPCell totalAmtCell = new PdfPCell(new Phrase(totalAmtStr.ToString("#,###.00"), boldTableFont));
    totalAmtCell.HorizontalAlignment = 1;
    itemTable.AddCell(totalAmtCell);

    PdfPCell cell = new PdfPCell(new Phrase("*** Please note that ABC Co., Ltd’s bank account is USD Bank Account ***", bodyFont));
    cell.Colspan = 4;
    cell.HorizontalAlignment = 1;
    itemTable.AddCell(cell);
    document.Add(itemTable);
    #endregion

    Chunk transferBank = new Chunk("Your Bank Account:", boldTableFont);
    transferBank.SetUnderline(0.1f, -2f); //0.1 thick, -2 y-location
    document.Add(transferBank);
    document.Add(Chunk.NEWLINE);

    // Bank Account Info
    PdfPTable bottomTable = new PdfPTable(3);
    bottomTable.HorizontalAlignment = 0;
    bottomTable.TotalWidth = 300f;
    bottomTable.SetWidths(new int[] { 90, 10, 200 });
    bottomTable.LockedWidth = true;
    bottomTable.SpacingBefore = 20;
    bottomTable.DefaultCell.Border = Rectangle.NO_BORDER;
    bottomTable.AddCell(new Phrase("Account No", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(accountNo, bodyFont));
    bottomTable.AddCell(new Phrase("Account Name", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(accountName, bodyFont));
    bottomTable.AddCell(new Phrase("Branch", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(branch, bodyFont));
    bottomTable.AddCell(new Phrase("Bank", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(bank, bodyFont));
    document.Add(bottomTable);

    //Approved by
    PdfContentByte cb = new PdfContentByte(writer);
    BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, true);
    cb = writer.DirectContent;
    cb.BeginText();
    cb.SetFontAndSize(bf, 10);
    cb.SetTextMatrix(pageSize.GetLeft(300), 200);
    cb.ShowText("Approved by,");
    cb.EndText();
    //Image Singature
    iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/Bill_Gates2.png"));
    logo.SetAbsolutePosition(pageSize.GetLeft(300), 140);
    document.Add(logo);

    cb = new PdfContentByte(writer);
    bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, true);
    cb = writer.DirectContent;
    cb.BeginText();
    cb.SetFontAndSize(bf, 10);
    cb.SetTextMatrix(pageSize.GetLeft(70), 100);
    cb.ShowText("Thank you for your business! If you have any questions about your order, please contact us at 800-555-NORTH.");
    cb.EndText();

    writer.CloseStream = false; //set the closestream property
    // Close the Document without closing the underlying stream
    document.Close();
    return PDFData;
}
Copy the following function to code-behind for downloading the Invoice PDF:
protected void DownloadPDF(System.IO.MemoryStream PDFData)
{
    // Clear response content & headers
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/pdf";
    Response.Charset = string.Empty;
    Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=Receipt-{0}.pdf", orderNo));
    Response.OutputStream.Write(PDFData.GetBuffer(), 0, PDFData.GetBuffer().Length);
    Response.OutputStream.Flush();
    Response.OutputStream.Close();
    Response.End();
}
Finally, copy the following code into "Button1_Click" :
protected void Button1_Click(object sender, EventArgs e)
{
    if (rdoDownload.Checked)
    {
        DownloadPDF(CreatePDF());
    }
    else
    {
        MemoryStream ms = CreatePDF();
        ms.Position = 0; //Set pointer to the beginning of the stream
        byte[] PDFData = new byte[ms.Length];
        ms.Read(PDFData, 0, (int)ms.Length); // get byte arrary for PDF 
       // Attach byte array to email here
    }
}

Hope this helps,
SI THU

Reference :
http://www.4guysfromrolla.com/articles/030911-1.aspx
http://www.mikesdotnetting.com/Article/86/iTextSharp-Introducing-Tables

Sunday, September 15, 2013

How to create link button and event handler programmatically in user control

We often have the scenario that it need to generate LinkButtons in our web application depend on user role or action. This post explain you step by step how to create link buttons and their event handler dramatically in user control and use in .aspx page as below image :
Dynamic link buttons
First, create one user control ("LinkButtonControl.ascx") and copy the following code to that control. It uses PlaceHolder contron that is to store dynamically added server controls on the Web page.
<fieldset style="width: 200px;">
    <legend>Dynamic Links</legend>
    <ul>
        <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
    </ul>
</fieldset>
In code-behind, it should look like as below :
public partial class LinkButtonControl : System.Web.UI.UserControl
{
    //Declare event handler 
    public delegate void LinkButtonEventHandler(object sender, EventArgs e);
    public event LinkButtonEventHandler LinkButtonClick;
    //Create generic list object 
    List<LinkControl> linkControlList = new List<LinkControl>();

    protected void Page_Load(object sender, EventArgs e)
    {
        //Add the sample data to generic list
        linkControlList.Add(new LinkControl { Name = "aboutus", Title = "About Us", Url = "aboutus.aspx" });
        linkControlList.Add(new LinkControl { Name = "contactus", Title = "Contact Us", Url = "contactus.aspx" });
        linkControlList.Add(new LinkControl { Name = "tou", Title = "Term of use", Url = "TOU.aspx" });
        CreateLinkButtons();
    }
    public void CreateLinkButtons()
    {
        foreach (var link in linkControlList)
        {
            //Create LinkButton programmatically 
            LinkButton lb = new LinkButton();
            lb.ID = link.Name;
            lb.Text = link.Title;
            lb.CommandArgument = link.Url;
            lb.Click += new EventHandler(this.LinkButtonClick);
            //Add LinkButton to PlaceHolder
            PlaceHolder1.Controls.Add(new LiteralControl(@"<li>"));
            PlaceHolder1.Controls.Add(lb);
            PlaceHolder1.Controls.Add(new LiteralControl(@"</li>"));
        }
    }
    protected void LinkButton_Click(object sender, EventArgs e)
    {
        if (LinkButtonClick != null)
            LinkButtonClick(sender, e);
    }
}
//Data Transfer Object class  
public class LinkControl
{
    public string Name{get; set; }
    public string Title { get; set; }
    public string Url { get; set; }
}
Second, create one .aspx page("UserControlTest.aspx") and add the follow CSS to <head> tag for link button layout.
<style type="text/css">
    ul 
    {
        list-style-type: none;
        margin: 0;
        padding: 0;
    }
</style>
Finally, drag and drop our user control ("LinkButtonControl.ascx") to .aspx page and add "OnLinkButtonClick" event manually as below :
<uc1:LinkButtonControl ID="LinkButtonControl1" runat="server" OnLinkButtonClick="LinkButtonControl1_Click" />    
Copy the following code snippet to code-behind for event implementation.   
protected void LinkButtonControl1_Click(object sender, EventArgs e)
{
    LinkButton lb = sender as LinkButton;
    if (lb != null)
        Response.Redirect(lb.CommandArgument);
}
That's it.

Hope this helps
SI THU WIN

Sunday, July 21, 2013

How to create and read Xml in asp.net

We often have to deal with Xml message when our applications are integrated with SMS Api, Email Api or Payment Api. At that time, we prepare Xml message and feed the services. Likewise, it gets the Xml message from the service of API and extracts the message from Xml message for on-going process. This post explain step by step how to create Xml message and read the message from Xml elements.

First, copy and paste the following Xml message to new file "XmlMessage.xml" in "App_Data" folder in your project. You see "[xxxxxxx]" and it is place holder for data we put.
<?xml version="1.0" encoding="utf-8" ?>
<paymentService version="1.4" merchantCode="[merchantCode]">
  <reply>
    <orderStatus orderCode="[orderCode]">
      <payment>
        <paymentMethod>[paymentMethod]</paymentMethod>
        <amount value="[value]" currencyCode="[currencyCode]" exponent="[exponent]"/>
        <lastEvent>[lastEvent]</lastEvent>
        <CVCResultCode description="[CVCResultCode]"/>
        <ISO8583ReturnCode code="[ISO8583ReturnCode]" description="[ISO8583ReturnDescription]"/>
      </payment>
    </orderStatus>
  </reply>
</paymentService>
Second, we need to add Textbox server control to .aspx page as below:
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="txtXml" runat="server" Height="250px" Width="576px" 
            TextMode="MultiLine"></asp:TextBox>
    </div>
    </form>
</body>
Third, copy and paste the following code in code behind.
protected void Page_Load(object sender, EventArgs e)
{
    //Set the data here.
    string merchantCode = "MYMERCHANT";
    string orderCode = "T0211234";
    string paymentMethod = "ECMC-SSL";
    string value = "162095";
    string currencyCode = "GPB";
    string exponent = "2";
    string lastEvent = "REFUSED";
    string CVCResultCode = "NOT SUPPLIED BY SHOPPER";
    string ISO8583ReturnCode = "33";
    string ISO8583ReturnDescription = "CARD EXPIRED";

    string xmlMsg = GetXmlMessage();
    //Fill the data in place holder in Xml message.
    xmlMsg = xmlMsg.Replace("[merchantCode]", merchantCode);
    xmlMsg = xmlMsg.Replace("[orderCode]", orderCode);
    xmlMsg = xmlMsg.Replace("[paymentMethod]", paymentMethod);
    xmlMsg = xmlMsg.Replace("[value]", value);
    xmlMsg = xmlMsg.Replace("[currencyCode]", currencyCode);
    xmlMsg = xmlMsg.Replace("[exponent]", exponent);
    xmlMsg = xmlMsg.Replace("[lastEvent]", lastEvent);
    xmlMsg = xmlMsg.Replace("[CVCResultCode]", CVCResultCode);
    xmlMsg = xmlMsg.Replace("[ISO8583ReturnCode]", ISO8583ReturnCode);
    xmlMsg = xmlMsg.Replace("[ISO8583ReturnDescription]", ISO8583ReturnDescription);
    txtXml.Text = xmlMsg;
    ReadXmlMessage(xmlMsg);
}

public string GetXmlMessage()
{
    //Get Xml message from file.
    string XmlFile = "~/App_Data/XmlMessage.xml";
    StreamReader sr = new StreamReader(Server.MapPath(XmlFile));
    string str = sr.ReadToEnd();
    return str;
}

public void ReadXmlMessage(string xmlMsg)
{
    if (!string.IsNullOrEmpty(xmlMsg))
    {
        //Read the data from Xml elements.
        XmlDocument document = new XmlDocument();
        document.LoadXml(xmlMsg);
        string merchantCode = document.GetElementsByTagName("paymentService")[0].Attributes["merchantCode"].Value;
        string orderCode = document.GetElementsByTagName("orderStatus")[0].Attributes["orderCode"].Value;
        string paymentMethod = document.SelectSingleNode("//paymentMethod").InnerText;
        string value = document.GetElementsByTagName("amount")[0].Attributes["value"].Value;
        string currencyCode = document.GetElementsByTagName("amount")[0].Attributes["currencyCode"].Value;
        string exponent = document.GetElementsByTagName("amount")[0].Attributes["exponent"].Value;
        string lastEvent = document.SelectSingleNode("//lastEvent").InnerText;
        string CVCResultCode = document.GetElementsByTagName("CVCResultCode")[0].Attributes["description"].Value;
        string ISO8583ReturnCode = document.SelectSingleNode("//ISO8583ReturnCode").Attributes["code"].Value;
        string ISO8583ReturnDescription = document.SelectSingleNode("//ISO8583ReturnCode").Attributes["description"].Value;
    }
}
I use XmlNode.SelectSingleNode method to get xml data. It selects the first XmlNode that matches the XPath expression. The first XmlNode that matches the XPath query or null if no matching node is found.
I used aslo XmlDocument.GetElementsByTagName method to return an XmlNodeList containing a list of all descendant elements that match the specified Name. If no nodes match name, the returned collection will be empty.

Finally, run and see the result. It look like as below:

Sunday, May 5, 2013

How to use Pass-through authentication to Access Resources in different domain environment

Our web application often need to access local or network resources in production environment. For example, our application have to access file server for read/write access in different domain (not in a domain). In the above cases, we can use mirrored local accounts known as "Pass-through authentication". With this approach, you use two local accounts with the same user name and password on both servers (such as web server and file server). For network resources in the same domain, see previous post. Let's start here.

Step 1. Create a New User Account on Web Server

1. Click Start, select Administrative Tools and click Computer Management.
2. In Computer Management, click Local Users and Groups.
3. Double click the Users folder.
4. Right click in the users list and click New User.
5. Fill in the information for the new user (e.g. newacc) and click Create.


6. Make that account a member of the IIS_IUSRS group (In IIS 6, it is IIS_WPG group instead of IIS_IUSRS) as below:


Step 2. Create an Application Pool with a Custom Identity

1. Right click on Applicaton Pools node underneath the Machine node and Click Add Application Pool...
2. Type the name of new application pool (e.g. NewAppPool) on Add Application Pool dialog and press OK.


3. Select new application pool (NewAppPool) under Application Pools node and click Advanced Settings.


4. Advanced Settings dialog will appear and select the "Identity" list item and click the ellipsis (the button with the three dots).


5. Select Custom account option and press Set..


6. Type the new created account information (newacc) and press OK.


Step 3. Configure Your Application to Run in the New Application Pool

1. Go to IIS, click on your web application and click "Advanced Settings".
2. Click the ellipsis (the button with the three dots) on Application Pool item list.


3. Select the new application pool (NewAppPool) on Select Application Pool dialog and press OK.


Step 4. Create a New User Account on File Server

1. Create a local account with the same username and password as the one in Web Server (Step 1).

Step 5. Set permission of folder on File Server

1. Go to the given folder (e.g. FileShare) in File Server
2. Right click the folder and select "Properties"
3. Select the "Security" tab and click Edit


4. Click Add for new user account.


5. Type the created user account (newacc) and click Check Names and OK.


6. Set permission for that created local accout as below:


7. Click OK to finish.

By doing this, the file or directory you selected in file server will now allow the custom account  identity access from your web application in web farm.

Reference :
How To: Create a Service Account for an ASP.NET 2.0 Application
Understanding Built-In User and Group Accounts in IIS 7

Saturday, March 23, 2013

How to use Network Service Account to Access Resources in ASP.NET in the same domain

Our web application often need to access local or network resources in production environment. For example, our application have to access file server for read/write access in the same domain. In case, web application upload and save user account photo or document such as excel and word file. At that time, it need the Network Service Account that is least privileged, although it have network credentials which means that you can use it to authenticate against network servers.

By default, Microsoft Internet Information Services (IIS) 6.0 on Windows Server 2003 runs ASP.NET applications in application pools that use the NT AUTHORITY\Network Service account identity. This account is a least privileged machine account with limited permissions and an application that runs using this account has restricted access, network credentials, which means you can use it to access network resources and remote databases by using Windows authentication. The network resources must be in the same domain as your Web server or in a trusted domain. Normally, the Application Pool Identity in IIS7 is "ApplicationPoolIdentity" by default and in IIS5 or IIS6, is "NetworkService" by default. Let's start here, to use the NT AUTHORITY\Network Service machine account to access local and network resources in Web Farm.

1. Configuring IIS Application Pool Identities
First, we check what Application Pool our web application use as follow:


Go to IIS, click on your web application and click "Advanced Settings".


Now, you see your application use "DefaultAppPool" Application Pool. If you want to change it to another, click the ellipsis (the button with the three dots). The following dialog appears.


Select the Application Pool you want from the combo box and Press OK button. Now, we know already what Application pool we used. Then we change the Identity Type for Application Pool.
Go to IIS, select "Application Pool" node and then select Application Pool you want to change as shown below:


Click "Advanced Setttings" and you will see the following dialog box:


Now, Identity is "NetworkService" already. Otherwise, select the "Identity" list item and click the ellipsis (the button with the three dots). The following dialog appears.


Select the Identity Type "NetworkService" from the combo box and press OK button. So, we finished marking sure that our web application that run using "NetworkService" Application Pool Identity.

2. Securing Resources
Whenever a new Application Pool is created, the IIS management process creates a security identifier (SID) that represents the name of the Application Pool itself. For example, if you create an Application Pool with the name "MyNewAppPool," a security identifier with the name "MyNewAppPool" is created in the Windows Security system. From this point on, resources can be secured by using this identity. However, the identity is not a real user account; it will not show up as a user in the Windows User Management Console.
Let's start giving permission to folder in remote server here.

1. Open Windows Explorer
2. Select a file or directory.
3. Right click the file and select "Properties"
4. Select the "Security" tab
5. Click the "Edit" and then "Add" button



6. Click "Locatoins" and make sure you select your domain and then enter the Network Service account.


The Network Service account's credentials are of the form DomainName\AspNetServer$, where DomainName is the domain of the ASP.NET server and AspNetServer is your Web server name.For example, if your ASP.NET application runs on a server named SVR1 in the domain CONTOSO, the Network Service account is CONTOSO\SVR1$.

7. Click the "Check Names" button and click "OK".
8. Set permission for new account as below:


By doing this, the file or directory you selected in file server will now allow the Network Service identity access from your web application.

Reference :

How To: Use the Network Service Account to Access Resources in ASP.NET
Application Pool Identities