European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET 4.5 Hosting - Amsterdam :: Create ASP.NET 4.5 File Security Process

clock March 20, 2013 07:24 by author Scott

Often when working with web applications it is necessary to secure access to documents or other user supplied resources.  If you look online you will find a number of different recommendations on how to accomplish this.  Some will recommend a HTTP Handler, some will recommend a simple ASPX, others will have other random ideas.  Regardless of the actual implementation there is always a common area of mixed recommendation, once you have validated that the user has the proper permissions to access the resource, how do you get the item to the user?  In this post I'll discuss a new API that is publicly available in .NET 4.5 that helps with one problem area.

The Problem

Determining if the user has access to the resource in question is rarely the area that causes trouble.  The problem comes with the process of serving the desired files to the user.  When you let IIS handle the serving of a file it automatically sets the Content Type on the HTTP Response to match the proper type for the file, however, if you are sitting in the middle of this process, you have to handle this yourself.

Recommendation to Solve Issue

If you look into this issue, try googleing "Determining File MIME Types" or similar.  You will find all kinds of recommendations.  They will range from creating a custom look up process based on file extension, to weird PInvoke calls into windows, or even from the really crafty individuals a reflection call to an internal member of previous versions of the .NET framework.

In the end, there has never really been a good, consistent way to handle this.  Often times if you are working with a limited subset of file types the switch statement solution will work, however, as new file types are added etc it becomes harder to manage.

New Solution

With .NET 4.5, there is a newly exposed class that can be used to solve this complicated process.  System.Web.MimeMapping is a class that has existed for a while prior to .NET 4.5 but was "internal" to the framework and could not easily be called without using reflection.  Now you can simply call a method with a file path and it will return the Content Type.

This makes it so that we can now use something as simple as the following to serve a secured document after validating that the user has permissions.

Response.Clear();
Response.ContentType =
  System.Web.MimeMapping.GetMimeMapping(Server.MapPath(document.ServerDocumentPath));
Response.AddHeader("Content-Disposition",
                    "attachment; filename=" + document.UploadedDocumentName);
Response.WriteFile(Server.MapPath(document.ServerDocumentPath));
Response.End();

As you can see here, it is just 5 lines of code. In the first line of code we clear anything that  might have already been written to the response.  In the second line we call out to MimeMapping's GetMimeMapping method providing it the filepath to our document.  The third line we are telling the browser that we want to force download the file and are specifying a custom file name.  Then in the last two lines we write the file to the response and end.

The nice thing with this approach as you can see in the above example we can have a different ServerDocumentPath than our actual document name.  This allows us to hide the files in a different manner and serve them up to users with a friendly name.

I hope this helps someone looking for a way to introduce a security process to file downloads.  This .NET framework MimeType mapping is very helpful for this type of situation.



European ASP.NET Hosting - Amsterdam :: Tips Submit Form with ASP.NET

clock March 11, 2013 06:11 by author Scott

In this article I try to explain the default submit behavior of form and panel. Suppose, you want to press/click submit button on Enter key press or you are trying to post the form on Enter key press. In asp.net, to achieve this functionality we need to set "Defaultbutton" property either in Form or in panel.

Form DefaultButton Property

     <form id="form1" runat="server" defaultbutton="btnSubmit">
    <div>
    <asp:TextBox ID="txtUserID" runat="server"/> <asp:TextBox ID="txtUserpwd" runat="server"/> <asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit _Click" Text="Submit"/>
    </div>
    </form>

Panel DefaultButton Property

     <asp:Panel ID="Panel1" runat="server" defaultbutton="btnSubmit">
    <div>
    <asp:TextBox ID="txtUserID" runat="server"/> <asp:TextBox ID="txtUserpwd" runat="server"/> <asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit _Click" Text="Submit"/>
    </div>
    </asp:Panel >

Note

1. We specify the defaultbutton property at the Form level in the form tag when there is only one Submit Button for post back.

2. We specify the defaultbutton property at the Panel level in the Panel tag when there are multiple Submit Button for post back.



European ASP.NET 4.5 Hosting - Amsterdam :: How to Enable Unobtrusive Validation Mode in ASP.NET 4.5

clock February 27, 2013 05:09 by author Scott

In this article we will learn how to enable Unobtrusive Validation in ASP.NET 4.5.

Visual Studio 2012 provides some new Validation features that include Unobtrusive Validation. When you work with this Validation mode you will find that there is not much difference in this validation and previous validations but to enable this type of validation you had to first configure your Web Application.

There are three ways to enable the Unobtrusive Validation in your Web Application; they are:

- By using Web.Config file
- By using Global.asax file
- By using Page_Load event on each page

The first method is by using the Web.Config file.

Step 1

Write the following code in your Web.Config file:

<configuration>
  <
appSettings>
    <
add key="ValidationSettings:UnobtrusiveValidationMode" value="None"></add>
  </
appSettings>
    <
system.web>
      <
compilation
 debug="true" targetFramework="4.5" />
      <
httpRuntime targetFramework="4.5" />
    </
system.web> 
</configuration>

Step 2

Now write the following code in your WebForm.aspx Page:

<asp:TextBox runat="server" ID="txt" />
     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ErrorMessage="txt is required"ControlToValidate="txt" runat="server" Text="Text is Required" Display="Dynamic" />

    <asp:Button ID="Button1" Text="Send info" runat="server" />

Step 3

Now debug your code, on debugging the code you will get the output like this:

When you click on the button in the output window you will see an Error Message. As you write in the Text Box and click again on the Button the error message will be disposed of automatically.

The second method is by using a Global.asax file.

Step 1

In the Global.asax file, first add the namespace "using System.Web.UI;".

After adding the namespace write the following code in the Application_Start method:

protected void Application_Start(object sender, EventArgs e)
{
    ValidationSettings.UnobtrusiveValidationMode =
 UnobtrusiveValidationMode.None;
}

Step 2

Now write the following code in your WebForm.aspx page:

<asp:TextBox runat="server" ID="txt" />
     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ErrorMessage="txt is required"ControlToValidate="txt" runat="server" Text="Text is Required" Display="Dynamic" />

    <asp:Button ID="Button1" Text="Send info" runat="server" />

Step 3

Again debugging your Web Application you will again get the same output as you got in the first method.

The third method is by simply writing the code on each page inside the Page_Load event.

Step 1

protected void Page_Load(object sender, EventArgs e)
{
    this.UnobtrusiveValidationMode = System.Web.UI.UnobtrusiveValidationMode.None;

}

Step 2

Now write the following code in your WebForm.aspx page:

<asp:TextBox runat="server" ID="txt" />
     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ErrorMessage="txt is required"ControlToValidate="txt" runat="server" Text="Text is Required" Display="Dynamic" />

    <asp:Button ID="Button1" Text="Send info" runat="server" />

Step 3

Again debug your Web Application and you will again get the same output as you got in the first method.

 



European ASP.NET Hosting - Amsterdam :: How to download a file from FTP Server using Csharp/VB.NET

clock February 19, 2013 08:26 by author Scott

This is brief tutorial how to download file from FTP using C#/VB.NET. Let’s start it:

C#

using System.Net;
using System.IO;

VB.NET

Imports System.Net
Imports System.IO

Following is the code of download file from the FTP Server.

C#

private void Download(string filePath, string fileName)
   {
       FTPSettings.IP = "DOMAIN NAME";
       FTPSettings.UserID = "USER ID";
       FTPSettings.Password = "PASSWORD";
       FtpWebRequest reqFTP = null;
       Stream ftpStream = null;
       try
       {
           FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
           reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + FTPSettings.IP + "/" + fileName));
           reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
           reqFTP.UseBinary = true;
           reqFTP.Credentials = new NetworkCredential(FTPSettings.UserID, FTPSettings.Password);
           FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
           ftpStream = response.GetResponseStream();
           long cl = response.ContentLength;
           int bufferSize = 2048;
           int readCount;
           byte[] buffer = new byte[bufferSize];

           readCount = ftpStream.Read(buffer, 0, bufferSize);
           while (readCount > 0)
           {
               outputStream.Write(buffer, 0, readCount);
               readCount = ftpStream.Read(buffer, 0, bufferSize);
           }

           ftpStream.Close();
           outputStream.Close();
           response.Close();
       }
       catch (Exception ex)
       {
           if (ftpStream != null)
           {
               ftpStream.Close();
               ftpStream.Dispose();
           }
           throw new Exception(ex.Message.ToString());
       }
   }
   public static class FTPSettings
   {
       public static string IP { get; set; }
       public static string UserID { get; set; }
       public static string Password { get; set; }
   }

