Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

View, View Controller, Model Controller, Model (VVCMCM) Pattern

, 18 Mar 2012 CPOL
The MVC Pattern was first conceptualized assuming all the three actors were present at one place. Since Web Applications have both a client and a server this needs to be applied differently without technology bias.
VVCMCMSystem.zip
VVCMCMSystem
VVCMCM
VVCMCMSystem.suo
App_Data
bin
Model
ModelControllers
obj
Debug
Refactor
TempPE
VVCMCM.dll
VVCMCM.pdb
Properties
Scripts
JqGrid
i18n
JqueryUI
Themes
jqgrid
start
images
ui-bg_flat_55_999999_40x100.png
ui-bg_flat_75_aaaaaa_40x100.png
ui-bg_glass_45_0078ae_1x400.png
ui-bg_glass_55_f8da4e_1x400.png
ui-bg_glass_75_79c9ec_1x400.png
ui-bg_gloss-wave_45_e14f1c_500x100.png
ui-bg_gloss-wave_50_6eac2c_500x100.png
ui-bg_gloss-wave_75_2191c0_500x100.png
ui-bg_inset-hard_100_fcfdfd_1x100.png
ui-icons_0078ae_256x240.png
ui-icons_056b93_256x240.png
ui-icons_d8e7f3_256x240.png
ui-icons_e0fdff_256x240.png
ui-icons_f5e175_256x240.png
ui-icons_f7a50d_256x240.png
ui-icons_fcd113_256x240.png
ui-lightness
images
ui-bg_diagonals-thick_18_b81900_40x40.png
ui-bg_diagonals-thick_20_666666_40x40.png
ui-bg_flat_10_000000_40x100.png
ui-bg_glass_100_f6f6f6_1x400.png
ui-bg_glass_100_fdf5ce_1x400.png
ui-bg_glass_65_ffffff_1x400.png
ui-bg_gloss-wave_35_f6a828_500x100.png
ui-bg_highlight-soft_100_eeeeee_1x100.png
ui-bg_highlight-soft_75_ffe45c_1x100.png
ui-icons_222222_256x240.png
ui-icons_228ef1_256x240.png
ui-icons_ef8c08_256x240.png
ui-icons_ffd27a_256x240.png
ui-icons_ffffff_256x240.png
ViewControllers
ViewEvents
Views
VVCMCM.csproj.user
using System;
using System.Web;
using System.Threading;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;

using VVCMCM.ModelControllers;

namespace VVCMCM
{
    public class ModelAsynOperation : IAsyncResult
    {

        private bool _completed;
        private Object _state;
        private AsyncCallback _callback;
        private HttpContext _context;

        bool IAsyncResult.IsCompleted
        { 
            get 
            { 
                return _completed; 
            } 
        }



        public ModelAsynOperation(AsyncCallback callback, HttpContext context, Object state)
        {
            _callback = callback;
            _context = context;
            _state = state;
            _completed = false;
        }

        public void StartAsyncWork()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null); 
        }

        private void StartAsyncTask(Object workItemState)
        {
            try
            {

                String method = String.Empty;
                String modelController = String.Empty;
                String customModelControllerAssembly = String.Empty;
                String action = String.Empty;
                String contentType = String.Empty;
                String format = String.Empty;
                NameValueCollection parameters = null;
                Type modelControllerType = null;
                String content = String.Empty;
                Object modelControllerInstance = null;


                //Sample URL to test this handler replace with the virtual directory if required
                //http://localhost/VVCMCM/ModelController.rspx?method=get&controller=Entity&action=Search&format=xml&firstname=alfred&lastname=anton
                //query string expected
                //method=get&controller=Entity&action=Search&format=xml&firstname=alfred&lastname=anton

                //TODO try to get this from the http header
                method = _context.Request.QueryString["method"];

                //get the model controller for the request       
                modelController = _context.Request.QueryString["controller"];

                //check if there is a customization assembly to call
                customModelControllerAssembly = _context.Request.QueryString["controllerAssembly"];

                
                if (String.IsNullOrEmpty(modelController))
                {
                    //return a server error status code as there is no controller present
                    _context.Response.StatusCode = 500;
                }
                else
                {
                    //add the namespace for the controller
                    //modelController = String.Concat("VVCMCM.ModelControllers.", modelController);

                    action = _context.Request.QueryString["action"];

                    //this can come from query string or form post
                    format = _context.Request["format"];

                    //check if an action tag is present
                    if (String.IsNullOrEmpty(action))
                    {
                        action = "view";
                    }

                    //check if format tag is present
                    if (String.IsNullOrEmpty(format))
                    {
                        format = "plain";
                    }

                    contentType = GetContentType(format);

                    //check to see if this is a form post
                    if (method.Equals("post"))
                    {
                        parameters = _context.Request.Form;
                    }
                    //else get the parameters from the query string
                    else
                    {
                        parameters = _context.Request.QueryString;
                    }


                    //check if there is customization present
                    if (!String.IsNullOrEmpty(customModelControllerAssembly))
                    {
                        //load the assembly and then take the type
                        Assembly customization = AppDomain.CurrentDomain.Load(customModelControllerAssembly);
                        modelControllerType = customization.GetType(modelController);

                    }
                    else
                    {
                        //take it type from the current assembly
                        modelControllerType = Type.GetType(modelController);
                    }

                    //check if type is present
                    if (modelControllerType != null)
                    {
                        
                        modelControllerInstance = Activator.CreateInstance(modelControllerType);
                    }

                    if (modelControllerInstance != null)
                    {
                        _context.Response.ContentType = contentType;

                        content = modelControllerType.InvokeMember(action, BindingFlags.Default | BindingFlags.InvokeMethod, null, modelControllerInstance, new Object[]{parameters}) as String;

                        //TODO caching logic

                        _context.Response.Write(content);
                    }
                    else
                    {
                        throw new ArgumentNullException(modelController);
                    }
                    

                }
            }
            catch
            {
                //dont throw
                //remove the content and give an error status
                _context.Response.Clear();
                
                _context.Response.StatusCode = 500;
            }
            finally
            {
                _completed = true;
                _callback(this);
            }
        }




        #region IAsyncResult Members

        public object AsyncState
        {
            get
            { 
                return _state; 
            }
        }

        public WaitHandle AsyncWaitHandle
        {
            get 
            {
                return null;
            }
        }

        public bool CompletedSynchronously
        {
            get 
            {
                return false;
            }
        }

        //split the query string into name values pairs
        private Dictionary<String, String> GetParametersDetails(HttpContext context)
        {
            Dictionary<String, String> parameters = null;
            //its possible that the action query string would also be counter
            if (context.Request.QueryString.Count > 0)
            {
                parameters = new Dictionary<String, String>();
                foreach (String key in context.Request.QueryString.Keys)
                {
                    if (key != "action" && key != "controller")
                    {
                        parameters.Add(key, context.Request.QueryString[key]);
                    }
                }
            }

            if (parameters.Count == 0)
            {
                parameters = null;
            }

            return parameters;

        }


        //obtain the content type to be sent
        private String GetContentType(string format)
        {
            String contentType = String.Empty;

            switch (format)
            {
                
                case "xml":
                    contentType = "text/xml";
                    break;                
                case "json":
                case "plain":
                    contentType = "text/plain";
                    break;
                case "html":
                default:
                    contentType = "text/html";
                    break;
            }
            return contentType;
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Anton Pious Alfred
Architect Riversand Technologies Inc
India India
Head of Engineering at Riversand Technologies Inc.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 18 Mar 2012
Article Copyright 2012 by Anton Pious Alfred
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid