Nov 21, 2012

Detecting multiple postbacks using Ajax Update panel

There is  Ajax update panel.
You have a textbox with Autopostback server side logic inside panel.
There is also submit or Save button that of course creates Postback.

The problem may and may not show up its ugly face depending on server response time.

So good practice is to put some sleeping in your server side:

Threading.Thread.Sleep(1000);

Make some changes in your textbox and WITHOUT leaving field select Save button.
At this moment:
- Autopostback of textbox fires and reaches first server side
- standard postbak generated by Save is IGNORED since there is still active postback from textbox

Bad news is that no errors is raised and your logic for saving data behind Save button is completely ignored.
So user leaves form been sure that content is saved.

Here is a patch not a solution since is quite ugly but at least makes sure that everyone what happened.

Replace your server side button with standard html input and fill onclick event:

<input type="button"  value="Save" onclick="return Save('btnSave')" />          

Important! Place this button OUT of Ajax update panel tag :


     </ContentTemplate>    
</asp:UpdatePanel>
...
<input type="button"  value="Save" onclick="return Save('btnSave')" />          

Now write some javascript on page:


function Save(updatePanelId) {  
    if (!WaitForAnsycPostback()) { return; };

    var requestManager = Sys.WebForms.PageRequestManager.getInstance();

    __doPostBack(updatePanelId, "save");
};

function WaitForAnsycPostback() {
    var requestManager = Sys.WebForms.PageRequestManager.getInstance();

    if (requestManager.get_isInAsyncPostBack()) {
        alert('Please save again');
        return false;
    }

    return true;
};

Idea is  to ask Ajax PageRequestManager "Hey is something already going on?".
If he confirms we should inform user.
Yea I know its ugly but its a patch not a solution.
Ideally we should create some sort of queue and wait but this is safer.

And of course once you manually do postback like we did:

    __doPostBack(updatePanelId, "save");

; you must handle it differently in your PageLoad:

        If Not Me.Page.Request.Params Is Nothing AndAlso Me.Page.Request.Params.Count > 0 AndAlso _
            Not Me.Page.Request.Params("__EVENTARGUMENT") Is Nothing AndAlso _
            Not Me.Page.Request.Params("__EVENTTARGET") Is Nothing AndAlso _
            Me.Page.Request.Params("__EVENTARGUMENT").ToString().ToLower() = "save" _
            AndAlso Me.Page.Request.Params("__EVENTTARGET").ToString() = "btnSave" Then
            btnSave_Click(Nothing, Nothing)
            Return
        End If

And have in mind important issue that your Save button control ID is unique.
By default when using server side button ASP.NET takes care about this generating those ugly ctl00__  names.
Now you should take care of it.


Read more here:

















Headaches with trailing zeros in double value

I have a textbox on ASP.NET webforms page.
It should allow for double values fixed to 5 decimal places.
Initially I've used Infragistics Web numeric edit control.
You set it's minDecimalPlaces and DataType to "double" and everything is fine.
There is a catch.
If you enter :
1,2 it becomes  1,20000
; which is quite ugly.

So client came along and said fix it. I hate those trailing zeros, loose them.
Unfortunately after hours I could'nt find way to apply formatting without trailing zeroes so it all defaulted to use of regular textbox with server side formatting.

No, it does not filter chars and you can enter any chars.

The tricky part was this part executed in Autopostback:

If Double.TryParse(rowValue, controlValue) Then control.Text = String.Format("{0:G}", Math.Round(controlValue, NUMDECIMALPLACES))

After rounding to desired number of decimals "G" formatting must be used to suppress scientific notation 1E-5 etc.
Any other like F5 etc. generate again trailing zeros.

Here are some links on subject:


http://msdn.microsoft.com/en-us/library/26etazsy.aspx
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
http://blogs.msdn.com/b/kathykam/archive/2006/03/29/net-format-string-101-c_2300_-strings.aspx
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

Oct 30, 2012

Xml Serializer - Deserialization - basics


Collection of bussines objects in XML should be deserialized in collection of DTO objects using .NET XmlSerializer.
Although it is normal in such scenario to have XSD schema that explains XML will assume that you can't obtain one but have to manually write DTO's that reflect data in XML.

Here is collection of bus.objects in plain XML:

<Products>
<Product>
<Id>1</Id>
<Name>Tommato</Name>
</Product>
<Product>
<Id>2</Id>
<Name>Apple</Name>
</Product>
</Products>

Firstly we have to tweak above since it is not acceptable for XmlSerializer.
When working with collections we must envelope collection node with an extra node serving as container like this:
<ProductCollection>
<Products>
<Product>
<Id>1</Id>
<Name>Tommato</Name>
</Product>
<Product>
<Id>2</Id>
<Name>Apple</Name>
</Product>
</Products>
</ProductCollection>

Writing DTO


Here is DTO:


[Serializable()]
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    [Serializable()]  
    public class ProductCollection
    {      
        public Product[] Products;
    }  

It is not common to write your own DTO's. You should have XSD schema provided and then consider using XSD.EXE to generate your objects.
Observe how objects are clear from attributes.
DO NOT needlesly decorate your DTO with XML attributes unless neccessary.

Bellow code will perform absolutly the same. Added atributes serve only to developer as comments not XmlSerializer. He is perfectly capable to reflect simple DTO's.

[Serializable()]  
    public class Product
    {
        [XmlElement("Id")]
        public int Id { get; set; }
        [XmlElement("Name")]
        public string Name { get; set; }
    }
    [Serializable()]
    [XmlRoot("ProductCollection")]
    public class ProductCollection
    {
        [XmlArray("Products")]
        [XmlArrayItem("Product")]
        public Product[] Products;
    }  

Here is one of proper ways of using attributes. Let's assume that my DTO objects and XML input have different naming of fields or even parent node. In this sample XML field "Name" is mapped to DTO's "ProductName" and XML parent node "ProductCollection" is mapped to our DTO ProductsContainer.

[Serializable()]  
    public class Product
    {  
        public int Id { get; set; }
        [XmlElement("Name")]
        public string ProductName { get; set; }
    }
    [Serializable()]  
    [XmlRoot("ProductCollection")]
    public class ProductsContainer
    {      
        public Product[] Products;
    }  

Writing deserialization


Let's write simplest deserialization for above sample. Note that this code matches last version of DTO's with name mappings.

       private static ProductsContainer GetProductsFrom(string xml)
        {
            using (TextReader textReader = new StringReader(xml))
            {
                var serializer = new XmlSerializer(typeof(ProductsContainer));
                ProductsContainer results = serializer.Deserialize(textReader) as ProductsContainer;
                return results;
            }          
        }
Serializer expect two things: prepared stream with XML content (either from file or plain string like in my case) and secondly type of object we try to deserialize.

Handling nullable or empty values in XML


In real life we can receive empty values for fields content or even complete field can be missing.
For example:

<ProductCollection>
<Products>
<Product>
<Id></Id>
<Name>Tommato</Name>
</Product>
<Product>
<Id>2</Id>
<Name></Name>
</Product>
</Products>
</ProductCollection>

In this sample Id from first and Name from second element is empty.
Of course empty string is completely valid value for String element. Although one could ask how to get NULL value not "" as a result.
This empty Id is problem since conversion from NULL -> Int is not possible.

Let's tweak Product DTO allowing nullable integer:

...
public class Product
    {
        public int? Id { get; set; }
...

That's our side but it is not problem solver. Serializer will not treat empty content or in that manner any other content which is not convertible to Int as NULL. Why would he? Change your mindset - yes he sees NOT empty but non-convertible value and he will complain about it. If you had instead  :
...
<Product>
<Id>foo</Id>
...
; it would still raise error.
Your provider of XML has to handle this too. Again commonly this is stated in XSD schema accepted by both sides as contract.
If no XSD then your provider must explicitly write like this:
...
<Product>
<Id xsi:nil="true"></Id>
...
Additionally on header of root element provide reference to XML schema language like this:
...
<ProductCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...
Otherwise XML Serializer won't know what xsi attribute stands for.

Handling missing value


So what about completly missing fields like this:

<ProductCollection>
<Products>
<Product>
<Id>1</Id>
<Name>Tommato</Name>
</Product>
<Product>
<Name></Name>
</Product>
</Products>
</ProductCollection>

Allowing for nullable types in your DTO will do it. We did it already above with this:
...
public class Product
    {
        public int? Id { get; set; }
...
When XML Serializer bumps on missing field he checks your DTO and sees that nullable is allowed. Ok by him.


Deserializing 1:MANY entity



How about a litle bit more complicated example. Let's assume Order contains collection of products. Here is XML input:

<?xml version="1.0" encoding="utf-8" ?>
<Order>
  <Id>1</Id>
  <Name>Order one</Name>
  <Products>
    <Product>
      <Id>1</Id>
      <Name>Apple</Name>
    </Product>
  </Products>
</Order>

And here is DTO's. Very clean and logic:

    [Serializable()]
    [XmlRoot("Order")]
    public class Order
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Product[] Products;
    }
    [Serializable()]
    public class Product
    {
        public int? Id { get; set; }
        public string Name { get; set; }
    }


Handling XML node attributes



In real life we can have price for our product described in XML like this:

<Product> <Id>1</Id> <Name>Apple</Name> <Price Currency="€" Taxdeductable="true">2.23</Price> </Product>

Value of currency and taxdeduction are described as attributes. This is how we describe it in DTO's:

  [Serializable()]
    [XmlRoot("Order")]
    public class Order
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Product[] Products;
    }
    [Serializable()]
    public class Product
    {
        public int? Id { get; set; }
        public string Name { get; set; }      
        public PriceElement Price { get; set; }
    }
    [Serializable()]
    public class PriceElement
    {
        [System.Xml.Serialization.XmlTextAttribute()]
        public double Value { get; set; }
        [XmlAttribute("Currency")]
        public string Currency { get; set; }
        [XmlAttribute("Taxdeductable")]
        public bool Taxdeductable { get; set; }
    }


Handling XML namespaces



In our samples we work with orders. It is quite realistic that we could get orders from more than one company.
Also it is quite possible that both companies provide us with entites named Order. In such case in XML we use XML namespaces to differ two Order entities
since XML syntax does not allow for two Order elements with different structure.
Here is XML document:

<?xml version="1.0" encoding="utf-8" ?>
<Catalog>
  <myorders:Order xmlns:myorders="http://www.myorders.com/ordercatalog">
    <myorders:Id>1</myorders:Id>
    <myorders:Name>Order one</myorders:Name>
    <myorders:Products>
      <myorders:Product>
        <myorders:Id>1</myorders:Id>
        <myorders:Name>Apple</myorders:Name>
        <myorders:Price Taxdeductable="true">2.23</myorders:Price>
      </myorders:Product>
    </myorders:Products>
  </myorders:Order>
  <croatiaorders:Order xmlns:croatiaorders="http://wwww.croatiaorders.com">
    <Id>23</Id>
    <Name>Pear</Name>
  </croatiaorders:Order>
</Catalog>

Observe that myorders prefix is applied to all elements of myorders:Order. That way all its elements are consistently assigned to myorders xml namespace.
Second order is not all prefixed. Only parent element croatiaorders:Order is prefix. It's items Id & Name are not prefix. This is perfectly legal by XML syntax but not expected by parsers as we shall see.
Our existing entity Order belongs now to xml namespace defined in http://www.myorders.com/ordercatalog.
Second order came from company whose XML namespace is defined in http://wwww.croatiaorders.com
New Catalog entity is added as simple container for both orders.
Let's look at changes in DTO's:

    [Serializable()]
    [XmlRoot("Catalog")]
    public class Catalog
    {
        [XmlElement(Namespace = "http://www.myorders.com/ordercatalog")]
        public Order Order { get; set; }
        [XmlElement("Order", Namespace = "http://wwww.croatiaorders.com")]
        public CroatiaOrdersOrder CroatiaOrdersOrder { get; set; }
    }      
    [Serializable()]
    public class Order
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Product[] Products;
    }
    [Serializable()]
    public class Product
    {
        public int? Id { get; set; }
        public string Name { get; set; }      
        public PriceElement Price { get; set; }      
    }
    [Serializable()]
    public class PriceElement
    {
        [System.Xml.Serialization.XmlTextAttribute()]
        public double Value { get; set; }
        [XmlAttribute("Currency")]
        public string Currency { get; set; }
        [XmlAttribute("Taxdeductable")]
        public bool Taxdeductable { get; set; }
    }
    [Serializable()]
    public class CroatiaOrdersOrder
    {
        [XmlElement(Namespace="")]
        public int Id { get; set; }
        [XmlElement(Namespace = "")]
        public string Name { get; set; }
    }