VB.NET

   Private Sub Download(ByVal filePath As String, ByVal fileName As String)
       FTPSettings.IP = "DOMAIN NAME"
       FTPSettings.UserID = "USER ID"
       FTPSettings.Password = "PASSWORD"
       Dim reqFTP As FtpWebRequest = Nothing
       Dim ftpStream As Stream = Nothing
       Try
           Dim outputStream As New FileStream(filePath + "\" + fileName, FileMode.Create)
           reqFTP = DirectCast(FtpWebRequest.Create(New Uri("ftp://" + FTPSettings.IP + "/" + fileName)), FtpWebRequest)
           reqFTP.Method = WebRequestMethods.Ftp.DownloadFile
           reqFTP.UseBinary = True
           reqFTP.Credentials = New NetworkCredential(FTPSettings.UserID, FTPSettings.Password)
           Dim response As FtpWebResponse = DirectCast(reqFTP.GetResponse(), FtpWebResponse)
           ftpStream = response.GetResponseStream()
           Dim cl As Long = response.ContentLength
           Dim bufferSize As Integer = 2048
           Dim readCount As Integer
           Dim buffer As Byte() = New Byte(bufferSize - 1) {}

           readCount = ftpStream.Read(buffer, 0, bufferSize)
           While readCount > 0
               outputStream.Write(buffer, 0, readCount)
               readCount = ftpStream.Read(buffer, 0, bufferSize)
           End While

           ftpStream.Close()
           outputStream.Close()
           response.Close()
       Catch ex As Exception
           If ftpStream IsNot Nothing Then
               ftpStream.Close()
               ftpStream.Dispose()
           End If
           Throw New Exception(ex.Message.ToString())
       End Try
   End Sub
   Public NotInheritable Class FTPSettings
       Private Sub New()
       End Sub
       Public Shared Property IP() As String
           Get
               Return m_IP
           End Get
           Set(ByVal value As String)
               m_IP = Value
           End Set
       End Property
       Private Shared m_IP As String
       Public Shared Property UserID() As String
           Get
               Return m_UserID
           End Get
           Set(ByVal value As String)
               m_UserID = Value
           End Set
       End Property
       Private Shared m_UserID As String
       Public Shared Property Password() As String
           Get
               Return m_Password
           End Get
           Set(ByVal value As String)
               m_Password = Value
           End Set
       End Property
       Private Shared m_Password As String
   End Class

Hope you enjoy this simple tutorial. :)

 



European ASP.NET 4.5 Hosting - Amsterdam :: How to Disable Bundling and Minification in ASP.NET 4.5/MVC 4

clock February 12, 2013 05:51 by author Scott

Lots of people are excited about the new bundling and minification feature in the next version of ASP.NET and MVC. One major drawback I see a lot of people clamoring about is the fact that you cannot conditionally disable bundling or minification when you are in debug mode. Out of the box (and to be clear, I’m referring to the version that ships with MVC 4 beta) it’s impossible to debug your CSS and Javascript.

I expect this will change in the release version, but for now you are forced to create your own custom bundles (something you’d end up doing anyway) and conditionally check if you’re in debug mode to short-circuit the bundling/minification.

Disabling minification while in debug mode

It’s as simple as an #if DEBUG line and creating a transformer that does nothing. For example:

01           protected void Application_Start()
02           {
03               IBundleTransform jsTransformer;
04           #if DEBUG
05               jsTransformer = new NoTransform("text/javascript");
06           #else
07               jstransformer = new JsMinify();
08           #endif
09          
10               var bundle = new Bundle("~/Scripts/js", jsTransformer);
11          
12               bundle.AddFile("~/Scripts/script1.js");
13               bundle.AddFile("~/scripts/script2.js");
14          
15               BundleTable.Bundles.Add(bundle);
16           }

Now when you reference this javascript bundle like <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script> in a view it will render a single bundled and minified script when in release mode, but as a single bundled, non-minified file while in debug mode.

Disabling bundling while in debug mode

The above approach improves this situation, but I don’t think it goes far enough. If I’m going to have multiple source files, I want to debug with the same multiple source files, at least initially. It would get too confusing writing code in a several files and then debugging it in a single monolithic file.

As an experiment to see if it was possible, I ended up building a better bundler that does just what I want: bundles and minifies in release mode, but doesn’t bundle or minify when the build is set to debug.

The entire class is below, explanation to follow:

01           public static class BetterBundler
02           {
03               private static bool _debug;
04               const string CssTemplate = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
05          
06               public static void Init()
07               {
08           #if DEBUG
09                   _debug = true;
10           #endif
11                   var bundle = new Bundle("~/content/css", new CssMinify());
12          
13                   bundle.AddFile("~/Content/test.css");
14                   bundle.AddFile("~/Content/site.css");
15                   
16                   BundleTable.Bundles.Add(bundle);
17               }
18          
19               public static MvcHtmlString ResolveBundleUrl(string bundleUrl)
20               {
21                   return _debug ? BundledFiles(BundleTable.Bundles.ResolveBundleUrl(bundleUrl)) : UnbundledFiles(bundleUrl);
22               }
23               
24               private static MvcHtmlString BundledFiles(string bundleVirtualPath)
25               {
26                   return new MvcHtmlString(string.Format(CssTemplate, bundleVirtualPath));
27               }
28          
29               private static MvcHtmlString UnbundledFiles(string bundleUrl)
30               {
31                   var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);
32          
33                   StringBuilder sb = new StringBuilder();
34                   var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
35          
36                   foreach (var file in bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl)))
37                   {
38                       sb.AppendFormat(CssTemplate + Environment.NewLine, urlHelper.Content(ToVirtualPath(file.FullName)));
39                   }
40          
41                   return new MvcHtmlString(sb.ToString());
42               }
43          
44               private static string ToVirtualPath(string physicalPath)
45               {
46                   var relativePath = physicalPath.Replace(HttpContext.Current.Request.ServerVariables["APPL_PHYSICAL_PATH"], "");
47                   return relativePath.Replace("\\", "/").Insert(0, "~/");
48               }
49          
50               public static MvcHtmlString CssBundle(this HtmlHelper helper, string bundleUrl)
51               {
52                   return ResolveBundleUrl(bundleUrl);
53               }
54           }

To summarize, I’m using the same technique to determine debug mode, and of course this could be extended to conditionally bundle or not based on any boolean. The interesting code is in the UnbundledFiles(string bundleUrl) method.

Currently, there is no concept of named bundles – bundles are specified simply by the virtual path of the resultant bundle. This means all our calling code in the view has to give is the virtual path of the bundle. We have to start from that and uncover all the physical files deeper within the BundleTable.

var bundle = BundleTable.Bundles.GetBundleFor(bundleUrl);

This line retrieves the bundle that we created from the BundleTable.

bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundleUrl))

This gets all of the physical files from the bundle.

The rest is just boilerplate code to turn those raw physical files back into relative virtual paths and into the proper html tags.

Finally, you’ll note that I have an HtmlHelper method in there, CssBundle(this HtmlHelper helper, string bundleUrl). To render a bundle link in a view, this must be used. Since the result of a bundle could be one or multiple files, I decided the simplest approach would be to allow the BetterBundler to render the full html tag itself. This could easily be changed or enhanced.

1              In the view:
2             
3              @Html.CssBundle("~/content/css")

The Result

In release mode:

<link href="/content/css?v=7GiB-1k9Pr1JbbYY72bT3T2EOpxXf0rGPdEOXVKl5oQ1" rel="stylesheet" type="text/css" />

In debug mode:

<link href="/content/test.css" rel="stylesheet" type="text/css" />
<link href="/content/site.css" rel="stylesheet" type="text/css" />

 



European ASP.NET Hosting - Amsterdam :: How to Publish ASP.NET Web Application

clock February 6, 2013 07:04 by author Scott

In this article I will show you how to publish ASP.NET web application. I have found many people ask this question on asp.net forum. You can simply publish your web application to the File System and copy paste all the files to your server. Then from IIS, you can add a new website. You can set this by right clicking on the web application in the solution explorer and choosing 'Package/Publish Settings'.

Right click on your project in the solution explorer and choose 'Publish'. From the dialog box, as the publish method, choose 'File System'. And choose some directory as the Target Location.

Add the website by right clicking on the 'Sites' in IIS.

Then give a name to your site and select the Physical path from where you copied the site folder.

 



European ASP.NET Hosting - Amsterdam :: The Parallel.Invoke() Method C# / .NET

clock February 4, 2013 10:17 by author Scott

Many times in software development, we want to invoke several processes at one time and continue when we get all the results back.  Obviously, if we were needing to process a sequence of items in a similar matter, we could use PLINQ.  Unfortunately, when the things we want to invoke asynchronously are heterogeneous tasks, PLINQ doesn’t really fit the bill.  Today we will look at a handy method in the Parallel class that can help us accomplish this.

Invoking processes asynchronously

Let’s say we have three completely separate methods and we want to invoke all three of them and the continue when they have returned.  These methods may be from separate classes and have completely different parameters and/or return types.  Thus, it may not be possible to use facilities likeParallel.ForEach() or PLINQ.

So how would we do this?  Well, we could obviously create three threads, start them, and join on them to come back:

   1: var threads = new List<Thread>
   2:                   {
   3:                       new Thread(SomeMethod),
   4:                       new Thread(() => SomeOtherMethod(x, y)),
   5:                       new Thread(() => { result = YetAnotherMethod(x, y, z); })
   6:                   };
   7: threads.ForEach(t => t.Start());
   8: threads.ForEach(t => t.Join());

Which, as you can see, can be used to call any method that fits Thread’s constructor (or can be adapted to it using a lambda, etc.). 

