We have talked already what are the best ways to handle the object scope instance in stateless environments like the Web in previous blog posts. We will build up on this and demonstrate additional web techniques, starting with using the same persistent objects on different pages (state sharing).


Who needs that? Well let me explain a rather simplified scenario (but a valid one) – web-based wizard. Wizards usually have a workflow, which is produced by connecting web pages in a meaningful way. Every page is responsible for gathering data and providing navigation to the previous and next pages. This means that the gathered data and any persistent objects included should be preserved and transported (usually via the session state) between the wizards’ pages.


Here  are the details: When keeping a persistent object alive, it is very intuitive that one just keeps the object using some of the ASP .NET state mechanisms.
The internal state management of a persistent object is not completely serizalizable by design. This means that the State Manager, which is the connection between a persistent instance and the lower layers of Telerik OpenAcces ORM is not desterilized after obtaining it from View state or Session for example. To put it simple, if you retrieve the persistent object from a Session after doing an update, and then you try to store its changes into the database, the object scope doesn’t know that the object is already in the database and just needs to be updated. It treats it as a completely new one with an already existing Identity. And this really leads to headaches.


So, this is one of the areas, where the Object Container provided by Telerik OpenAccess ORM comes in very handy. The object container is keeping every peace of information for the persistent objects it contains and can easily be used for serialization/deserialization or transportation of such instances.

Let’s think of a very common customer registration scenario. It simply requires some login credentials in the first page, then some personal information in the second and credit card information in the third.
So this is the persistent class that emulates such a customer:

    [Telerik.OpenAccess.Persistent(IdentityField = "id")]
   
public class Customer
   
{
       
private int id;
       
private string ssn;
       
private string userName;
       
private string password;
       
private string firstName;
       
private string lastName;
       
private DateTime dateOfBirth;
       
private string phoneNumber;
       
private string bankAccountNumber;
       
private CardTypes cardType;

In the first of the three sample pages we ask the customer only for a username and a password:

page1

When the Next button is clicked, in the code-behind I create a new persistent object, assign the correct values to the username and password properties and then store this object in a new object container instance. Then we store the object container in the Session for further usage in the next page of the registration form.

        ObjectContainer container = new ObjectContainer();
       
container.Transaction.Begin();
       
Customer cust = new Customer();
       
cust.UserName = RadTextBoxUserName.Text;
       
cust.Password = RadTextBoxPass.Text;
       
container.Add(cust);
       
container.NamedList("Registration", true).Add(cust);
       
container.Transaction.Commit();
       
Session["container"] = container;
       
Response.Redirect("Page2.aspx");
 

In Page 2, we gather the next portion of information for the new customer:

page2

The retrieval of the object container from the Session and extracting the Customer object from the container like:

        ObjectContainer container = (ObjectContainer)Session["container"];
       
Customer cust = (Customer)container.NamedList("Registration")[0];
       
container.Transaction.Begin();
       
cust.FirstName = RadTextBoxFirstName.Text;
       
cust.LastName = RadTextBoxLastName.Text;
       
cust.DateOfBirth = dob;
       
cust.PhoneNumber = RadTextBoxPhone.Text;
       
container.Transaction.Commit();

       
Session["container"] = container;
       
Response.Redirect("Page3.aspx");

 

The last step is very important: The remaining properties of the Customer object are filled and then the object goes in the database in a single step.
That is accomplished by obtaining a new object scope and passing the changes from the container to it.

page3

        ObjectContainer container = (ObjectContainer)Session["container"];
       
Customer cust = (Customer)container.NamedList("Registration")[0];
       
container.Transaction.Begin();
       
cust.Ssn = RadTextBoxSSN.Text;
       
cust.BankAccountNumber = RadTextBoxIBAN.Text;
       
cust.CardType = (CardTypes)(int.Parse(RadComboBoxCard.SelectedValue));
       
container.Transaction.Commit();

       
IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
       
scope.Transaction.Begin();
       
container.CopyTo(scope, ObjectContainer.Verify.All);
       
scope.Transaction.Commit();
 
So, in the end the object container did a great job for us by carrying our objects and letting us do the registration procedure in a single database transaction. Download the full code from the Telerik OpenAccess ORM code-library.

Comments

Comments are disabled in preview mode.