title: Nhibenate - DOS Attack
body: <p>One of the testers in my company found an error on my ASP.Net MVC 3 solution, that I believe is pretty common.</p>
  
  <p>One post to the server it can handle. But if you send a lot of posts, like a <strong>denial-of-service attack (DoS attack)</strong> it thrown an exception:</p>
  
  <pre><code>Server Error in '/' Application.
  Initializing[UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader#567]-failed to lazily initialize a collection of role: UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader.CustomerOrderLines, no session or session was closed
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
  
  Exception Details: NHibernate.LazyInitializationException: Initializing[UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader#567]-failed to lazily initialize a collection of role: UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader.CustomerOrderLines, no session or session was closed
  
  Source Error:
  
  Line 880:
  Line 881:
  Line 882:            return
  Line 883:                Json(
  Line 884:                    new
  
  
  Source File: C:\Projects\DavidPM\Hosts\ProdMaster.Hosts.Web\Areas\Sales\Controllers\CustomerOrderController.cs    Line: 882
  
  Stack Trace:
  
  [LazyInitializationException: Initializing[UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader#567]-failed to lazily initialize a collection of role: UseSoft.ProdMaster.Domain.Entities.CustomerOrderHeader.CustomerOrderLines, no session or session was closed]
     NHibernate.Collection.AbstractPersistentCollection.ThrowLazyInitializationException(String message) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:484
     NHibernate.Collection.AbstractPersistentCollection.ThrowLazyInitializationExceptionIfNotConnected() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:474
     NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:465
     NHibernate.Collection.AbstractPersistentCollection.Read() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:264
     NHibernate.Collection.Generic.PersistentGenericBag`1.System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Collection\Generic\PersistentGenericBag.cs:142
     System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +63
     System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217
     System.Linq.Enumerable.ToArray(IEnumerable`1 source) +78
     UseSoft.ProdMaster.Hosts.Web.Areas.Sales.Controllers.CustomerOrderController.SaveOrUpdateOrderLines(CustomerOrderModel customerOrderModel) in C:\Projects\DavidPM\Hosts\ProdMaster.Hosts.Web\Areas\Sales\Controllers\CustomerOrderController.cs:882
     lambda_method(Closure , ControllerBase , Object[] ) +162
     System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
     System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
     System.Web.Mvc.&lt;&gt;c__DisplayClass15.&lt;InvokeActionMethodWithFilters&gt;b__12() +55
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
     System.Web.Mvc.&lt;&gt;c__DisplayClass17.&lt;InvokeActionMethodWithFilters&gt;b__14() +19
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
     System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
     System.Web.Mvc.Controller.ExecuteCore() +116
     System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
     System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
     System.Web.Mvc.&lt;&gt;c__DisplayClassb.&lt;BeginProcessRequest&gt;b__5() +37
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass1.&lt;MakeVoidDelegate&gt;b__0() +21
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass8`1.&lt;BeginSynchronous&gt;b__7(IAsyncResult _) +12
     System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
     System.Web.Mvc.&lt;&gt;c__DisplayClasse.&lt;EndProcessRequest&gt;b__d() +50
     System.Web.Mvc.SecurityUtil.&lt;GetCallInAppTrustThunk&gt;b__0(Action f) +7
     System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
     System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
     System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
     System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
     System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +184
  </code></pre>
  
  <p>The is described bellow:</p>
  
  <p>Click in a button many times. Or click once and press enter, it will send a lot of requests to the server "Post".</p>
  
  <p>The Model Basically is:</p>
  
  <pre><code>public class CustomerOrderModel
  {
      public CustomerOrderModel()
      {
          this.CustomerOrderLines = new List&lt;CustomerOrderLineModel&gt;();
          this.CustomerOrderHeader = new CustomerOrderHeaderModel();
      }
  
      public CustomerOrderHeaderModel CustomerOrderHeader
      { get; set; }
  
      public List&lt;CustomerOrderLineModel&gt; CustomerOrderLines
      { get; set; }
  
  }
  </code></pre>
  
  <p>The Controller:</p>
  
  <pre><code>[HttpPost]
          public JsonResult SaveOrUpdateOrderLines(  CustomerOrderModel customerOrderModel)
          {
  
    if (customerOrderModel.CustomerOrderHeader.OrderNumber == 0)
               {
                   customerOrderModel.CustomerOrderHeader.OrderNumber = this.CustomerOrderService.CreateOrUpdate(customerOrderHeader, false);
               }
  </code></pre>
  
  <p>return
                  Json(
                      new
                      {
                          OrderNumber = customerOrderModel.CustomerOrderHeader.OrderNumber,
                          CustomerOrderLines = new
                              {
                                  CustomerOrderLine = (
                                      from ordeline in custOrderHeader.CustomerOrderLines
                                      select new
                                      {
                                          Id = ordeline.Id,
                                          LineNumber = ordeline.LineNumber,
                                          LineStatus = ordeline.LineStatus
                                      }</p>
  
  <pre><code>                            ).ToArray()
  
                          }
                  }, 
                  JsonRequestBehavior.AllowGet
              );
  
  }
  </code></pre>
  
  <p>The CustomerOrder Service:</p>
  
  <pre><code> public class CustomerOrderService : ServiceBase, ICustomerOrderService
      {
  
   public long CreateOrUpdate(CustomerOrderHeader customerOrderHeader, bool updateCustomerOrderHeader)
          {
              using (var session = this.SessionManager.OpenSession())
              {
                  var transaction = session.BeginTransaction();
  
                  try
                  {
                      //TODO: CHECKS IF PARTNER EXISTS
                      bool existsPartner = false;
                      long number = 0;
                      if (this.PartnerService.FindByName(customerOrderHeader.Partner.Name) != null)
                      {
                          existsPartner = true;
                      }
  
                      //CREATE PARTNER AND PARTNER ADDRESSES
                      if (!existsPartner)
                      {
                          this.PartnerService.Create(customerOrderHeader.Partner as Partner);
                      }
  
  
  
                      if (!updateCustomerOrderHeader)
                      {
                          number = this.CustomerOrderHeaderService.Create(customerOrderHeader, true);
                      }
                      else
                      {
                          this.CustomerOrderHeaderService.Create(customerOrderHeader, false);
                      }
                      transaction.Commit();
                      return number;
  
  
                  }
  
                  catch (Exception ex)
                  {
  
                      transaction.Rollback();
                      throw ex;
                  }
                  finally
                  {
                      session.Close();
                  }
              }
          }
  
  
  
          /// &lt;summary&gt;
          /// Initializes a new instance of the &lt;see cref="CustomerOrderService"/&gt; class.
          /// &lt;/summary&gt;
          /// &lt;param name="sessionManager"&gt;
          /// The session manager.
          /// &lt;/param&gt;
          public CustomerOrderService(ISessionManager sessionManager)
          {
              this.SessionManager = sessionManager;
          }
  }
  </code></pre>
  
  <p>The CustomerOrderHeaderService:</p>
  
  <pre><code>public long Create(CustomerOrderHeader customerOrderHeader, bool firstTime)
          {
  
  
              using (var session = this.SessionManager.OpenSession())
              {
              //    var transaction = session.BeginTransaction();
  
              //    try
              //    {
  
  
  
  
                      if (firstTime)
                      {
                          foreach (var customerOrderLine in customerOrderHeader.CustomerOrderLines)
                          {
                              customerOrderLine.CustomerOrderHeader = customerOrderHeader;
                          }
  
                          customerOrderHeader.OrderNumber = this.NextOrderNumber();
                          session.Save(customerOrderHeader);
                      }
                      else
                      {
  
                          CustomerOrderHeader customerOrderHeaderToBeChanged =
                              this.FindByOrderNumber(customerOrderHeader.OrderNumber);
  
                          customerOrderHeaderToBeChanged.CopyDomainProperties(
                              customerOrderHeader, new[]
                                                       {
                                                           "Id", 
                                                           "Partner", 
                                                           "DataOwner", 
                                                           "dataOwner", 
                                                           "SysCreatedOn",
                                                           "SysCreatedBy",
                                                           "CustomerOrderLines"
                                                       });
                          customerOrderHeaderToBeChanged = UpdateLines(customerOrderHeader, customerOrderHeaderToBeChanged);
                          List&lt;ICustomerOrderLine&gt; linestoBeInserted = GetTheLineNumbersToBeInserted(customerOrderHeader);
  
                          foreach (var customerOrderLine in linestoBeInserted)
                          {
                              customerOrderHeaderToBeChanged.CustomerOrderLines.Add(customerOrderLine);
                              customerOrderLine.CustomerOrderHeader = customerOrderHeaderToBeChanged;
                          }
  
                          session.Update(customerOrderHeaderToBeChanged);
                      }
  
              //        transaction.Commit();
              }
              //    catch (Exception ex)
              //    {
              //        transaction.Rollback();
              //        throw ex;
              //    }
              //    finally
              //    {
              //        session.Close();
              //    }
              //}
              //throw new System.ArgumentException();
  
              return customerOrderHeader.OrderNumber;
          }
  
  
  public class CustomerOrderHeaderService : ServiceBase, ICustomerOrderHeaderService
      {
          #region Constructors and Destructors
  
          /// &lt;summary&gt;
          /// Initializes a new instance of the &lt;see cref="CustomerOrderHeaderService"/&gt; class.
          /// &lt;/summary&gt;
          /// &lt;param name="sessionManager"&gt;
          /// The session manager.
          /// &lt;/param&gt;
          public CustomerOrderHeaderService(ISessionManager sessionManager)
          {
              this.SessionManager = sessionManager;
          }
  
          #endregion
  
   public long Create(CustomerOrderHeader customerOrderHeader, bool firstTime)
          {
  
  
              using (var session = this.SessionManager.OpenSession())
              {
              //    var transaction = session.BeginTransaction();
  
              //    try
              //    {
  
  
  
  
                      if (firstTime)
                      {
                          foreach (var customerOrderLine in customerOrderHeader.CustomerOrderLines)
                          {
                              customerOrderLine.CustomerOrderHeader = customerOrderHeader;
                          }
  
                          customerOrderHeader.OrderNumber = this.NextOrderNumber();
                          session.Save(customerOrderHeader);
                      }
                      else
                      {
  
                          CustomerOrderHeader customerOrderHeaderToBeChanged =
                              this.FindByOrderNumber(customerOrderHeader.OrderNumber);
  
                          customerOrderHeaderToBeChanged.CopyDomainProperties(
                              customerOrderHeader, new[]
                                                       {
                                                           "Id", 
                                                           "Partner", 
                                                           "DataOwner", 
                                                           "dataOwner", 
                                                           "SysCreatedOn",
                                                           "SysCreatedBy",
                                                           "CustomerOrderLines"
                                                       });
                          customerOrderHeaderToBeChanged = UpdateLines(customerOrderHeader, customerOrderHeaderToBeChanged);
                          List&lt;ICustomerOrderLine&gt; linestoBeInserted = GetTheLineNumbersToBeInserted(customerOrderHeader);
  
                          foreach (var customerOrderLine in linestoBeInserted)
                          {
                              customerOrderHeaderToBeChanged.CustomerOrderLines.Add(customerOrderLine);
                              customerOrderLine.CustomerOrderHeader = customerOrderHeaderToBeChanged;
                          }
  
                          session.Update(customerOrderHeaderToBeChanged);
                      }
  
              //        transaction.Commit();
              }
              //    catch (Exception ex)
              //    {
              //        transaction.Rollback();
              //        throw ex;
              //    }
              //    finally
              //    {
              //        session.Close();
              //    }
              //}
              //throw new System.ArgumentException();
  
              return customerOrderHeader.OrderNumber;
          }
  }
  </code></pre>