But that’s a bit heavy.  In addition, if an unhandled exception is thrown in one of those methods it will kill the thread, but we don’t have a very clean way of catching it here at the point of invocation.

Of course, we also have the Task class from the TPL which can help simplify threads:

   1: var tasks = new []
   2:
                 {
   3:                     Task.Factory.StartNew(SomeMethod),
   4:                     Task.Factory.StartNew(() => SomeOtherMethod(x, y)),
   5:                     Task.Factory.StartNew(() => { result = YetAnotherMethod(x, y, z); })
   6:                 };
   7: Task.WaitAll(tasks);

This simplifies things on the surface, and better yet simplifies things a lot more with exception handling as well (TPL task exceptions get wrapped into a AggregateException and can be caught at the WaitAll() – and other possible places).

But there’s an even easier way…

Parallel.Invoke() – Easily invoke asynchronously

Just as the TPL gave us Parallel.For() and Parallel.ForEach() to make processing loops asynchronously a breeze, it also gave us Parallel.Invoke(), which takes any number of Action delegates and invokes them asynchronously and waits for them to rejoin.  If your methods have return values you want to store or need parameters, you can easily use lambda expressions as well:

   1: Parallel.Invoke(
   2:
     SomeMethod,
   3:     () => SomeOtherMethod(x, y)),
   4:     () => { result = YetAnotherMethod(x, y, z); })

As long as the method can convert to an Action or you can form a lambda that will allow it to do so, you can use the Parallel.Invoke() to easily call them all in parallel without having to worry about starting or joining the threads or tasks.  And, because this is part of the TPL, you get the nice AggregateException handling as well that lets you easily catch tasks thrown from the underlying tasks.

Summary

When you just need to fire off several methods in parallel, consider the Parallel.Invoke().  It is a very handy way to invoke several different methods easily without having to worry about all the details of creating tasks or threads.

 



Europe ASP.NET/MVC Hosting :: Creating ASP.NET WebApplication/ASP.NET MVC Application Membership Database on SQL Server Rather Than LocalDb

clock January 21, 2013 03:43 by author Scott

How can a DB be created in SQL Server rather than locally (LocalDb) which is the default?

When you create a new ASP.NET MVC Application (using regular template "Internet") or ASP.NET WebApplication, you will notice the following connection string in the Web.config file:

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcApplication1-20121005163323;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-
 MvcApplication1-20121005163323.mdf" providerName="System.Data.SqlClient" />