Our original Order (myorders.com) is decorated with :

[XmlElement(Namespace = "http://www.myorders.com/ordercatalog")]

Note that child elements of myorders.com by default inherit namespace. No further decorating with attributes is neccessary.
So if in XML you consistently use your namespace in all child elements, like we did for myorders:Order, we're done.
On the other hand if in XML you ommit xml prefix for child elements of parent that has declared xml namespace, like we did for CroatiaOrders, then you must explicitly decorate each child element with :

[XmlElement(Namespace="")]

; in order to work with XMLSerializer. Otherwise you wont have errors but NULL values.


And if you ran on problems some good reading:

http://www.codeproject.com/Articles/14064/Using-the-XmlSerializer-Attributes
Troubleshooting Common Problems with the XmlSerializer

Oct 29, 2012

What is POCO & DTO?

Sooner or later after years of working as .NET developer ,without no aspirations to become architect :),  you get hit by this or that pure architecture jargon from your coworker (doing a lot of overnight reading and with aspiration to become architect :) ) or your boss.

Well it happens to once in a while.

So what is POCO?  " Hey, just do plain POCO's object no big deal, OK ? Got it?"

Been there ?

Yea, you try to hide stupid expression from your face and node with your head like you know what is it.
Few developers got guts to simple ask explanation from dude that speaks like that.

One thing you can be sure is that person thinks highly off you :) considering you have more than basic .NET architectural expirience.
POCO & DTO as terms that relay above simple old multi-layer architecture.
Yes they are both .NET classes. So what?

How many times have you decorated your objects for serialization?
Or how many times have you created partial classes to extend  LINQ or EF entities ?
Or writing highly custom WCF contracts and etc?

Well as average developer you do this and that with objects but you don't spend to much time naming what you do. You don't dwell in deeper understanding on what architecture principles lies EF or WCF.
We simply use it, right?

But than it comes to those 1 out of 100 situations. You use WCF, LINQ on everyday bases and BAM you run in to problem. Things don't work as you expected. Been there?
Suddenly its not enough to only know exposed API model - load, save, update, fetch bla bla.
As every normal dude you need to google solution, but how ?

That's my point, average developer today should get introduced to basic architectural terminology so you can google or ask your fellow architect and buy him a coffee.

Back to subject... Plain and simple POCO is good old OO class. You DO NOT decorate it with attributes.

In vision of accepted DDD (Domain driven design) approach it should be in very heart of your domain or business logic (onion architecture).
The catch is that you DO NOT make it dependant on your ORM for example.
And NO it is not just STATE or data container that is DTO.
POCO is full fledged sovereign object that describes in both behavior and content given real world problem.
And it does NOT KNOW how to save itself.

To repeat myself, POCO objects ideally should be in very heart of your project / domain you describe and not dependent on outer architecture that service them.

