Microsoft Dynamics Nav: Using an XMLPort as a .NET DataSource

I previously discussed connecting to Microsoft Dynamics Nav using a Web Service and also discussed using an XMLPort to create an XML file. Building upon these concepts we can use a Microsoft Dynamics Nav XMLPort as a DataSource for a .NET application. I recommend reading the previous posts before continuing with this one.

Microsoft Dynamics Nav: Using an XMLPort as a .NET DataSource

This example slightly expands on the previous example and uses the Customer XMLPort as the datasource.

  1. Ensure that the MaxOccurance property is set for the Text element Open_Balance.
    XMLPort Designer
  2. Create a CodeUnit with a Function that uses the XMLPort as a parameter. Ensure that the parameter is marked as a Var parameter.
    CodeUnit Function
  3. Publish the CodeUnit as a Web Service from within Microsoft Dynamics Nav and restart the “Microsoft Dynamics Nav Web Services” service.
    Microsoft Dynamics Nav Web Service
  4. Create a new .NET Application and add the Web Reference for the CustomerExport CodeUnit published as a Web Service
  5. Place a DataGridView on the form
  6. Set the DataSource for the DataGridView to be the Microsoft Dynamics Nav XMLPort
    private void Form1_Load(object sender, EventArgs e)
            {
                CustomerExport_Binding ws = new CustomerExport_Binding();
                ws.UseDefaultCredentials = true;
                ws.Url = "http://localhost:7047/DynamicsNAV/WS/CRONUS%20USA,%20Inc./Codeunit/CustomerExport";
    
                Customers customers = new Customers();
                ws.ExportCustomer(ref customers);
                
                BindingSource bs = new BindingSource();
                dataGridView1.DataSource = bs;
    
                bs.DataSource = customers.Customer;
            }

A Microsoft Dynamics Nav XMLPort can easily also be the datasource for a DataGrid in an ASP.NET application.

The sample application referenced in this post can be downloaded >>>here<<<.



   

Microsft Dynamics Nav: Export XMLPort to File

A Microsft Dynamics Nav XMLPort is conceptually similar to a Dataport and can be used to create an XML format file to exchange information between systems. The follow example demonstrates exporting customer data to an XML file using Microsoft Dynamics Nav.

  1. Using the XMLPort Designer create an XMLPort that contains the data that you would like to Export
    Microsoft Dynamics Nav XMLPort
  2. If an Element is of type Text the value can be specified in code in the Export::OnBeforePassVariable trigger
    Microsoft Dynamics Nav XMLPort OnBeforePassVariable Trigger
  3. Create the code to export the data to an XML file
    1. Filter the RecordSet for the data desired
    2. Create a File
    3. Create an OutStream
    4. Set the view of the XMLPort to be the filtered RecordSet
    5. Export the XMLPort data (to the OutStream)
    6. Close the XMLFile
      Microsoft Dynamics Nav XMLPort Code

The sample application referenced in this post can be downloaded >>>here<<<.

 



   

Microsoft Dynamics Nav: .NET Interoperability

Microsoft Dynamics Interoperability with .NET

With Microsoft Dynamics Nav 2009 you can take advantage of .NET Framework interoperability and create code that allows Microsoft Dynamics NAV objects and .NET Framework objects to interact. This interoperability can be leveraged to execute Microsoft Dynamics Nav business logic from a .NET application. Here is an example of how to create a .NET Application that executes Nav code within a CodeUnit through the use of the “Microsoft Dynamics NAV Business Web Services”.

Before creating any code it is important that Microsoft Dynamics Nav is properly setup and configured to work with Web Services.

  1. Edit the CustomSettings.config in the Microsoft Dynamics Nav Service directory to work with your database and port.
    Microsoft Dynamics Interoperability with .NET
  2. Ensure that the “Microsoft Dynamics NAV Business Web Services” and Microsoft Dynamics Nav Server” are configured to use an account that has access to the database
    Microsoft Dynamics Interoperability with .NET
  3. In Microsoft Dynamics Nav create a CodeUnit with two functions that will be executed from the .NET Application
    Microsoft Dynamics Interoperability with .NET
  4. Publish the CodeUnit created in step 3 as Web Service and restart the “Microsoft Dynamics NAV Business Web Services” service. From the Classic Client fill out the appropriate data in the form.
    Microsoft Dynamics Interoperability with .NET
  5. Create a new .NET Application
  6. Add Microsoft Dynamics Nav as Web Service Reference to the project
    1. Right Click References
    2. Click Add Web Reference buttonClick Advanced buttonAdd Reference
    3. Enter the Web Service URL for your Microsoft Dynamics Nav installation
    4. Enter your Web Reference Name
    Microsoft Dynamics Interoperability with .NET
  7. Create an object to communicate with your service
    namespace BP.NavWebService
    {
        public class NavWebService
        {
            // when registering the web reference connect to the server with an address like
             //http://localhost:7047/DynamicsNAV/WS/CRONUS%20USA,%20Inc./services
    
            private Web1_Binding ws;
            public Web1_Binding Ws { get { return ws; } }
    
            public NavWebService(string url, bool usedefaultcredentials)
            {
                ws = new Web1_Binding();
                // Use default credentials for authenticating against Microsoft Dynamics NAV.
                ws.UseDefaultCredentials = usedefaultcredentials;
                ws.Url = url;
            }
        }
    }
  8. Interact with your service
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            NavWebService Nws;
    
            private void button1_Click(object sender, EventArgs e)
            {
                textBox2.Text = Nws.Ws.GetCustomerName(textBox1.Text);
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                Nws.Ws.SetCustomerName(textBox1.Text, textBox2.Text);
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string Url = "http://localhost:7047/DynamicsNAV/WS/CRONUS%20USA,%20Inc./Codeunit/Web1";
                Nws = new NavWebService(Url, true);
            }
        }

 

The sample application referenced in this post can be downloaded >>>here<<<.



   

C#: ASP.NET CAPTCHA

As easy as it is to develop a web form that accepts user input, it is just as easy to develop an automated application that can fill the web form with data. In an attempt defend against these applications; web authors often implement a challenge-response mechanism to verify that the web form has been completed by a “human”. This challenge-response mechanism is commonly referred to as CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart). The key to a CAPTCHA mechanism is to make it easy for humans and difficult for “computers” to solve. One popular method is to generate random text for a human to enter as part of the data entry process.

CAPTCHA

There are many commercial and free CAPTCHA plugins available for use, but you can easily create a CAPTCHA as part of your web application. To incorporate your own CAPTCHA mechanism into your web form:

- Add a method to generate the “random text”

public void SetCAPTCHAText()
    {
        // generate a random number
        Random ran = new Random();
        int no = ran.Next(11111, 99999);
        // store the random number in a session variable
        Session["Captcha"] = no.ToString();
    }

Add a method to validate the “random text” with user input

protected void CAPTCHAValidate(object source, ServerValidateEventArgs args)
    {

        if (Session["Captcha"] != null)
        {
            if (txtVerify.Text.ToUpper() != Session["Captcha"].ToString().ToUpper())
            {
                SetCAPTCHAText();
                args.IsValid = false;
                return;
            }
        }
        else
        {
            SetCAPTCHAText();
            args.IsValid = false;
            return;
        }

    }

- Add a new Generic Handler to your Web Site to draw the image containing the “random text”

Generic Handler
public void ProcessRequest(HttpContext context)
    {
        //factor for scaling
        int factor = 25;

        // set the size of the image
        int imagewidth = 150;
        int imageheight = 30;

        // setup the image
        Bitmap bmpOut = new Bitmap(imagewidth, imageheight);
        Graphics g = Graphics.FromImage(bmpOut);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        g.FillRectangle(Brushes.White, 0, 0, imagewidth, imageheight);

        // draw the verification code on the image
        Color c = new Color();
        c = Color.Black;
        Font f = new Font("Verdana", 14);
        SolidBrush b = new SolidBrush(c);
        if (!String.IsNullOrEmpty(System.Web.HttpContext.Current.Session["Captcha"].ToString()))
        {
            g.DrawString(System.Web.HttpContext.Current.Session["Captcha"].ToString(), f, b, 5, 5);
        }

        // draw some random data to image to distort OCR
        Random rnd = new Random();
        int m = imagewidth / factor;
        for (int i = 0; i <= Convert.ToInt32(Math.Truncate(bmpOut.Width * bmpOut.Height / (double)factor)) - 1; i++)
        {
            int x = rnd.Next(bmpOut.Width);
            int y = rnd.Next(bmpOut.Height);
            int w = rnd.Next(m);
            int h = rnd.Next(m);
            g.FillEllipse(Brushes.Gray, x, y, w, h);
            
            // you could get creative with other "noise"
            //Point[] points = { new Point(100, 25), new Point(90, 20), new Point(110, 15), new Point(85, 15) };
            //g.FillClosedCurve(Brushes.Red, points);
        }

        // write the image to the stream for display on the webpage
        MemoryStream ms = new MemoryStream();
        bmpOut.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        byte[] bmpBytes = ms.GetBuffer();
        bmpOut.Dispose();
        g.Dispose();
        ms.Close();
        context.Response.BinaryWrite(bmpBytes);
        context.Response.End();
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

- Add an image to the web form to display the CAPTCHA text – the image is drawn by the Handler
- Add a text box for the user input
- Validate the user input when the user submits the form

 
<div>
        <asp:Image ID="imCaptcha" ImageUrl="~/Captcha.ashx" runat="server" /><br />
        <asp:TextBox ID="txtVerify" runat="server"></asp:TextBox>
        <asp:CustomValidator ID="CustomValidator2" runat="server" ControlToValidate="txtVerify"
            ErrorMessage="Invalid verification code entered." OnServerValidate="CAPTCHAValidate"
            SetFocusOnError="True" ValidateEmptyText="True" 
            ToolTip="Invalid verification code entered.">*</asp:CustomValidator><br />
        <asp:Label ID="Label4" runat="server" Text="Enter the number displayed above."></asp:Label><br />
        <asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert"
            Text="Submit" />
        <asp:ValidationSummary ID="ValidationSummary1" runat="server" />
    </div>

 

The sample application referenced in this post can be downloaded >>>here<<<.



   

C#: Regular Expression URL and Format HTML

When developing an application it is often a requirement to identify and format a URL within text. One example would be in the formatting of user input that is saved and displayed on a web page. The following code uses a Regular Expression to identify links within text and replace the links with HTML creating a valid HyperLink when displayed in a browser.
 
public static string FormatEntry( string e )
        {
            string original = e;
            try
            {
                string pattern = @"((ht|f)tp(s?):\/\/([\w.]+\/?)\S*)";
                Regex rgx = new Regex ( pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled );
                e = rgx.Replace ( e, "<a href=\"$1\" target=\"_blank\">$1</a>" );
                return e;
            }
            catch
            {
                return original;
            }
        }
RegEx URL