Ehsan Ghanbari

Experience, DotNet, Solutions

Using FluentFTP in Asp.net applications

FluentFTP is a lightweight opensource library for FTP operations and I have used it several times in the applications I have worked on. You can refer to the documentation of the project on GitHub for more information. But I'm just gonna to share you the distilled helper I'm using for FluentFTP.

 

 

 public class FtpManager

    {

        private readonly string _ftpUrl;

        private readonly string _username;

        private readonly string _password;

 

        public FtpManager(string ftpUrl, string username, string password)

        {

            if (string.IsNullOrEmpty(ftpUrl))

            {

                throw new ArgumentNullException(nameof(ftpUrl));

            }

 

            if (string.IsNullOrEmpty(username))

            {

                throw new ArgumentNullException(nameof(username));

            }

 

            if (string.IsNullOrEmpty(password))

            {

                throw new ArgumentNullException(nameof(password));

            }

 

 

            if (!ftpUrl.StartsWith("ftp://"))

            {

                ftpUrl = $"ftp://{ftpUrl}";

            }

 

            _ftpUrl = ftpUrl;

            _username = username;

            _password = password;

        }

 

        public void UploadFile(AttachmentFileModel attachmentFileModel)

        {

            try

            {

                var client = new FtpClient(_ftpUrl);

 

 

                byte[] data;

                using (var inputStream = attachmentFileModel.HttpPostedFileBase.InputStream)

                {

                    var memoryStream = inputStream as MemoryStream;

                    if (memoryStream == null)

                    {

                        memoryStream = new MemoryStream();

                        inputStream.CopyTo(memoryStream);

                    }

 

                    data = memoryStream.ToArray();

                }

 

                client.Credentials = new NetworkCredential(_username, _password);

                client.Connect();

                var path = CreateDirectory(attachmentFileModel, client);

                client.Upload(data, path + attachmentFileModel.ContentName);

                client.Disconnect();

            }

            catch (Exception exception)

            {

                //Log

            }

        }

 

        public void UpdateFile(AttachmentFileModel attachmentFileModel)

        {

            try

            {

                var client = new FtpClient(_ftpUrl);

 

                byte[] data;

                using (var inputStream = attachmentFileModel.HttpPostedFileBase.InputStream)

                {

                    var memoryStream = inputStream as MemoryStream;

                    if (memoryStream == null)

                    {

                        memoryStream = new MemoryStream();

                        inputStream.CopyTo(memoryStream);

                    }

 

                    data = memoryStream.ToArray();

                }

 

                client.Credentials = new NetworkCredential(_username, _password);

                client.Connect();

                var path = CreateDirectory(attachmentFileModel, client);

                client.Upload(data, path + attachmentFileModel.ContentName);

                client.Disconnect();

            }

            catch (Exception exception)

            {

                //Log it

            }

        }

 

        public void DeleteFile(AttachmentFileModel attachmentFileModel)

        {

            try

            {

                var client = new FtpClient(_ftpUrl);

                client.Credentials = new NetworkCredential(_username, _password);

                client.Connect();

                var path = CreateDirectory(attachmentFileModel, client);

 

                if (client.FileExists(path + attachmentFileModel.ContentName))

                {

                    client.DeleteFile(path + attachmentFileModel.ContentName);

                }

 

                client.Disconnect();

            }

            catch (Exception exception)

            {

                //Log

            }

        }

 

        private static string CreateDirectory(AttachmentFileModel attachmentFileModel, FtpClient client)

        {

            string extension;

            if (attachmentFileModel.HttpPostedFileBase != null)

            {

                extension = Path.GetExtension(attachmentFileModel.HttpPostedFileBase.FileName);

            }

            else

            {

                extension = attachmentFileModel.FileName;

            }

 

            extension = extension.Replace(".", "");

            var path = string.Format("FolderName-" + extension + "/");

            if (!client.DirectoryExists(path))

                client.CreateDirectory(path);

            return path;

        }

    }

 

As I insinuated, this is a distilled helper and basic usage of CRUD on FTP, you can change it based on your needs as I have done many times. Cheers!



Cookie stealing in asp.net

You know that the cookie could be stolen by attackers. As nothing is secure until it's designed to be so, to make your cookie safe, firstly use HTTPS and make it required in your Web.config :

 

<httpCookies httpOnlyCookies="true" requireSSL="true" />

 

Personally, I don't store important data in the cookie and I just store a key in the cookie and by using that key I fetch the target data from a database but it doesn't work everywhere and it's not a solution for all the problems at all! Anyway, if you can't use Https, You can config the SSL by code for some sensitive cookies like below:

 

 protected void ForceCookieToBeHttpOnly(string cookieName, string cookieValue)

        {

            HttpCookie myHttpCookie = new HttpCookie(cookieName, cookieValue);

            Response.Cookies.Add(myHttpCookie);

            myHttpCookie.HttpOnly = true;

        }

 

But remember that, the only effective solution is Https.



Asp.net: Don't do that, do this!

This blog post is about what I learned from the presentation by @DamianEdwards on here. As it was so interesting so I decided to write a blog post about that. It seems that Most of the points are about using Asp.net web form techniques.

 

Standard compliance

