Binding problem when Sending JSON object to MVC3

25. May 2012 16:59 by Mrojas in ASP.NET, Razor, Visual Studio  //  Tags: , , ,   //   Comments (0)

After a frustrating couple of hours trying to determine WHY WHY my object did not bind with MVC3 I finally found why.

The story began like this.

I have a very simple method in a controller. Something like this:

 

public class Form1Controller : Controller
    {
        //
        // GET: /Form1/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult DoButton1(Person zzz)
        { 
            System.Diagnostics.Debug.WriteLine(zzz.Name);
            return Json(data: "Good Test");
        }
   
       

    }
 
And I called that code with a jquery Statement like:
var person= JSON.stringify({ Name: "Mauricio", LastName: "Rojas" });              $.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: person,
                    success: function () {
                        alert("OK");
                    },
   
                });
 
But!!! (maybe you already saw the obvious mistake) no matter what I sent, the Person object was not bind.
The action method got called but I was not able to see the sent values. I used Chrome developer tools and the network that show the
values I had modified.
SO WHYYYYY!!!!
I tried to debug the MVC code, but VS studio could not load the pdb, something I get that I still not sure why.
So how could I intercept what was happening? Simple with a ModelBinder.
A ModelBinder is class that is used to bind your request to a model object.
So I went to the Global.asax file and register my binder, and set some breakpoints.
//Code in Global.asax to register a Person Binder
    protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ModelBinders.Binders.Add(typeof(Person), new PersonBinder());
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

    public class PersonBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return (null);

            string bodyText;

            using (var stream = controllerContext.HttpContext.Request.InputStream)
            {
                stream.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(stream))
                    bodyText = reader.ReadToEnd();
            }

            if (string.IsNullOrEmpty(bodyText)) return (null);

            var xx = new JavaScriptSerializer().Deserialize<Person>(bodyText);

            return xx;
        }
    }
 
And voila!! the content type I was getting was something like:application/x-www-form-urlencoded
 
So I just added the content type parameter to my javascript code:
$.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: viewModelStr,
                    success: function () {
                        alert("inside");
                    }//,
                    contentType: 'application/json; charset=utf-8' 
                });
 

Binding problem when Sending JSON object to MVC3

25. May 2012 16:59 by Mrojas in ASP.NET, HTML5, JSON, Razor, Visual Studio  //  Tags: , , ,   //   Comments (0)

After a frustrating couple of hours trying to determine WHY WHY my object did not bind with MVC3 I finally found why.

The story began like this.

I have a very simple method in a controller. Something like this:

 

public class Form1Controller : Controller
    {
        //
        // GET: /Form1/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult DoButton1(Person zzz)
        { 
            System.Diagnostics.Debug.WriteLine(zzz.Name);
            return Json(data: "Good Test");
        }
   
       

    }
 
And I called that code with a jquery Statement like:
var person= JSON.stringify({ Name: "Mauricio", LastName: "Rojas" });              $.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: person,
                    success: function () {
                        alert("OK");
                    },
   
                });
 
But!!! (maybe you already saw the obvious mistake) no matter what I sent, the Person object was not bind.
The action method got called but I was not able to see the sent values. I used Chrome developer tools and the network that show the
values I had modified.
SO WHYYYYY!!!!
I tried to debug the MVC code, but VS studio could not load the pdb, something I get that I still not sure why.
So how could I intercept what was happening? Simple with a ModelBinder.
A ModelBinder is class that is used to bind your request to a model object.
So I went to the Global.asax file and register my binder, and set some breakpoints.
//Code in Global.asax to register a Person Binder
    protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ModelBinders.Binders.Add(typeof(Person), new PersonBinder());
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

    public class PersonBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return (null);

            string bodyText;

            using (var stream = controllerContext.HttpContext.Request.InputStream)
            {
                stream.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(stream))
                    bodyText = reader.ReadToEnd();
            }

            if (string.IsNullOrEmpty(bodyText)) return (null);

            var xx = new JavaScriptSerializer().Deserialize<Person>(bodyText);

            return xx;
        }
    }
 
And voila!! the content type I was getting was something like:application/x-www-form-urlencoded
 
So I just added the content type parameter to my javascript code:
$.ajax({                                    
                    url: "/Form1/DoButton1/",
                    type: "POST",
                    dataType: "json",
                    data: viewModelStr,
                    success: function () {
                        alert("inside");
                    }//,
                    contentType: 'application/json; charset=utf-8' 
                });
 

Migration of Point of Sale (POS) Applications to Mobile/Tablet Devices

22. January 2012 23:54 by Mrojas in HTML5  //  Tags: , , , , , , , , , , , , ,   //   Comments (0)

A long time ago, I had the idea of writing a series of posts about the issues
related to the migration of Point Of Sale applications developed in VB6.
(http://blogs.artinsoft.net/Mrojas/archive/2007/05/07/Migration-of-VB6-POS.aspx)

 A lot of companies developed this kind of software in VB6, and they faced a lot of
of similar issues specially when dealing with POS devices.

 

It's nice that the industry has made the effort of developing standards as the UPOS or
Unified POS (http://en.wikipedia.org/wiki/UnifiedPOS) and Microsoft also did a great work
by providing the COM and .NET implementations.

 

It was nice to move VB6 applications to POS for .NET, but times have change and so
has the UPOS grown to interesting proposals like WS-POS.

 

"The fundamental benefit of WS-POS is the ability to provision POS peripherals as
services that can be accessed by remote POS applications, including mobile POS
solutions. Retailers can then use the power of Service-Oriented Architecture (SOA)
to allow access to their existing peripherals anywhere in the store through these
services. WS-POS holds potential benefits for all members of the retail ecosystem." from http://www.ibm.com/developerworks/webservices/library/ws-pos-retail/index.html 

 

So you can now think about leveraring your VB6 POS to Silverlight or HTML5 and
consume WS-POS services to provide for example tablet-based implementations.
Imagine your POS application running in Silverlight or WinFX on a Windows 8 Tablet
or in HTML5 in iPads or Androids. Does it sound appealing? Well that is exactly the
kind of experience that our migration solution brings to the table.

 

 

 

You can download a working implementation of WS-POS from the  Association for Retail
Technology Standards (ARTS) web site.
Go to http://www.nrf-arts.org/arts_download/schema-non-member
Download the UnifiedPOS 1.13 pdfs and reference implementation from the
WS-POS Addendum link (http://www.nrf-arts.org/download/file?f=http://www.nrf.com/Attachments.asp?id=30476&rid=227810) There are Java and WCF implementations. It is also very easy to modify the WCF
implementation so it can receive and respond JSON and work with your HTML5 implementations.

I always appreciate feedback, so if you have any more toughts or questions about HTML5 or Windows 8 POS implementations just let me know.