Web controls of the Graphics Mill for .NET provides very convenient and powerful feature - possibility to invoke server code directly from the JavaScript. It enables you to run this code without reloading of the page (this approach is also known as AJAX). Undoubtedly, it greatly reduces your efforts of creating interactive and user-friendly web interface.
Before we drill into the code example, let's examine the basics of the remote scripting mechanism of the Graphics Mill for .NET. It consists of two parts: server method and JavaScript code.
Now let's see a code example. For example, we want to put a vignette with adjustable width at the image. To do it, we add a server method AddVignette, mark it with the RemoteScriptingMethodAttribute attribute, and call it when the button Add Vignette is clicked. The vignette width is selected from the drop down list and sent to server.
<%@ Page language="VB" AutoEventWireup="true"%> <%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" Assembly="Aurigma.GraphicsMill.WebControls" %> <script runat="server" language="VB"> Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) If Not Page.IsPostBack Then BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg")) End If End Sub <Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod> _ Public Sub AddVignette(width As Integer) BitmapViewer1.Bitmap.Transforms.Buttonize(width, _ Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, _ Aurigma.GraphicsMill.Transforms.Direction.UpLeft, _ Aurigma.GraphicsMill.RgbColor.Black, _ Aurigma.GraphicsMill.RgbColor.Black) End Sub </script> <html> <head> <title>Remote Scripting</title> <script language="javascript"> function AddVignette_click(){ var selectBorderWidth = document.getElementById("SelectBorderWidth"); var width = selectBorderWidth.options[selectBorderWidth.selectedIndex].value * 1; var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>"); var params=new Array(); params.push(width) bitmapViewer1.invokeRemoteMethod("AddVignette", params); } </script> </head> <body> <form runat="server" ID="Form1"> Border width: <select id="SelectBorderWidth"> <option>30</option> <option selected>50</option> <option>80</option> </select> <input id="InputAddVignette" type="button" value="Add Vignette" onclick="AddVignette_click();"> <br> <br> <aur:BitmapViewer id="BitmapViewer1" runat="server" Width="400px" Height="300px"></aur:BitmapViewer> </form> </body> </html>
<%@ Page language="C#" AutoEventWireup="true" %> <%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" Assembly="Aurigma.GraphicsMill.WebControls" %> <script runat="server" language="C#"> private void Page_Load(object sender, System.EventArgs e) { if (!Page.IsPostBack) { BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg")); } } [Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod] public void AddVignette(int width) { BitmapViewer1.Bitmap.Transforms.Buttonize(width, Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, Aurigma.GraphicsMill.Transforms.Direction.UpLeft, Aurigma.GraphicsMill.RgbColor.Black, Aurigma.GraphicsMill.RgbColor.Black); } </script> <html> <head> <title>Remote Scripting</title> <script language="javascript"> function AddVignette_click(){ var selectBorderWidth = document.getElementById("SelectBorderWidth"); var width = selectBorderWidth.options[selectBorderWidth.selectedIndex].value * 1; var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>"); var params=new Array(); params.push(width) bitmapViewer1.invokeRemoteMethod("AddVignette", params); } </script> </head> <body> <form runat="server" ID="Form1"> Border width: <select id="SelectBorderWidth"> <option>30</option> <option selected>50</option> <option>80</option> </select> <input id="InputAddVignette" type="button" value="Add Vignette" onclick="AddVignette_click();"> <br> <br> <aur:BitmapViewer id="BitmapViewer1" runat="server" Width="400px" Height="300px"> </aur:BitmapViewer> </form> </body> </html>
Now let's examine a bit more complicated code example. It demonstrates how to handle exceptions occurred at the remote method. Also, this code demonstrates how to work with return values. This code builds a histogram of the image and sends the median value of this histogram to the client.
<%@ Page language="VB" AutoEventWireup="true"%> <%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" Assembly="Aurigma.GraphicsMill.WebControls" %> <script runat="server" language="VB"> Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) If Not Page.IsPostBack Then BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg")) End If End Sub <Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod> _ Public Function GetStatistics() As Single Return BitmapViewer1.Bitmap.Statistics.GetLuminosityHistogram().Median End Function </script> <html> <head> <title>Remote Scripting</title> <script language="javascript"> function GetStatistics_click(){ var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>"); bitmapViewer1.invokeRemoteMethod("GetStatistics", null); //Attach event handler on call completion bitmapViewer1.addStatusChanged(bitmapViewer1_addStatusChanged, this); } function bitmapViewer1_addStatusChanged(){ var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>"); //Detach event handler on call completion bitmapViewer1.removeStatusChanged(bitmapViewer1_addStatusChanged, this); //Check whether exception occured if (bitmapViewer1.getExceptionName() == ""){ alert("Median of image histogram is " + bitmapViewer1.getReturnValue() + "."); } else{ alert("Following exception occured during calling remote method:\n\r" + bitmapViewer1.getExceptionName() + "\n\r" + bitmapViewer1.getExceptionDescription()); } } </script> </head> <body> <form runat="server" ID="Form1"> <input id="InputGetStatistics" type="button" value="Get Statistics" onclick="GetStatistics_click();"> <br> <br> <aur:BitmapViewer id="BitmapViewer1" runat="server" Width="400px" Height="300px"></aur:BitmapViewer> </form> </body> </html>
<%@ Page language="C#" AutoEventWireup="true" %> <%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" Assembly="Aurigma.GraphicsMill.WebControls" %> <script runat="server" language="C#"> private void Page_Load(object sender, System.EventArgs e) { if (!Page.IsPostBack) { BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg")); } } [Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod] public float GetStatistics() { return BitmapViewer1.Bitmap.Statistics.GetLuminosityHistogram().Median; } </script> <html> <head> <title>Remote Scripting</title> <script language="javascript"> function GetStatistics_click(){ var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>"); bitmapViewer1.invokeRemoteMethod("GetStatistics", null); //Attach event handler on call completion bitmapViewer1.addStatusChanged(bitmapViewer1_addStatusChanged, this); } function bitmapViewer1_addStatusChanged(){ var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>"); //Detach event handler on call completion bitmapViewer1.removeStatusChanged(bitmapViewer1_addStatusChanged, this); //Check whether exception occured if (bitmapViewer1.getExceptionName() == ""){ alert("Median of image histogram is " + bitmapViewer1.getReturnValue() + "."); } else{ alert("Following exception occured during calling remote method:\n\r" + bitmapViewer1.getExceptionName() + "\n\r" + bitmapViewer1.getExceptionDescription()); } } </script> </head> <body> <form runat="server" ID="Form1"> <input id="InputGetStatistics" type="button" value="Get Statistics" onclick="GetStatistics_click();"> <br> <br> <aur:BitmapViewer id="BitmapViewer1" runat="server" Width="400px" Height="300px"> </aur:BitmapViewer> </form> </body> </html>
You see, Graphics Mill for .NET provides elegant and easy-to-use powerful remote scripting mechanism. You can use it to run almost any server code. However in the conclusion we would like to warn you to write server code carefully. We highly recommend you not to put a RemoteScriptingMethodAttribute attribute at the methods which are not actually necessary to be run. Also, if the performance of the method depends on the arguments, it is strongly recommended to check such argument to avoid malicious attacks. For example, if you create new bitmap in this method and pass it dimensions from the JavaScript, you must check them and do not run the method if the dimensions are too wild. You can find more guidelines for creating the reliable server code in the topic Scalability and Reliability of Web Applications.