Control Adapters: Try to Avoid control adapters in asp.net web form as they are originally designed to support mobile devices. instead, try to use standard HTML and CSS and mobile-specific design if you want to make it responsive. And also Try to Avoid using style properties in asp.net web form in code behind, instead try to use CSS style sheets as they are maintainable in CSS classes.

Page and control callbacks: try to avoid using page callback or any control with the callback in asp.net web form and try to use Ajax, Web API, SignalR, MVC actions instead.

Capability detection: Try to avoid BrowserCaps feature in asp.net and use client-side detection such as modernizer to determine the capability of the browser.

 

 

Security

Request validation: Try to use @foo (in MVC razor) and <%foo %>(in web form) and JavaScriptStringEncode and overall client checks to protect your site against XSS attacks.(although in my opinion It's better to have server-side check for more security but client-side checks are required to reduce the requests for server)

Cookies and Session authentication: Do not use cookies and session authentication because it's not safe for hijacking attacks. Instead, use require cookies and SSL cookies.

EnableViewStateMac: Do not make EnableViewStateMac as false because it will provide the Cross Site Scripting attack.

Medium trust: If you are running two application in a server, don’t use medium trust and place untrusted applications into their own application pools and run each application pool under its own unique identity.

<appSettings>: Do not make <appSettings> as disable

UrlPathEncode: Don't use it to encode arbitrary user-provided strings, Use UrlEncode to encode meant to appear as a query string parameter in a URL.

 

Reliability and performance

PreSendRequestHeaders and PreSendRequestContent: Don't use these methods within IHttpModule instances and use native IIS modules instead.

Asynchronous page events: Try to avoid async void methods for page lifecycle events. (for example Page_Load in web form) and try to use Page.RegisterAsyncTask() instead.

Fire-and-forget work: Don't use Timers and ThreadPool from asp.net and try to move them to a windows service(you can use WebBackgrounder to do that)

The request entity body: Try to not to use Request.Form and InputString before the HandlerExecute event. instead, you Can use Request.GetBufferlessinputStream() and GetBufferedInputStream()

Response.Redirect & end: By default Response.Redirect(string) calls Response.End(), which abort the current thread in the asynchronous request. but for asynchronous handlers, Response.End() does not abort the current thread. so try to avoid using Response.Redirect

EnableViewState & ViewStateMode: Try to avoid using EnableViewState, instead you can set ViewStateMode as "Disabled" and "Enabled" instead

SqlMembershipProvider: Use UniveralProviders instead of sqlMembershipProvider to work with all databases that entity framework supports. (it's available in NuGet package manager)

Long-Running request: Try to avoid asp.net session as asp.net release the session object lock. Instead, Try to use WebSocket or signalR for long-running requests if you can.

 

For more detail about the exact reason for the above quotes, you can see the presentation. 



Introducing book: Pro Asp.net 4.5 in C#

About two years ago, I read some chapters of Pro asp.net 3.5 (it was the second edition of the book). I remember that I didn't dig in some chapter like lifecycle and Context, Modules, Handlers, Caching, Managing paths, Configurations, …  but now as I really need to know what's exactly going on the behind of asp.net I've decided to read this book in detail. In my opinion it's necessary to every asp.net developer as it really convers more about asp.net and it's frameworks. 

This book is in my books queue and will start reading of this book soon. I think the most important part of the book is part2 as it discusses on basics of asp.net, core architecture of the framework. although readers could jump over this part as it's for guys who want to know the main scenario behind asp.net

 

Pro asp.net

 

This is the definition of Apress about the book:

Pro ASP.NET 4.5 in C# is the most complete reference to ASP.NET that you will find. This comprehensively revised fifth edition will teach you everything you need to know in order to create well-designed ASP.NET websites. Beginning with core concepts the book progresses steadily through key professional skills. You'll be shown how to query databases in detail, consider the myriad applications of XML, and step through all the considerations you need to be aware of when securing your site from intruders. Finally, you'll consider advanced topics such as using client-side validation, jQuery and Ajax.



In process session state mode in asp.net

You know a session is just a period of time for a specific user interaction in a web application. And the Session state is a feature in Microsoft asp.net for maintaining the same time for the user stored locally the Web server. InProc is the default session state mode and specified In-process mode to values and variables in memory on the local Web server. In comparison to other modes (state server and SQL server), InProc is faster as they both spend some time to serializing and desterilizing while reading and writing the data.

 

Usages and Disadvantages:

If your application is running on a single server and you are not dealing with lot's or online users, the best choice is InProc. Notice that in InProc mode, more session data are stored in memory and that can affect performance so you can't store more data in InProc mode because it stores your data in the memory. InProc is much much faster, has fewer requirements (serialization), but it's not a good idea to use it when the application is running on several web servers. It's obvious that data in InProc model will be lost if domain restart. When using InProc session state, the session will be stored locally on the server which served the request and therefore using the same Machine Key on both servers won't serve the purpose, so using it multiple servers is not recommended.



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns and I'm spending a lot of my time on architecture subject. Since 2008, I've been as a developer for companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the&nb Read More

Post Tags
Pending Blog Posts
Strategic design
Factory Pattern
time out pattern in ajax
Selectors in Jquery
Peridic pattern
How to use PagedList In asp.net MVC
How to query over Icollection<> of a type with linq
Domain driven design VS model driven architecture
What's the DDD-lite?
Redis as a cache server