Actually this helps the MVC Application or ASP.NET WebApplication to generate a database locally (within the project's App_Data folder) at run-time for accounts and login management (membership). If however you want to generate this database in SQL Server then you can make some quick changes in the above Web.config file to do that, so here is what you need replace in the above db mapping.

<add name="DefaultConnection" connectionString="Data Source=ITORIAN-PC;Initial Catalog=ASPNETMembership;Integrated Security=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />

You probably have a different data source so change it before running. Now, run the application and click on the "Register" link to create an account and then you are all done.

Open the SQL Server Management Studio and look at the generated DB for this application.

 



European SQL 2012 Hosting - Amsterdam :: SQL Server 2012 Integration Services with HostForLIFE.eu

clock December 24, 2012 05:57 by author Scott

SQL Server 2012 Integration Services introduces an innovative approach to deploying SSIS projects, known as Project Deployment Model. This is the default and recommended deployment technique, due to a number of benefits it delivers (such as, the ability to centralize management of package properties across deployed projects, as well as monitor and log package execution performance and progress). However, even though the new model has become the recommended and default configuration for new packages created using SQL Server Data Tools, the traditional, package-based methodology remains available and supported. More importantly, in some scenarios, it might be considered a more viable option, since it allows for separation of SQL Server Database Engine and SQL Server Integration Services roles, yielding performance benefits and facilitating a distributed extraction, transformation, and loading (ETL) activities. Project Deployment Model, on the other hand, requires SSIS to be collocated on a SQL Server 2012 instance, due to its dependency on SSIS catalog. We will discuss its characteristics and walk through its implementation in this post.

Reporting Services 2008 for Internet deployment

The deployment method available from a SQL Server Data Tools-based project is directly dependent on the model employed during its creation (it is also possible to switch between two models after a project is created by applying a conversion process, which is invoked from the Project menu in SQL Server Data Tools). Effectively, in order to use the traditional package deployment mechanism, you will need to first ensure that your project is based on the package deployment model, which you can easily identify by checking its label in the Solution Explorer window.

In addition, you will also have to modify default project properties. To access them, right-click on the node representing the project in the Solution Explorer window and select the Properties entry from its context sensitive menu. In the resulting dialog box, switch to the Deployment section, where you will find three settings displayed in the grid on the right hand side:

AllowConfigurationChanges – a Boolean value (i.e. True, which is the default, or False) that determines whether it will be possible to choose package configurations during its deployment and assign values of properties or variables they reference.

CreateDeploymentUtility – a Boolean value (True or False, which is the default) that indicates whether initiating the project build will result in the creation of its Deployment Utility.

DeploymentOutputPath – a path that points to the file system folder where the Deployment Utility will be created. The path is relative to the location where project files reside (and set, by default, to bin\Deployment).

Set the value of the CreateDeploymentUtility property to True and modify AllowConfigurationChanges according to your requirements (e.g. set it to False if your project does not contain any package configurations or you want to prevent their modifications during deployment). Next, start the build process (using the Build item in the top level main menu of SQL Server Data Tools), which will populate the output folder (designated by DeploymentOutputPath parameter) with the .dtsx package file (or files, depending on the number of packages in your project), an XML-formatted Deployment Manifest file (whose name is constructed by concatenating the project name and .SSISDeploymentManifestsuffix) and, potentially, a number of other, project related files (representing, for example, custom components or package configurations).

The subsequent step in the deployment process involves copying the entire content of the Deployment Output folder to a target server and double-clicking on the Deployment Manifest file at its destination. This action will automatically launch the Package Installation Wizard. After its first, informational page, you will be prompted to choose between File system and SQL Server deployments.

The first of these options creates an XML-formatted file (with extension .dtsx) in an arbitrarily chosen folder. If the project contains configuration files (and the AllowConfigurationChanges project property was set to True when you generated the build), then you will be given an option to modify values of properties included in their content. At the end of this procedure, the corresponding .dtsConfigfiles will be added to the target folder.

The second option, labeled SQL Server deployment in the Package Installation Wizard relies on a SQL Server instance as the package store. Once you select it, you will be prompted for the name of the server hosting the SQL Server Database Engine, an appropriate authentication method, and a path where the package should be stored. If you want to organize your packages into a custom folder hierarchy, you will need to pre-create it by connecting to the Integration Services component using SQL Server Management Studio. In case your package contains additional files (such as package configurations), you will also be given an opportunity to designate their location (by default, the wizard points to Program Files\Microsoft SQL Server\110\DTS\Packagesfolder).

In either case, you can decide whether you want to validate packages following their installation (which will append the Packages Validation page to the Package Installation Wizard, allowing you to identify any issues encountered during deployment). In addition, when using SQL Server deployment, you have an option to set a package protection level (resulting in assignment of ServerStorage value to the ProtectionLevel package property). When deploying to file system, this capability is not available, forcing you to resort (depending on the deployment target) to either NTFS permissions or SQL Server database roles for securing access to your packages and sensitive information they might contain.

Just as in earlier versions of SQL Server, local SQL Service Integration Services 11.0 instance (implemented as the MSDTSServer110 service) offers the ability to manage packages stored in the MSDB database and file system, providing you with additional benefits (such as monitoring functionality), which we will discuss in more detail in our upcoming articles. In the case of MSDB storage, this is accomplished by following the SQL Server deployment process we just described and is reflected by entries appearing under the MSDB subfolder of the Stored Packages folder of Integration Services node when viewed in SQL Server 2012 Management Studio. In the same Storage Packages folder, you will also find the File System subfolder containing file system-based packages that have been identified by the SSIS service in the local file system. By default, the service automatically enumerates packages located in Program Files\Microsoft SQL Server\110\DTS\Packages directory, however, it is possible to alter this location by editing the Program Files\Microsoft SQL Server\110\DTS\Binn\MsDtsSrvr.ini.xml file and modifying the content of its StoragePath XML element. Incidentally, the same file controls other characteristics of MSDTSServer110 service, such as, package execution behavior in scenarios where the service fails or stops (by default, the execution is halted) or location of target SSIS instances (defined using the ServerName XMLelement).

While the Package Installation Wizard is straightforward to use, it is not well suited for deploying multiple packages. This shortcoming can be remedied by taking advantage of the DTUtil.exe command line utility, which in addition to its versatility (including support for package deployment and encryption), can also be conveniently incorporated into batch files. Its syntax takes the form DTUtil /option [value] [/option [value]] …, pairing option names with the values associated with them. For example, /SQL, /FILE, or /DTS options designating the package storage type (SSIS Package Store, File System, and MSDB database, respectively) can be combined with a value that specifies package location (as a relative or absolute path). By including COPY, MOVE, DELETE, or EXISTS options (with a value identifying package location) you can effectively copy, move, delete, or verify the existence of packages across all package stores.

In conclusion, the traditional package deployment methods available in earlier versions of SQL Server Integration Services are still supported and fully functional in the current release. However, in most scenarios, you should consider migrating your environment to the latest Project Deployment Model due to a wide range of advantages it delivers.



European ASP.NET 4.5 Hosting - Amsterdam :: Web Sockets and How to Develop HTML5 Web Sockets in ASP.NET 4.5

clock December 20, 2012 05:02 by author Scott

HTML5 WebSockets allow you to perform two-way (duplex) communication between the client browser and the server. ASP.NET 4.5 and IIS 8 provide support for WebSocket protocol so that you can program WebSockets in your ASP.NET web forms and ASP.NET MVC applications. This article discusses what WebSockets are and how to develop web applications that take advantage of HTML5 WebSockets.

Overview of HTML5 Web Sockets

Typically a communication over the web is comprised of two distinct parties participating in the communication, viz. the client and the web server. An ordinary web page uses a request-response model of communication wherein the browser sends a request to the server and the server then sends back a response. Each request and response uses a new connection and that connection is closed once the response is returned by the server. As you might have guessed, such a communication is poor in terms of performance since a new connection is established between the same client and the server every time. Additionally, such a communication can't be two way, i.e. client talking to server and server talking to the client simultaneously.

In the case of two-way or duplex communication both the parties participating in the communication can communicate at the same time. A common application of the duplex communication is chat systems such as MSN or Yahoo Messenger and Google Talk. In any chat system, two or more members can chat with each other at the same time. As far as HTML5 is concerned, the technique to achieve two way communications is Web Sockets.

Unlike the request-response model, WebSockets keep the underlying communication channel open throughout the course of communication. A WebSocket based communication typically involves three steps:

- Establishing a connection between the client and the server or Hand Shake.
- Asking the Web Socket server to listen to the incoming communication
- Sending and receiving data

Web applications use HTTP protocol for their functioning and HTTP protocol essentially makes use of the request-response model. The plain HTTP protocol isn't well suited for performing two-way communications. The WebSockets therefore, need to "upgrade" the plain HTTP protocol to WebSocket protocol. This "upgrade" takes place while establishing the connection between the client and the server. In order to upgrade the communication from plain HTTP to WebSocket, you need a web server that is capable of doing this upgrade.

Enabling WebSocket Protocol in Windows 8

As far IIS is concerned, IIS 8.0 that ships with Windows 8 is capable of accepting Web Socket communications. If you are developing a web application that makes use of HTML5 Web Sockets, you may need to install WebSocket support in IIS 8.0. The following figure shows the "Turn Windows features on or off" option from the control panel. It can be used to install WebSocket protocol.



Notice how the "WebSocket Protocol" feature is checked under "World Wide Web Services". If the IIS installation doesn't have WebSocket protocol enabled your ASP.NET applications won't be able to receive and respond to the WebSocket requests on the server.

A WebSocket based application consists of two parts, viz. WebSocket server side code and WebSocket client side code. The WebSocket server side code sits on the web server and "listens" to the incoming communication from clients. When some communication is received from the client it processes the communication and typically sends some communication back to the client. If there is no communication from the client the WebSocket server can either keep waiting for the communication or can terminate the communication channel. The WebSocket client side code makes use of the WebSocket object of HTML5 for the purpose of sending and receiving data to and from the WebSocket server side code.

The WebSocket client side code follows the same coding pattern regardless of your web server software. As far as ASP.NET is concerned, IIS 8 and certain .NET framework classes together allow you to develop WebSocket server side functionality. To understand how the client side and server side code goes hand in hand let's develop a simple application that performs a two-way communication. The web form that acts as a WebSocket client is shown below:



Using the above web form you can send a text message from the client to the server. The server then sends the same message back to the client (this is purely for the sake of simplicity and testing purposes. You can send any other data from the server. Clicking on the Stop button stops the server and no further communication can take place between the client and the server.

Coding the Client Side

Open the default web form and add the following jQuery code to a <script> block:

var socket;
$(document).ready(function () {
    socket = new WebSocket("ws://localhost:1046/WebSocketGenericHandler.ashx");
    socket.addEventListener("open", function (evt) {
      $("#divHistory").append('<h3>Connection Opened with the Echo server.</h3> ');},
    false);  
    socket.addEventListener("message", function (evt) {
      $("#divHistory").append('<h3^gt;' + evt.data + '</h3> ');   },
    false);  
    socket.addEventListener("error", function (evt) {
      $("#divHistory").append('<h3>Unexpected Error.</h3> ');},
    false);
    ...
});


The code shown above declares a global variable named socket to hold a reference to a WebSocket object. A WebSocket instance is then created by passing the URL of the WebSocketHandler.ashx. The WebSocketHandler.ashx contains the WebSocket server side code that "listens" to the client requests. You will develop WebSocketHandler.ashx later in this article. Notice how the URL uses ws:// protocol instead of http://. Next, event handlers for the three events, viz. open, message, and error, are wired using the addEventListener() method. The open event is raised when the readyState property (discussed next) changes to 1 (OPEN) and indicates that the connection is ready to send and receive data. The message event is raised when a message is received from the WebSocket server. The error event is raised when an error occurs during the communication with the Web Socket server.

Inside the message event handler the data sent by the server is retrieved using the evt.data property. The returned data is then appended to a <div> element. The other event handlers simply output the specified messages in the <div> element. The data from the client is sent to the server when the Send button is clicked. The click event handler of the Send button looks like this:

$("#btnSend").click(function () {
    if (socket.readyState == WebSocket.OPEN) {
        socket.send($("#txtMsg").val());
    }
    else {
        $("#divHistory").append('<h3>The underlying connection is closed.</h3> ');
  }
});


The click event handler of the Send button checks the readyState property of the WebSocket object. If the readyState is OPEN, it calls the send() method on the WebSocket instance. This read only property returns the current state of the connection. Possible values are 0 - CONNECTING, 1 - OPEN, 2 - CLOSING, 3 - CLOSED. The send() method sends data to the WebSocket server side code over an established connection. The text entered in the textbox is passed as a parameter to the send() method.

You can close the underlying connection by calling the close() method of the WebSocket object as follows:

$("#btnStop").click(function () {
  socket.close();
});

Coding the Server Side

The WebSocketHandler.ashx contains the server side code that listens and responds to the client requests. This code is shown below:

public class WebSocketHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            context.AcceptWebSocketRequest(DoTalking);
        }
    }
    ...
}