And what about DTO?
Now that is something you simply use to transfer data. They are flat. Way I see it put in .NET terms DTO are structures (which does not mean that DTO's should be coded as Structure ! ) . They only relay STATE or data NO BEHAVIOR

As stated bellow you could use them for example to service POCO's needs to "talk to world" by describing some data or frequently in web services as quick containers.

http://stackoverflow.com/questions/725348/poco-vs-dto

Oct 12, 2012

T-SQL order incorrect with dash charachter?

For those impatient read this: http://social.msdn.microsoft.com/Forums/en/transactsql/thread/a2785ed0-2355-43f3-bd8b-2200824e9c1f

 Now, this one is interesting...

After 8 years of SQL I'm still learning how to ... ORDER ?!

Check this out:


declare @mytable as table(name varchar(20))
insert into @mytable VALUES('FR-I')
insert into @mytable VALUES('FRieR')
insert into @mytable VALUES('FR-R')

select name from @mytable order by name 


The result is incorrectly ordered:

FR-I
FRieR
FR-R

What ?
 What's wrong, why is FRieR befoer FR-R ?

Aha, you figure it out ... It's the unicode of course.
Let' just use good ol' NVARCHAR and problem solved. Right?
Let's see:

declare @mytable as table(name nvarchar(20))

Nop, still incorrectly ordered...

Hmmm....

Oh yea its probably some collation mismatch, let's use explicit collation in ORDER clause:



select name from @mytable order by name COLLATE Latin1_General_CI_AS

Still not working ? But why oh why.

BTW 
In collation value Latin1_General_CI_AS last chars are VERY important 
CI - Case insensitive 
AS - Accent sensitive 
 or 
CS - Case sensitive 
AI - Accent sensitive 

Here is the solution:

select convert(nvarchar,name) as name from @mytable order by name COLLATE Latin1_General_BIN 

It's interesting that problem shows face only in quite special case like with char '-'.
Try '+' and no problem.
 As always at some point you can't take stuff for granted like ORDER.

"The day you stop learning is the day you die..."


 So remmeber : COLLATE Latin1_General_BIN is your best friend :)

May 29, 2012

doPostBack() saves the day

In its recent versions of ASP.NET Microsoft advises shift to MVC application model.
It is currently its flagship. 
Old classic webforms event driven model obviously want be given to much consideration in future.

But for us regular guys there will still be plenty of legacy code out there written in that old event driven model.
One of often obstacles for anyone starting to use ASP.NET webforms model it is concept of POSTBACK.
People coming from different web background like PHP, JAVA etc. are astounded with this term because it has nothing to do with standard HTTP model.

Anyway, many of us working with complex event driven controls like Telerik gridview and etc. sooner or later stumbled on this event system when we did not had legit ways to "talk" to backend and just POST it simple data.

Ok, one should always put effort to find legit way through given control event model or props to pass certain value(s) to backend.
But, I guess you've been there when you are pushing deadlines and you have to deliver.
Well sometimes you have to cross the line and start writing dirty. 

After 5 years I'm still learning so recently I've discovered doPostBack().

You need to push something using full page reload and tell the backend that it came from specific control which on top of it sends some value and you don't have faintness idea how to do it with given set of asp.net controls

Here is what you could consider as workaround: 


__doPostBack(postbackcontrolid,id)



;This will result in full page reload and then in PageLoad event you can handle action to be taken like this:

VB.NET


If Request.Params("__EVENTTARGET") = "imgDeleteWeitere" Then

            Dim id As Long

            If Long.TryParse(Request.Params("__EVENTARGUMENT"), id) = True Then


Watch it !  Compiler can't save you from typos in postbackcontrolid. Some articles also point out that it is not certain that in every scenario doPostBack will fill these params.

So if you use it thoroughly test and soon as possible replace with proper control driven solution...



May 16, 2012

Making HTTPS POST using webrequest with cookie handling

A bit intro in beginning...
My credit card company is a bit lazy. In this age of IT revolution its normal to receive info and not to ask for it. In order to get my credit card account balance I need to access my online account.
This sucks.
I wanted to receive my credit card balance in email on a regular timely base. But credit card company does not allow for this. It's not like they want me to be aware of it :)

Challenge was how to do POST from windows service on HTTPS url.
Simple sniffing of POST from browser got me details for POST data.
After a bit of google-ing I came up with this.
You know that stupid feeling when you write a bit complex stuff and it works on a first try.

One must admire guys from Microsoft in doing good job.
Observe what complexity is hidden in just few lines - negotiating HTTPS protocol, handling in and out of cookies.

Cool...

Here is the code that makes actual HTTPS POST:


   var postData = "j_username=xxxxxx&j_password=xxxxxx&Submit=continue";
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] postByteArray = encoding.GetBytes(postData);

            var response = new List();
            Uri myuri = new Uri(MYURL);
   
   var cookieContainer = new CookieContainer();

   //.NET client to accept all certificates
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
        
            HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(myuri);
            webRequest.CookieContainer = cookieContainer;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = postByteArray.Length;
            var requestStream = webRequest.GetRequestStream();
            requestStream.Write(postByteArray, 0, postByteArray.Length);
            requestStream.Close();
            
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
            
            using (Stream resStream = webResponse.GetResponseStream())
            {
                StreamReader reader = new StreamReader(resStream);
                string resline = "";
                while (resline != null)
                {
                    resline = reader.ReadLine();
                    response.Add(resline);
                }
                reader.Close();
                resStream.Close();
            }
            return response.ToArray();

