in

simplusoft.net

another .NET open source community

iulia

Web applications – Architectural and development advices: Part I

Web applications – Architectural and development advices: Part I

  • Some times you want to force a post back from your web application because is the only way that helps you to implement some requests. You can do like:

              ScriptManager.RegisterStartupScript(this, this.GetType()

                 , System.Guid.NewGuid().ToString(), "parent.__doPostBack('x','y');", true);

 

            And check if retrieve this post back with:

           

 string eventTar = Request.Form["__EVENTTARGET"];

             string eventArg = Request.Form["__EVENTARGUMENT"];

 
  • Create a Library for all your session variables
    namespace MyApp.SessionKeys
    {
        public static class Info
        {
            public const string InfoBeforeUpdate = "InfoBeforeUpdate";
            public const string InfoAfterUpdate = "InfoAfterUpdate";
        }

    public static class MultiUpload
    {
        public const string NewInsertedDocIds = "NewInsertedDocIds";
        public const string IsJustDocsAdmin = "IsJustDocsAdmin";
    }
}

        And use like Session[MyApp.SessionKeys.Info.InfoBeforeUpdate]
  • If you want that your custom assembly to appear in Visual Studio at “Add reference”, just copy it at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders
  • Create a separate library for all data access operations DAL and try to use here typed data sets .xsd
  • If you want that your web applications to be Multilanguage don’t put inside html controls server controls, like putting a label inside a div because the Generate Local Resources facility from Visual Studio will note generate recourse for the label. Try to put all text messages into App_GlobalResources in order to be translated
  • If you implement localization after changing current culture it’s not enough to make only once, you have to set these in every page in PreInit. The best solution is to write a base page wich will be inherited by all the others like:
 

public class BasePageSessionExpire : System.Web.UI.Page

    {

        public BasePageSessionExpire()

        {

        }

      

        protected override void OnPreInit(EventArgs e)

        {

            base.OnPreInit(e);

            if (Session["CurrentCulture"] != null)

                     System.Threading.Thread.CurrentThread.CurrentCulture

                    = System.Threading.Thread.CurrentThread.CurrentUICulture

                    = (Session["CurrentCulture"] as CultureInfo);

        }

  

protected override void OnInit(EventArgs e)

        {

            base.OnInit(e);

            this.VerifySessionExpiration();

        }

      

        /// <summary>

        /// function used for session expiration

        /// </summary>

        public void VerifySessionExpiration()

        {

            if (Context.Session != null)

            {

                if (Session.IsNewSession)

                {

                    string szCookieHeader = Request.Headers["Cookie"];

                    if ((null != szCookieHeader)

                        &&

                        (szCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))

                    {

                        Response.Redirect("~/" +

                            ConfigurationManager.AppSettings["LoginPage"].ToString()

                            + "?qpRefSess="

                            + System.DateTime.Now.Millisecond.ToString());

                    }

                }

            }

        }

 

}

This class is used also to check if the session has expired case in which the user is redirected to the login page settled in the configuration file.

 

  •  How to handle datetime data manipulation into c#: define into configuration file all date time constants

<add key="DateTimeFormat" value="dd/MM/yyyy HH:mm"/>

                        <add key="DateTimeFormatFull" value="dd/MM/yyyy HH:mm:ss"/>

                        <add key="DateFormat" value="dd/MM/yyyy"/>

                        <add key="DateTimeFormatWithTime0" value="dd/MM/yyyy 00:00"/>

                        <add key="TimeFormat" value="hh:mm"/>

                       

Define a class for the DateTimeFormatInfo long and short format which will be used in all datetime operations:

public static class Utils

    {

        public static System.Globalization.DateTimeFormatInfo DateFormat

        {

            get

            {

                System.Globalization.DateTimeFormatInfo dtfi

                = new System.Globalization.DateTimeFormatInfo();

                dtfi.ShortDatePattern

                = System.Configuration.ConfigurationManager.AppSettings[Constants.DateFormat].ToString();

                dtfi.FullDateTimePattern

                = System.Configuration.ConfigurationManager.AppSettings[Constants.DateTimeFormat].ToString();

                dtfi.ShortTimePattern

                = System.Configuration.ConfigurationManager.AppSettings[Constants.TimeFormat].ToString();

                return dtfi;

            }

        }

        public static System.Globalization.DateTimeFormatInfo ShortDateFormat

        {

            get

            {

                System.Globalization.DateTimeFormatInfo dtfi

                = new System.Globalization.DateTimeFormatInfo();

                dtfi.ShortDatePattern = dtfi.LongDatePattern

                = System.Configuration.ConfigurationManager.AppSettings[Constants.DateFormat].ToString();

                dtfi.FullDateTimePattern

                = System.Configuration.ConfigurationManager.AppSettings[Constants.DateFormat].ToString();

                dtfi.LongTimePattern = dtfi.ShortTimePattern = "";

               

                return dtfi;

            }

        }

        public static DateTime? GetDateTimeFromString(string dtStr)

        {

            try

            {

                return new Nullable<DateTime>(DateTime.Parse(dtStr, DateFormat));

            }

            catch { return null; }

        }

        public class Constants

        {

            public static string DateTimeFormat = "DateTimeFormat";

            public static string TimeFormat = "TimeFormat";

            public static string DateFormat = "DateFormat";

            public static string DoubleFormat = "DoubleFormat";

            public static string NoActiveDetailsPopups = "NoActiveDetailsPopups";

        }

 

    }

And after that just use the class like :