The above code shows an ASP.NET generic handler - WebSocketHandler - that triggers the WebSocket server. The ProcessRequest() method of the generic handler first checks whether the incoming request is a WebSocket request. This is done by checking the IsWebSocketRequest property of the HttpContext object. This property works hand-in-hand with the IIS 8.0 WebSocket module and returns true if an incoming request is a WebSocket request. A Web Socket request is different than an ordinary HTTP request in that instead of using http:// protocol it uses ws:// (Web Socket) protocol.

If the IsWebSocketRequest returns true, the AcceptWebSocketRequest() method of the HttpContext is called. This method takes one parameter - user function - that supplies a function that listens and responds to the client requests. In this case the user function contains the logic to listen to the incoming data and send it back to the client. The user function supplied to the AcceptWebSocketRequest() method should be an asynchronous function as shown below:

public async Task DoTalking(AspNetWebSocketContext context)
{
    WebSocket socket = context.WebSocket;
    while (true)
    {
        ArraySegment buffer = new ArraySegment(new byte[1024]);
        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
        if (socket.State == WebSocketState.Open)
        {
            string userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
            userMessage = "You sent: " + userMessage + " at " +  DateTime.Now.ToLongTimeString();
            buffer = new ArraySegment(Encoding.UTF8.GetBytes(userMessage));
            await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }
        else
        {
            break;
        }
    }
}