May 8, 2012

ASP.NET web api - multiple get does not work ?

So you've read and seen all there is on asp.net/webapi and your webapi service is running smoothly.
You follow rest and design guidelines of WEBAPI and place one GET, POST and all HTTP verbs.
Everything works, great cool.
For example in your CustomersController you have simple and single GET action which works just fine:
public string Get()  { 
return "Coolest customer controller";
 ; on url:   http://localhost/api/customers/get
and then you casually add another GET action:

public string Get(string what){
return "I'll be back";
}
And you run into problems:

404 - File or directory not found.



What a hack ?!

Ok, so you comment second Get and it works again. Aha!
But if you comment first Get and leave second it still works?
Actually if you step way back to your scenario with one GET and change action name like this:

public string GetDummy() {
thing still works on same url !

http://localhost/api/customers/get

What a  ... ?
You fervently start playing with different action names and it always works ?!
Now wait a sec... If you haven't played too much with MVC concept and you come from clean ASP.NET webforms arena you are by now probably in major piss of  state :)

Solution to your problem is tweaking routing engine. WEB API as HTTP skeleton of WCF is build on top of ASP.NET MVC and it uses its routing engine.

Catch is that guys from WEB API did not mean that average dude should have this basic routing setup out of the box in your WEB API template.

So go ahead and do it your self.
In your Global.asax.cs observe this part:


routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );


; and tweak route so it accepts your action name like this:


routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );


Now everything should work fine ...















Apr 27, 2012

DART - Google develops new javascript

Ok, another one...
Google is on attempt to develop web structured language that can compile to JavaScript.
Catch is it should support server side scripting what ever that means.
And it can not mean nothing less then employing Google web servers or what?

http://www.dartlang.org/

Cofee script

I had to persist this one as bookmark. It's one of those things that you don't hack know what they are for but they uber cool :)
Guys wrote small JavaScript language without lose of performance.
You write JavaScript with 1/3 length of original code.

http://coffeescript.org/

Apr 25, 2012

JQuery Mobile theme roller in action

JQuery Mobile elegantly approached customizing colors and feel of its UI by enrolling complete online solution through web app named "Theme roller".
Here is url:
http://jquerymobile.com/themeroller/

It looks great but I ran into problem.
I've created custom css, downloaded it and tried to put it as it should as an extending CSS that loads before original JQuery Mobile CSS. Hence it supposed to override existing JQM swatches A,B,C etc.
Something like this:


<link rel="stylesheet" href="themes/mycustomtheme.min.css" /><link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile.structure-1.1.0.min.css" />


It did not work for me. :(
So I end up with copying portions of swatches into original JQM CSS.
Open up CSS you just downloaded from theme roller and find for example swatch C witch should look like this:

/* C
------------------------------------------------------------------------------------
.ui-bar-c {
border: 1px solid #0071bc /*{c-bar-border}*/;
background: #53b9e4 /*{c-bar-background-color}*/;
Copy complete section and copy it to jquery mobile CSS  jquery.mobile-1.0.1.css under the same section.

Yes its wrong, yes I should dig out problem but for now it works.



Apr 15, 2012

ASP.NET WEB API vs MVC or what?

Now this was confusing at first.
So what's with this new ASP.NET component WEBAPI?
While ago I've got task to create lightweight back end for mobile JSON consumer app.
Ok, let's roll WCF, contracts, binding  WCF ABC and that stuff.
But no my colleague came with another acronym:
"No man, we'll use WEBAPI REST services. Where have you been, locked up somewhere ? :) "

And on top of it came another statement:
"Look, we must install ASP.NET MVC 4 so we can plug it in ..."

MVC ? What a ...?
Now wait a minute. There is that giant stuff that communicates with everything in the world (and they are building protocol for aliens :) ) called WCF? Right?
It inherited good ol' SOAP like in stone age.
To my humble knowledge that baby goes along and host virtually on anything that can host .NET.
It has nothing to do with MVC or webforms.
So what's the catch?