this.txtAwardDate.Text = dr.AwardDate.ToString(Utils.DateFormat.ShortDatePattern);

  • Create a separate library where to store all the .xsd files for every xml data you have and you need to prelucrate into the code; just make it typed object by using xsd.exe tool
  • If you need to design hierarchycal data into database don't use disjoint sets, just use nested sets technique
  • If you have many places where you need to upload files, just create a class which can be reused in all places like:
  • public class PostedFile
        {       
            private string fileName;
            public string FileName
            {
                get { return fileName; }
            }
            private string contentType;
            public string ContentType
            {
                get { return contentType; }
            }
            public string StringBytes
            {
                get { return Convert.ToBase64String(data); }
            }
            private byte[] data;
            public byte[] DataBytes
            {
                get
                {
                    return this.data;
                }
            }
            int docId = 0;
            public int DocId
            {
                get { return docId; }
                set { docId = value; }
            }
            public PostedFile(string fileName, string contentType, byte[] bytes, int docId)
            {
                this.fileName = fileName;
                this.contentType = contentType;
                this.data = bytes;
                this.docId = docId;
            }
            public PostedFile(HttpPostedFile httpFile, int docId)
            {
                this.fileName = httpFile.FileName;
                byte[] data = new byte[httpFile.InputStream.Length];
                httpFile.InputStream.Read(data, 0, (int)httpFile.InputStream.Length);
                this.data = data;
                this.contentType = httpFile.ContentType;
                this.docId = docId;
            }
            public SunPostedFile()
            {
            }
        }
     
  • If you decide to use asp membership provider it's good to create for this a separate library (in case you want to override SqlMembershipProvider or another provider), because if your system it's big and will have many projects (web services, web application) it's almost sure that you will use the same techique and user table
  • If you have let's say a table Contacts and you need to search for contacts, some times you will think it's better to create a single user control which search contacts and wich will be used in all places. Well, the theory sounds good, but the practic it's different. In this case, my advice from experience is NOT to develope a single reusable user control, because you have to handle a lot of "if"'s (if it is page 1 hide some search criteria etc) and also you have to implement binding manually instead of using the Visual Studio great facilities to bind automatically. You will have for sure diffrents between all places where you search contacts, and you will just wait time to create a single reusable user control. Of course, you will say "once created you just reuse it"...well it's not exatelly like this, you will have a planty of errors to handle binding and events, and it's far much more easy and stable to just Visual Studio every time.The productivity in Visual Studio is really great and you just have to use all his facilities without reinvent the wheel if it is not the case.
  • Refuse to just develope if you don't understand exactelly what you have to do, and why not, if you don't have a specification. In all cases, if you just develope because your boss want that you to be quick and to work, you will finish by doing unnecessary work. There is in majory of company this hury to "just develope" because you have to work. It's really not good. In fact, you have to do what the client want. If don't ask the client and just do stupid work you will add inutil code to your application, and when come the time to change you will introduce bugs. The application must have only simple and clear code, and you have to find a logical explination for every line of code you wrote.
  • Avoid as much as possible "work arrounds (hard coded)" and thinks which are not standard and you use only for particular cases. If you dont use starndard and generic solutions you will have allways problems, even at a particular moment in time they work.
  • Try to be allways near valuable people. If in your team you don't have at least one member from which you have something to learn, just leave.
  • Be allways in time with the latest technology, even for the moment you don't need new tools.
  • Try to don't develope thinks in order to rename them later. Avoid this! You have to start with a clear application frame and naming.
  • If you need to store and manipulate images in your web application, the best solution is to store them in the database. For displaying them, just use an .ashx.
    • In order to have a link in the web site for downloading the document you must create a generic handler (.ashx file) and then point to this file like a link.Sample of creating .ashx:using System;
      using System.Data;
      using System.Web;
      using System.Collections;
      using System.Web.Services;
      using System.Web.Services.Protocols;
      namespace Sun.Web.ashx
      {
          /// <summary>
          /// Summary description for $codebehindclassname$
          /// </summary>
          [WebService(Namespace = "http://tempuri.org/")]
          [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
          public class ViewDocSample : IHttpHandler
          {
              public void ProcessRequest(HttpContext context)
              {
                  string documentId = context.Request.QueryString["docId"];
                  string contentType = String.Empty;
                  byte[] contentBytes = null;
                  string fileName = String.Empty;
                  //take data from the database
                  extraNewslettersDocuments.extra_NewslettersDocuments_GetDocInfoByIdRow docInfo
                             = extraNewslettersDocuments.GetDocInfoById(int.Parse(documentId));
                  if (docInfo != null)
                  {
                      fileName = docInfo.FileName;
                      contentType = docInfo.ContentType;
                      contentBytes = docInfo.FileContent;
                  }
                  context.Response.Clear();
                  context.Response.ContentType = contentType;
                  context.Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
                  context.Response.AddHeader("Content-Length", contentBytes.Length.ToString());
                  context.Response.BinaryWrite(contentBytes);
              }
              public bool IsReusable
              {
                  get
                  {
                      return false;
                  }
              }
          }
      }

      Sample of using the .ashx:
      this.imgPicture.ImageUrl
           = "~/ashx/ ViewDocSample.ashx?docId="+ hmId+"&qpRef="+DateTime.Now.Ticks.ToString();
       
  • If you develope web services, a security rule is to use custom soap headers.
public class LoginDetails : SoapHeader
{
    public string Username;
    public string Password;
}

 public class TestWS : System.Web.Services.WebService
    {
        /// <summary>
        /// Soap headers required for web service authentication
        /// </summary>
        public LoginDetails LoginDetails;
   [SoapHeader("LoginDetails", Direction = SoapHeaderDirection.In)]
        public extraDocuments.DocContentDataTable GetDocument(int documentId)
        {
            //check here this.LoginDetails.Username, this.DocumentsRole
        }
}

Comments

No Comments
Simplusoft.net is a non-profit community dedicated to all .NET developers
Powered by Community Server (Non-Commercial Edition), by Telligent Systems