The DoTalking() method is marked as "async" indicating that the code inside it is going to run in asynchronous fashion. The DoTalking() method returns a Task object. The Task class acts as a wrapper to the asynchronous code. The DoTalking() method receives a parameter of type AspNetWebSocketContext. The AspNetWebSocketContext class gives you access to the WebSocket through its WebSocket property. The WebSocket class is the server side counterpart of the HTML5 WebSocket object. An endless while loop is then started so that the server can continuously listen to the incoming requests. To receive the incoming data, the ReceiveAsync() method of the WebSocket class is used. The ReceiveAsync() method is invoked along with the await operator. In this case the awaited task is to receive incoming data and store it in an ArraySegment, a byte array. The results of the receive operation are stored in WebSocketReceiveResult object. If the WebSocket is open as indicated by the State property, the received data is sent back to the client using the SendAsync() method. If the State property has any value other than Open, the while loop is exited thus terminating the server.

Summary

HTML5 WebSockets allow you to perform two-way (duplex) communication. To use HTML5 WebSockets in an ASP.NET application you need to enable the WebSocket protocol in IIS 8.0. You can then use IsWebSocketRequest property and AcceptWebSocketRequest() method to start the client-server communication. Using WebSockets, you can develop web applications such as Chat systems that require the ability to send and receive data simultaneously between the client and the server.

 



About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in