Well you'd better listen to this great Scott Hanselman minutes (no, I'm not on his marketing payroll :) ):

http://www.hanselminutes.com/264/this-is-not-your-fathers-wcf-all-about-the-webapi-with-glenn-block

Ok, now google REST and you got the picture.

Now, reason for this post was something else. On introduction videos on http://www.asp.net/web-api
there is very important statement about WEBAPI in MVC "skin".

When you create routing for WEBAPI you DON'T define actions as in classic MVC model.
WEBAPI defines standard HTTP  REST statements POST, PUT, GET ... as actions.

For me that punches the whole idea on integrating this "baby" wanna be REST WCF into MVC model and it fits just fine give it a try.


Apr 11, 2012

Proper referencing of PhoneGap with JQuery mobile

Ok, so you've setup Eclipse, Android SDK, PhoneGap or XCode and you want to use best from the two javascript libs:
  • PhoneGap
  • JQuery Mobile
JQuery Mobile is not just another JQuery plugin. So you don't just reference it and use it per scenario.
After its loading it runs asynchronously number of tasks to change DOM structure so it fits into JQMobile UI layout conventions.
Bottom line is that any other yours peace of javascript has to be put in proper place inside this JQM model or you won't get results you expect.

How to reference PhoneGap with JQuery Mobile?

It depends what and mostly when you want it to be done.
If you need to run it as the very first thing before JQM and you don't need nothing from JQM for this task you must reference it on the top before referencing JQM library like this:
<head>
...
  <script type="text/javascript" >
    function OnDeviceReady() {                    
                      // Do something when PhoneGap is initialized
                }
     $(document).ready(function(){
                document.addEventListener("deviceready", OnDeviceReady, false);
   });
   </script>
   <script type="text/javascript" src="jquery.mobile-1.0.1.min.js"></script>   
 ...
</head> 


Now this will work but there is a catch. Both PhoneGap and JQmobile libs are based on event driven model. They run bunch of task in their own processes asynchronously. What this means is that when you tell PhoneGap that you want OnDeviceReady executed it will not be executed until phonegap in separate thread says I'm ready.
After line:
          document.addEventListener("deviceready", OnDeviceReady, false);
; execution continues and JQM starts to kick in. So they run parallel and no one can tell will OnDeviceReady really get executed before JQM starts.
Now someone will say that this is exactly what is expected from async process to behave but its just not plain obvious when you start to play with this things.

Hence I figure out I'll have to do some more reading on JQM :)

To cut long story short as a manual for lazy developers, like I'am, here it is.


<div id="MyPageUniqueName" data-role="page" data-theme="e">        
        <script type="text/javascript">
            $("#MyPageUniqueName").bind("pagebeforecreate", function (event) {

                  function OnDeviceReady() {                    
                      // Do something when PhoneGap is initialized
                }
                document.addEventListener("deviceready", OnDeviceReady, false);

});
</script>
...

JQM recommends injecting your code in appropriate JQM events. Read JQM docs for details on events and their purpose.

Although in proper place this code still does not guarantee that OnDeviceReady will get executed before JQM thread kicks in.

This represents a problem only if you need PhoneGap to prepare some stuff BEFORE JQM starts.
For example you need to obtain some data from mobile device internal storage using phonegap, inject it to DOM of page and let JQM render UI with new data.

Although you could try to wait using setTimeOut() while PhonGap loads and do its work and then let go JQM continue it is simple not right approach.

Right approach is to have Page A that prepares DATA using PhoneGap and then POST's this DATA to PageB. Page B then does not care about when PhoneGap is loaded since it already has its required DATA and can render it in proper JQM event PageBeforeCreate.












Kick off

Hi,
you are visiting blog that tracks some of my interesting experiences with various web & mobile development endeavors from both my professional and amateur effort.
I make my bread as senior ASP.NET developer with occasional ventures in "dark side" NON-Microsoft arena :).
As any other developer out there and after a lot of Google-ing I've figure out that is easier to put some things online so I can keep them in one place and maybe someone else will get his answers just as I often seek them.

So have a nice reading a drop a line if you care,

Sinisa