Subscribe Now: Feed Icon

Saturday, October 19, 2013

Everything for Free, part 1

(the title is from K’s Choice – Everything for Free)

I have a friend who keeps calling me a hacker, I am not a hacker – not even close. I just use the tools I know far beyond what most other people are using them for. That is how I get some stuff for free while other people choose to pay for them.

I have far too many IOS apps in my account that I haven’t paid for (and they are legally mine), I also have around 30$ in my account that I got for free.

So how do you get free IOS Apps?

 

1. AppShopper

This how I got “Bike Baron” for free today :)

1. Register at AppShopper and mark all the apps you want with the “Want It” check.

2. In your email account add a rule that any email from notifications@appshopper.com that doesn’t contain the word “Free” skips the inbox and is moved to a “junk” folder.

Now every free app from your list will magically appear in your inbox when it is freed – so just “buy” it.

 

2. AppShopper

This is a way to get popular games you might not be aware of (which are free).

For this you will need a RSS feed reader such as Feedly. Subscribe to the following RSS feeds:

iPhone apps: http://appshopper.com/feed/?device=iPhone&mode=featured&type=free

iPad apps: http://appshopper.com/feed/?device=iPad&mode=featured&type=free

The feeds contain the Popular free Apps for either iPad or iPhone.

There will be overlap between the feeds but sometimes there are Apps that are iPad specific that the iPhone feed misses.

 

3. FreeMyApps

Using this way I had 45$ gifted to my account.

From your device open the following link (disclaimer: using this link will give me 200 credits).

1. Download Apps from the Sponsors tap, try them for 30 seconds and get credit

2. When you have enough credits you can exchange them for gifts – 4500 credits for 15$ iTunes Gift Card

Share your link with your friends and get more credits. If you want even more credits you can use the Dropbox Google Ads trick (basically get free Google credit and put an ad for free IOS Apps using your link, and for extra credit set the Google Ad to target only IOS devices).

Tip: if you have two devices then you can get the 200 credits for a friend and collect credits using both devices (they are listed as separate accounts – you can’t add them together to exchange the credits for one gift).

 

 

Call me crazy

In K’s Choice the price for getting things for free is people thinking you are crazy – the point is there is always a price…

When you get things for free there is nothing stopping you from getting too much things, especially when it is something like Apps that don’t take much space. There also downfalls to having too much stuff – in the case of IOS Apps I found it the hard way when I bought a new device – the fastest way I have ever seen 64GB of space being filled… I have since came up with a system to keep only the best of apps – everyday I try to organize 5 apps by either deleting them or keeping them in an Excel of best apps (so that when I upgrade my device I won’t have to work hard).

 

The next post is going to be on getting Free Kindle eBooks (right now I have ~60,000 of them in my account).

Sunday, August 11, 2013

Feedly Style bug

As everyone knows Google Reader died more than a month ago and a lot of replacements popped up. One of the leading ones is Feedly (another is Go Read) which supports most of the functionality of Google Reader (Go Read supports less). After the days of mourning have passed (why Google, WHY?!?) and I started using Feedly I found a weird bug. Looking at The Daily WTF, for example the post from “The Last Straw”:

Gather customer requirements   <span style="color: rgb(128, 128, 48);" sab="400">-</span> <span style="color: rgb(0, 140, 0);" sab="401">2</span> weeks
    Functional Design              <span style="color: rgb(128, 128, 48);" sab="402">-</span> <span style="color: rgb(0, 140, 0);" sab="403">2</span> weeks
    Detailed Design

But looking at it from the preview option (or opening the post in the browser) reveals a a much cleaner code - the HTML span tags are gone:

    Gather customer requirements   - 2 weeks
    Functional Design              - 2 weeks
    Detailed Design 

And the code is much more readable.

 

Why the difference?

Because Feedly doesn’t support Span tags – it turns them into text (Google Reader had this support).  And it seems that many blogging tools are using Span tags as the way to write code (The Daily WTF is the most famous of those blogs).

(In my blog the case seems to be a bit less hectic, the code in Feedly is shown but without Visual Studio’s colors that are shown on the site).

What can I do about this?

Glad you asked. In the Feedly User Group there is a bug opened on this very issue: “Support HTML span tag, to display styled text (source code, highlighting etc.) from original post”. In the time I am writing this down there are only 226 votes – please use your +3 votes on this issue.

Thursday, July 25, 2013

Pitfalls in restoring/moving SQL Server GeoDatabase

For the past two weeks I have been dividing my time between job interviews and moving a GeoDatabase from a Data Center in Spain to Israel. The GeoDatabase in question was SQL Server 2008 with SDE 10 and it was moved to a development server that at first glance seemed to have the same installation.

The moving of the Database was done by using SQL Server backup and restore of both the SDE database and our data database. The first problem that popped up was of Orphaned Users (I wasn’t the one to fix it but found this solution).

The next problem was over zealous IT people that gave everyone SA (System Admin) rights on the database, why is that a problem? well lets say user UserX has permissions to query a table named UserX.Points in the database and he has a default schema of UserX all he has to do in a query is:

SELECT * FROM Points

(This is also the default way we queried the DB from our application)

But if the user is defined as a SA then he must query with the full name of the table:

SELECT * FROM UserX.Points

The default schema name seems to be ignored.

 

The next problem was this error in ArcGis Server:

The Layer:'DB_NAME.SCHEMA_NAME.LAYER_NAME' in Map:'Layers' is invalid. This release of the GeoDatabase is either invalid or out of date. DBMS table not found [Microsoft SQL Server Native Client 10.0: Invalid object name 'sde.sde.GDB_Release'.] [sde.sde.GDB_Release]

The first thing I tried was opening SQL Server Management with the sde user and trying to query sde.sde.GDB_Release. The object can’t be found. Next I tried the SA user – failed as well, the table just didn’t exist. Checking the DB in the Data Center revealed that the missing table wasn’t there either – but there the ArcGis Server worked. I came into a conclusion that the table was from Sde 9.3.1 and in the upgrade to 10 (for some unknown reason) it is still kept (but not when doing a fresh install of version 10).

I have used the Sde command line tools to check what layers are in the DB: they were all there.

At that point I realized I needed to open ArcCatalog/ArcMap and try to solve the problem, but the PC where our license was stored was missing (all the PCs were turned off, stored in one storage room and there wasn’t any identifying marks on that specific PC). So I made a call to Systematics (the local retailers and experts on ESRI software) they gave me a link to a free trial of ArcGis Desktop 10.1 installing that didn’t solve the problem just made it weirder:

Using ArcCatalog I was able to connect to the features in the Database (as seen from the Sde command tools).

Using ArcMap I was able to open the ArcGis Server MXD and even save a document in the format of 10 but the error persisted.

I have made a backup of the geographic data on a File GeoDatabase and tried unistalling the Sde, deleting the Sde database, reinstalling the Sde (version 10) and then doing the restore again. In the thought that maybe using a fresh installation of Sde 10 will solve the problem (as opposed to an upgrade from 9.3.1). It didn’t work same error as before…

At that point I decided to broaden my options and install Sde on an existing DB server and ArcGis Server on another server. The new Sde was (this time) installed using our deploying application (instead of the backup/restore method) and then the data was imported using ArcCatalog. Trying to use a MXD with layers from this DB resulted with the error:

The Layer:'DB_NAME.SCHEMA_NAME.LAYER_NAME' in Map:'Layers' is invalid. The connection property set was missing a required property or the property value was unrecognized.

I tried both MXDs on the new ArcGis Server – the same errors (meaning the problem was not in the server).

I tried using data from a File GeoDatabase – that worked without any problems (in ArcGis Server) but trying to use it in our application caused the queries to return empty results because we were using where clauses that looked like Modified > ‘2000-01-01’ and it seems File/Personal GeoDatabse doesn’t support this type of date queries. I used it though as a temporary fix because some actions could be done even though no features were displayed in the map.

I tried creating a new Feature using ArcCatalog and trying to view just that feature – failed as well. The thought here was that maybe the deployment application caused the problem.

I have become a bit desperate so I even tried manually creating GDB_Release table in my original DB, found this reference that had all the fields of the table and tried entering versions:

  • Major: 10 Minor: 0
  • Major: 9 Minor: 3
  • Major: 9 Minor: 4

For all of them I got the new error:

The Layer:'DB_NAME.SCHEMA_NAME.LAYER_NAME' in Map:'Layers' is invalid. This release of the GeoDatabase is either invalid or out of date.

 

Then the people from Systematics saved the day and freed our licenses (because it seems that you have to deauthorize a license before you use it in another PC). After installing ArcDesktop 10 I got this error trying to connect to the original Sde (just by testing the connection):

ArcCatalogConnectionError

This is the same Sde server that worked with ArcDesktop 10.1…

 

But the new Sde worked just fine, and after creating a MXD file ArcGis Server worked as well.

 

At the end we decided to use the new Sde and mark the old one as an example of what happens when you upset ESRI’s software…

 

Conclusion: When transferring GeoDatabases don’t use Backup/Restore (and if you do then keep a backup of the old version of those databases) instead use ArcCatalog to transfer the feature data (you can even use it to transfer non geographic data). Unless of course you are feeling lucky! Are you feeling lucky, punk?

 

I would like to thank Mody Buchbinder and Yovav Zohar from Systematics, without them the problem would never have been solved.

Tuesday, June 11, 2013

Leaving a Better Place

I never actually wrote it in this blog but for the last 3 years I have been a Better Place employee (I have actually had an image of an award we received back in 2011 with the words Better Place but never actually wrote them as text).

It’s actually been a great 3 years where I met some amazing people and learned great technologies. When I joined the team our system – GTM (Grid Topology Management) was just starting up – basically the only action available was creating Sites (in Better Place the Site entity was the main entity – it could either mean a charging Site or a Battery Switch Site (BSS)). The server side at that time had a single WCF file with all the code (logical and DB access, and with using ArcObjects meant quite a bit of code).

It didn’t take me (too) long to change all that so the server side (which is more my specialty) now has a separation between the service layer, the BL (Business Logic) and the DAL (Data Access Layer). The BL is fully tested using NUnit (for a time it was VSTests). The Silverlight UI had so many upgrades like:

  • Google Street View from the Silverlight Application
  • Editing the Electric Topology (adding a Panels, Circuits, Spots ,Sockets and sometimes even communication elements since Better Place’s Grid could be remotely controlled – and in Denmark end users could set when their Electric usage was at a peak so that the Electric Vehicle will get less).
  • Electric Topology validation – so that before installation all the planned hardware elements could be verified to be correct
  • Routing – going from point A to B when you have to look out for your battery or switch it is not something Waze implemented (though wouldn’t it be cool if you just entered your remaining KMs until you have to fill your tank or switch your battery and have Waze do it automatically – with your preferred Gas Station (or BSS))
  • Traffic Reports – basically like it is implemented in Google Maps (only we used a paid service

The server side had many integration services build as well like making an order from SAP, communicating to the Electric Vehicle what Sites are down (maintenance or some kind of technical problem) and much more.

Along the way I somehow got some free software like Resharper, dotTrace (maybe I should be a QA?) and NDepend.

My last year at Better Place was dedicated to lowering operation costs and improving the system. One of those improvements was moving from SQL Server to Oracle, which considering we were using Linq2Sql meant moving to another Framework. For a time our team used Entity Framework and another team at the department used NHibernate, than for solidarity reasons we moved to NHibernate (I might write a blog post on that because: A. we had to use Timestamp and NHibernate “supports” it by using DateTime – not DateTimeOffset. B. for some odd reason NHibernate kept adding semi random numbers to column names’ aliases and with Oracle’s query optimizations that caused problems unless we used projections). The mapping for our NHibernate usage was done using Fluent NHibernate (for some odd reason I never liked writing xml where I could use plain code, is it just me?).

Through the downsizing and people leaving us I was put in charge of the in car computer called Oscar, unfortunately I only had enough time too learn it’s systems – not make any changes. I did find many bugs in the Media Player system (I even wrote an unofficial guide about how to operate it with the least amount of problems, like did you know playing all the songs on your DOK will be changed the next time you start your car to playing only the last artist’s songs?).

In the last 3 months we also had a MVC+jQuery course and had started to implement the new Self Service site (you can see it’s design here) when as the papers say “the battery has run out”…

Today I had to return my Electric Vehicle, yesterday I switched the battery for the last time with this vehicle (if the service continues I might just get another one sometime in the future, I really never had such good performance from any other car).

 

So after this long but partial summary of the last 3 years it is time to say I have started looking for the next Better Place. If you are looking for a Software Engineer (even if it’s not map related) then you are welcome to email me with the details. I have already found my next Better Place, I am starting at Microsoft at the start of August.

Monday, April 8, 2013

ORA-03149: Invalid Oracle error code

Just got this error.

The only thing I saw on the web on this was: “This is an internal protocol error. Contact Oracle Support Services.”

As I see it, it means Oracle doesn’t know what I did wrong.

At the end we found out that the error was caused by entering a value of 1.7976931348623157E308 to a NUMBER(38, 8) field. The person that sent me this value meant to send NaN but at the end sent Double.MaxValue.

I am sure this is just one symptom of the problem but maybe it will help someone out there…

Wednesday, March 27, 2013

SDE: Using SQL to copy feature rows

(Or to Bulk Insert features to a feature table)

This only works if you are using Oracle/MS SQL geometry types (where the shape field is not an integer but an actual shape).

I always thought that for copying more than one row of feature data I will need to use ArcCatalog, for one row I usually hard coded the OBJECTID field and hoped that the next person using ArcCatalog won’t hate my guts…

Well last week I needed to duplicate rows in a feature table and found this link, and even though it says ArcSDE 9.3.1 as the latest version it works on version 10.

Use:

SELECT table_name, registration_id FROM sde.table_registry WHERE owner = 'OWNER'

To find the registration number of the feature table, for example 21.

 

To find the next available ObjectId:

sde.version_user_ddl.next_row_id('OWNER', 21)

 

To copy the rows of Table_Name (for example: from type 1 to type 2):

insert into Table_Name(objectid, shape, Type) select sde.version_user_ddl.next_row_id('OWNER', 21), shape, 2  from Table_Name t where Type = 1

 

And that's it.

Monday, March 4, 2013

HTML5+MVC Course, Day 3

Continued from day 1, day 2.

This lesson was more a review of the last lesson with the added value of looking at profiling tools. In the summary I just skipped the review part…

 

After opening a new MVC project from a template looking at the libraries installed you will find that they are old libraries. You can update them if you wish using NuGet –> Update:

NuGetUpdates

NuGet knows which libraries it needs to update by looking at the packages.config file that describes the installed packages and their versions. For example:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="5.0.0" targetFramework="net45" />
  <package id="jQuery" version="1.7.1.1" targetFramework="net45" />
  <package id="jQuery.UI.Combined" version="1.8.20.1" targetFramework="net45" />

 

Web Programming must have:

  1. Browser Sniffer with a capability to see the HTML – Chrome F12
  2. Client side Sniffer that displays the data as it passes (optional: with JSON parser, with debugging, comparison) – Fiddler
  3. Server side: DB profiler for queries to the DB – SQL Server Profiler

 

Fiddler

FiddlerOverview

Clicking on the “Capturing” in the bottom left corner (pink arrow) will stop and start the capturing.

Clicking on the X (orange arrow) will give you in it’s first option: Remove all. Clears the screen.

HTTP Results:

  • HTTP 100-199 are for information
  • HTTP 200-299 are for successful result, for example: 200 is for success (green arrow)
  • HTTP 300-399 are for redirect, for example: 304 (blue arrow) indicates the result is in browser’s cache
  • HTTP 400-499 are for client errors, for example: 404 page not found
  • HTTP 500-599 are for server errors, for example: 503 server unavailable

On the top-right side of the screen Inspectors->raw we can see the request with it’s http headers

On the bottom-right side of the screen: raw if the message is encoded you will see gibberish (and the Content-Encoding will be gzip):

HTTP/1.1 200 OK

Content-Encoding: gzip

Content-Length: 44892

��������`I�%&/m�{J�J��t��`$ؐ@������iG#)�*��eVe]f@�흼��{���{���;�N'���?\fdl��J�ɞ!���?~|?"��O�<y���<M��<���������ⳏ��

*** FIDDLER: RawDisplay truncated at 128 characters. Right-click to disable truncation. ***

Then:

FiddlerBinary

Click on “Response is encoded and may need to be decoded before inspection. Click here to transform” (blue arrow). Or do it by hand by going to the Transformer tab and select “No Compression” in HTTP Compression.

Ajax+JSON Calls:

You can identify Ajax calls by:

FiddlerAjaxJson

Ajax calls will have: X-Requested-With: XMLHttpRequest (blue arrow).

JSON calls will have: Accept: application/json (green arrow), we can also see that the response has the Content-Type we requested application/json (bottom row).

The JSON response can be read several ways:

1. Text/Raw view:

[{"value":"ALFKI","label":"Alfreds Futterkiste"},{"value":"ANATR","label":"Ana Trujillo Emparedados y helados"},{"value":"ANTON","label":"Antonio Moreno Taquería"},{"value":"AROUT","label":"Around the Horn"}]

Raw will also show the headers.

2. JSON view:

FiddlerResponseJsonView

Views the JSON as a data structure – more readable.

 

Chrome F12 Profiler

Console

From the Console you can run jQuery queries like you can run code in the Immediate of VS:

ChromeF12Console

Console will also show JavaScript errors:

ChromeF12ConsoleException

We will know there is an error by the error icon at the bottom-right corner (red arrow).

We will get the exception details like: from where it was thrown and the description at the center (orange arrow).

And most importantly we will get a link to the actual location in the code the error was thrown from (blue arrow), clicking on it will lead us to _ window:

ChromeSourcesDebugException

As you can see the error icon appears on all screens (red arrow).

You can see the location of the error (yellow arrow).

And you can watch the local variables at the right side (blue arrow).

You can also add more functionality with extensions (for example PageSpeed).

Timeline

very important!

ChromeF12Timeline

At the bottom there is a button for starting the profiler (red arrow).

At the top you can select the timeframe, my browser default for some unknown reason was the first 1 second – so the default is not seeing anything (use the lines at the blue arrows to adjust the time frame).

Profiles: Memory leak checker

ChromeF12ProfileTakeSnapshot

Take heap snapshot at the start and you get the current memory profile:

ChromeF12ProfilesSnap1

As with most memory profiling tools you can sort (blue arrow) by object count, shallow size (the size of the element by itself), retained size (the size of the element including links to other classes). You can read more on the size differences here, but we will use retained size.

You can also drill down to the actual function/line that takes the memory (green arrow).

Take another snapshot and you can compare snapshots:

ChromeF12ProfilesCompare

At the bottom change from Summery to Comparison (blue arrow) and all the view changes to a delta between the runs.

 

Note: IE has it’s own profiler but it seems to be for running time and not for memory leaks.

 

Entity vs. Class

Entity has to have a unique identifier – Key.

Data/Class is without an identifier, JSON uses data not entities (only Silverlight has entities in the client)

If we were to return an Entity with JSON:

public JsonResult GetCustomersCircularError(string term)
{
    var results = from c in db.Customers
                  where c.CompanyName.StartsWith(term)
                  select c;

    return Json(results.ToList(), JsonRequestBehavior.AllowGet);
}

The parser might fail with a circular reference exception:

JsonCircularReferenceError

Instead we have 2 options:

1. POCO: Create a class (View Model) for the return value – one without circular references.

public class JsonCustomer
{
    public string value { get; set; }
    public string label { get; set; }
}

public JsonResult GetCustomersClass(string term)
{
    var results = from c in db.Customers
                  where c.CompanyName.StartsWith(term)
                  select new JsonCustomer { value = c.CustomerID, label = c.CompanyName };

    return Json(results.ToList(), JsonRequestBehavior.AllowGet);
}

2. Use Linq+Anonymous Classes to return that data from the DB entities:

public JsonResult GetCustomers(string term)
{
    var results = from c in db.Customers
                  where c.CompanyName.StartsWith(term)
                  select new { value = c.CustomerID, label = c.CompanyName };

    return Json(results.ToList(), JsonRequestBehavior.AllowGet);
}

Yair believes the second option is best because the class will only be used for returning values (you can’t use it in the client because the client is in JavaScript – not C#).

 

Demo: AutoComplete+Redirect

AutoComplete box that when an item is selected the page is redirected to another and the value of the AutoComplete is passed to the new page.

Server side:
public ActionResult OrdersForCustomers(string id)
{
    var orders = db.Orders.Where(ord => ord.CustomerID == id).Include(o => o.Customer);
    return View("Index", orders.ToList());
}
Client side:

We will use the select event of AutoComplete box. Since we don’t really know the event arguments lets debug them to see their values:

<body>
    <input id="txtCustomer" />
    <script>
        $("#txtCustomer").autocomplete({
            source: "orders/GetCustomers",
            select: function (event, ui) {
                alert("Breakpoint here!");
            }
        });
    </script>
</body>

Note: putting the script tag inside the HTML body is another way to write $(document).ready(function(){…

We will add a breakpoint at the alert to see the argument values:

ChromeF12DebugSelect

As we can see the event argument contains information on the event itself: who called it, from where on the screen, the control name…

The ui argument is what we need it contains both the value and the label of the item selected.

Now the only thing left is to do the redirect:

<script>
    $("#txtCustomer").autocomplete({
        source: "orders/GetCustomers",
        select: function (event, ui) {
            var url = 'Orders/OrdersForCustomers/' + ui.item.value;
            window.location = url;
        }
    });
</script>

And the page will change to the correct URL.

Monday, February 25, 2013

HTML5+MVC Course, Day 2

Continued from day 1.

Last class we learned about the client side, today we are going to go over the server and talking to the server. In the past it was done with Forms and the method Post. Today there is Ajax.

If you want to skip the history lesson you can just go straight to “ASP.NET MVC 4” title.

General

There are 3 option to build Web Applications:

1. Html rendering in the Server side

Every action from changing the color of the text to filtering a table is done by calling the server and getting the result to the client. If you wanted to see the Current Movies, Current Traffic, something from the DB/File system the server renders it.

The server is a “Factory” for Html.

Technological History: CGI, ASP (allowed saving data in the server using the Session object), Sun did something similar with Java.

The Code is build into a Dll, you get to write in a real language (.Net or Java), you get memory management, variables, …

You want to do something, you fill out a Form and data goes to the server. But doing something like Filtering required going to the server as well. Microsoft added a lot of libraries to help this pragma: Rendering, Caching, Database, Controls. All of them for the server side.

 

The Browsers became stronger, so they moved to option 2:

2. Ajax: Html Rendering in the Server but some parts call the server for updates

In the past there was a Frame that you could use to receive updates to just part of the page (most of the Portals inside organizations are still built like this). But Frames are in the past and HTML5 doesn’t include them. Frames are windows that work independently – like opening a different browser per frame, but with frames you can have one frame ask another to do some action. Every frame has a different DOM.

Inner objects in the Html page are calling the server with Ajax to receive updates. The whole page is not updated just the inner part.

Ajax Call – Microsoft has invented a component called XML Http (later the other Browsers implemented it as well) that is  an Object that lives in the DOM (it is actually part of the DOM), it resembles a Frame, it has an inner Form, it sends a request and gets back a response asynchronously (without asking – it’s default way). XML Http was later renamed Ajax, they first believed that you will just transfer XML data and in the client transform it using XSL – joining them both will result in HTML (it was called B2C - Business to Consumer). For a long time no one used that object because ASP got in and made use of option 1, only a few people actually worked with it.

Then Mozilla-Firefox and Google-Chrome adopted this object and gave it the name Ajax - Asynchronously JavaScript And Xml: Asynchronously because that’s how it worked, JavaScript because that the language that consumed it, And Xml that was back then. Today the only part left is asynchronously (JavaScript is a given) no one uses Xml…

ASP.NET Ajax is Microsoft adoption of option 2: it uses a hidden field named ViewState to pass data from the server to the client, they built the ViewState in the Client and passed it to the Server, then built in the Server and passed it to the Client… It worked well: Render in the server and update increments. Sorting some table for example sent Ajax to the server, the server returned a small Html part, then you took a “knife” and cut out the old Html and put instead the new Html. All you had to do was mark which Control you wanted and the system would disable the submit for those controls, do an Ajax request, receive an Ajax response with just the Html needed and replace the control.The problem is it was all done automatically, architecturally wrong: just “drag and drop” and the system patched all the component together. This system was easy for starting users but annoying to advanced users: even changing the design of a button might cause headaches.

ASP.NET came in 2001 to solve the then problem of memory. The Session was a problematic object (the Enemy) that was kept for 20 minutes (by default). So to solve that problem ASP.NET transformed the session to an object that was passed from the server to the client called the ViewState. Since that time memory became less of an enemy, storage has became cheaper but Microsoft was stuck with the ViewState (not using it was an equitant to going back to ASP).

Then came PHP that Facebook was built using a spinoff of PHP. PHP came with the attitude of not using the ViewState hidden field. After that in 2010 Microsoft came up with ASP.NET MVC.

2.1. ASP.NET MVC

The Controller (written in C# and can be debugged and unit tested) creates/puts data into the View and renders the Html in the Server. The controller also allows returning JSON to the client without rendering the Html (the + 0.1). As opposed to ASP.NET Web Forms:

  • No more Ajax
  • Works with jQuery (in it’s orientation)
  • Total separation between the client side and the server side

No longer uses the ViewState, instead uses the Session.

In 2012 Microsoft adds ASP.NET Web API, Mobile, Facebook extension,…

3. Html Rendered in the Client, the Server supplies the data

The application is written with a static Html page, the Server supplies the data with the Business Model. No Html is rendered in the Server. The rendering is done in the Client. The first template might come statically from the server but nothing is rendered in the server.

jQuery was build in the same time as ASP.NET Ajax by John Resig, started as a library that supplied selectors by Id, Class name, Element name, etc. (Original JavaScript code). Minimal code that rely on CSS3. Supports all the Browsers (from IE8 and on, Firefox, Chrome…). Then he added some elementary actions like toggle, style, etc. And (of course) provided support for Ajax (in a property that has a url to which you can GET or POST with a name-value array).

jQuery became a Must Have for every Web Developer in the industry. On top of that came the jQueryUI group that build it’s control on top of jQuery as an alternative to Microsoft’s ASP.NET Ajax (like the AutoComplete box that is available at both libraries).

At around that time JavaScript Framework started appearing that enabled OOP JavaScript, with MVVM or MV* (MV Something): Model you always need, View you always need, now you need something that connects them – in MVC it’s the controller and in MVVM it’s the View Model. The Frameworks were built in GitHub where entire communities were built around those projects. One of those is Knockout by Steve Sanderson who is now a Microsoft employee (though the code is not owned by Microsoft). Knockout gives Templates and is very similar to Silverlight.

 

ASP.NET MVC 4

We will start with ASP.NET MVC of option 2 (fully rendering in the server side: looking briefly at the Controllers of MVC, the routing mechanism, the view, the Razor engine that help the view. The model will be built using Entity Framework. First by hand then using a wizard) and upgrade it to option 3 (with a html page that calls the server for JSON data, with jQueryUI AutoComplete).

Create empty MVC Project with Empty Project Template (or just use the one from last lesson):

CreateEmptyMvcProject

Add Controller named HomeController – by right clicking the Controllers folder-> Add-> Controller… (or Ctrl+M,Ctrl+C):

AddingHomeController

Template: Empty MVC controller

Note: Controller names must end with Controller, MVC at the server works with naming conventions.

In HomeController we get a default method of Index():

MvcBasicUrlFormat

Trying to run it will return an error “The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched…”:

MvcErrorNoViewCreated

The method:

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

leads us to the default View of the method named Index. MVC looks for the view Home-Index at a lot of location but doesn’t find it, because it doesn’t exist we get an Error. We have a Controller Home with Index that returns View() – which is the default view for that action.

Another way of thinking about it is: The Controller is C# code, the View is HTML script. The code we have cannot be translated to HTML.

The View method has several overrides:

  • View() – default view: the same name as the method that calls View(), in our case Index
  • View(object) – object that he can shove into the default view as it’s data (in the future it will be the Model)
  • View(IView) – using a custom view object
  • View(IView, object) - using a custom view object with object data
  • View(string) – the value of the string is the name of a different view that will be the View
  • View(string, object) – view name with object data
  • View(string, string) – view name with master name
  • View(string, string, object) - view name with master name and object data

Adding a View is as easy as right clicking the Index method and clicking Add view (or Ctrl+M, Ctrl+V):

BasicMvcAddViewDialog

For now we will uncheck the “Use a layout or master page”, because we don’t have one. The view was added at:

View\Home\Index.cshtml

(the location is a very important part)

Now running the application won’t cause any error. But the View is static, the Controller doesn’t do anything.

Note: CSHTML (the extension of the view file) doesn’t have a built in designer. You can use a designer to build the HTML and just copy paste that to the CSHTML.

 

Passing data from the Controller to the View:

For that we will use a dynamic object named ViewBag that is defined in MVC.

In the Controller writing:

ViewBag.Msg = "Hello";

In the View:

<body>
    <div>
        @ViewBag.Msg
    </div>
</body>

The result is a page displaying Hello.

 

Configuring the default page in MVC:

AppStart\RouteConfig.cs

Contains the code that tell MVC that the default Controller is Home and the default Action is Index:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

The first row just tells the server to ignore all requests with .axd. Because ASP.NET uses urls with .axd extension internally.

The second row tells us what the default url is – Home\Index. it also tells us that it receives an Id and that it is optional.

Note: the Home Controller is the default Controller (it isn’t because we added a Controller named Home, it was like this before hand). And Index is the default action.

 

Passing Id to an Action:

In the Controller:

public ActionResult Test(int? id)
{
    ViewBag.Msg = id.HasValue ? id.Value.ToString() : "Hello test";
    return View("Index");
}

View(“Index”) tells MVC to use the Index view for this action.

Calling from the Browser:

\Home\Test\123

(Better for GET request if you need the extra length of GET)

or

\Home\Test?id=123

Note: Passing something that isn’t an int (like ABC) to Test will be the same as not passing a value, i.e. passing null.

 

What is better Get or Post?

GET wakes the server and does the request at the same time.

  • Limited in it’s length.
  • Security: The talk about being insecure is wrong since POST without encryption is just as insecure as GET (passing a user+password in the url is the same as passing it in POST since using any sniffer you can see the variables, it should be preferred to put it in the url so that it could be fixed).
  • If you can get – GET: Much better at the performance. Google uses GET.

POST calls the server, the server opens a socket, the server returns HTTP 100 response and then start passing the data.

  • Security: Data can be encrypted. But if it doesn’t then just use GET.
  • We used POST in ASP.NET because of the ViewState – just saying “hello” caused the GET data to be filled.
  • Not limited in length

 

MVC with Entity Framework Model

Create a new MVC 4 project with a template of Internet Application:

AddProjectMvcWithInternet

Exercise: changing the default layout:
  • Add a tag of test in the home controller
  • Add a tag of test2 in the WhatEver controller

 

The default layout is configured at _ViewStart.cshtml:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

In Razor the file _ViewStart.cshtml determines what is the default layout. You can define a different layout when adding a view:

MvcChoosingLayout

(what I wrote is the same as leaving it empty, both point to the same file)

The code added will contain the layout specified:

@{
    ViewBag.Title = "Test";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Test</h2>

The code for leaving the text box empty (using the default layout):

@{
    ViewBag.Title = "Test";
}

The code for not checking the checkbox (not using a layout):

@{
    Layout = null;
}

Self study: Partial views.

 

Installing Northwinds DB:

  • Download Northwinds.sql.zip
  • Using SQL Server Management and a SA account add a new database named: Northwind
  • Run the script Northwinds.sql using SQL Server Management and the SA account

     

    Under Model folder add ADO.NET Entity Data Model and connect it to the Northwind DB with:

  • Table: Customers
  • Table: Orders
  • Stored Procedure: CustOrderHist

    Note: it is advised to separate the Model from the ORM (when there are many-to-one or many-to-many relationships a JSON parser might cause an infinite loop, separating it to simple classes without outside relations solves the problem), but for this demo we won’t.

    Reference: AutoMapper that helps mapping between the ORM Model to MVC Model.

     

    Add new controller:

  • Template: MVC controller with read/write actions TODO using EF
  • Model: Customer
  • Data Context NorthwindEntities

    AddMvcControllerWithEF

    Just adding an EF Controller gives out of the box a controller and view for actions such as Index with a list of customers that allows viewing, editing, creating and deleting of rows. Though some of the functionality doesn’t work- for example create.

    For example the Index view looks like this:

    MvcWithEfIndexView

    (clicking on each link passes you to the different views, for example clicking on the first row details the browser redirects to BaseUrl/Customer/Details/ALFKI)

     

    The Create action is divided to two methods:

    GET for a blank page(the default is an attribute of HttpGet):

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

     

    Http Post that after the submit saves the data (it is like in ASP.NET Web Forms PostBack):

    [HttpPost]
    public ActionResult Create(Customer customer)
    {
        if (ModelState.IsValid)
        {
            db.Customers.Add(customer);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(customer);
    }

    ModelState.IsValid makes sure that all the fields are correct by checking the data types and more advanced the Data Annotations of the model: one property below another, one is times two another, checking the data against data in the DB… For all of those there will be a nice validation error shown to the user.

    Reference Data Validation:

  • With UI
  • More on Validations

     

    After submitting the Create form an Error “pops”:

    MvcEfCreateError

    The Create method failed in saving to the DB. It doesn’t work because the view is missing the CustomerID field (which the system “thought” that in the DB that field is Auto Increment – it isn’t!).

    Exercise: Make create work by adding the CustomerID field to the UI.

     

    Side note on Entity Framework:

    NorthwindEntities should inherit from DbContext (and not from ObjectContext)

    public partial class NorthwindEntities : DbContext

    Using ObjectContext means that the entities inherit from ObjectData, are not POCO and has a lot of extra code (like INotifyChanges that WPF loved).

    Yair advised to start from the code and let EF generate the DB (unless you are in good terms with the DBA).

     

     

    Returning JSON results:
    public JsonResult GetCustomersDetail(string term)
    {
        var results = from c in db.Customers
                      where c.CustomerID.StartsWith(term)
                      select new { Id = c.CustomerID, name = c.ContactTitle, other = c.CompanyName};

        return Json(results.ToList(), JsonRequestBehavior.AllowGet);
    }

    JsonRequestBehaviour enum:

  • DenyGet – the default option from a security point view, though using Fiddler you can quite easily see the POST request/response.
  • AllowGet – usually not turning this on causes the system to not work. Just turn it on! 

    Calling it:

    /Customer/GetCustomersDetail?term=a

    JsonNotPretty

    The results can be made more readable using the Chrome Extension JSONView from Developer Tools:

    JsonChromeExtension

    Note: We can’t use /Customer/GetCustomersDetail/a because we want to pass the term parameter not the id parameter.

     

    JSON Syntax:
  • […] array
  • {…} a type
  • Instead of = we use :
  • Commas to separate types/properties

     

    Exercise: Add a text box that creates a combo box of auto complete using a JSON method. Using the event OnChange when 2 seconds pass we will request the data from the server with a GET, receive the data asynchronously, create a type out of the data returned, and set the result in the view as a list items below the TextBox. The only missing information we need is how to make an Ajax call using jQuery.

    The JSON method:

    public JsonResult GetCustomers(string term)
    {
        var results = from c in db.Customers
                      where c.CustomerID.StartsWith(term)
                      select c.CustomerID;

        return Json(results.ToList(), JsonRequestBehavior.AllowGet);
    }

    In the Documentation we will use the following demo as our base:

    $.ajax({
        url: "http://fiddle.jshell.net/favicon.png",
        beforeSend: function (xhr) {
            xhr.overrideMimeType("text/plain; charset=x-user-defined");
        }
    }).done(function (data) {
        if (console && console.log) {
            console.log("Sample of data:", data.slice(0, 100));
        }
    });

    We will change it to:

    $(document).ready(function () {
        $("#btnGetCustomers").click(function () {
            var strUrl = "Customer/GetCustomers?term=" + $("#txtCustomer").val();
            $.ajax({
                url: strUrl,
                beforeSend: function (xhr) {
                    alert("Good Luck");
                }
            }).done(function (data) {
                alert("Done");
            });
        });
    });

    The Body looks like:

    <input id="txtCustomer" />
    <button id="btnGetCustomers">Click Me</button>

    Note: The first example from here show using jQuery Ajax with POST. If you want to use the data parameter you must work with a POST. GET doesn’t know how to work with the data parameter.

    Now lets debug it to see what the data returns.

     

    Debugging JavaScript:

    1. Using IE:

    Add break point in VS2012

    Set the current browser to IE (on the HTML page right click –> Browse With…):

    Vs2012BrowseWith

    Choose Internet Explorer and set it as the default browser.

    And then just start debugging:

    DebuggingJavaScriptIE

    2. Using Chrome F12: Open Sources tab

    When you open it it will be empty simply click on this thingy (“Show navigator”):

    ChromeF12SourcesTab

    Choose the file you want to debug:

    ChromeF12SourcesHtml

    In our case the HTML page and right click to add break points (you might have to refresh the page).

    ChromeDebuggerBreakpoint

     

    Now the only thing left as homework is changing the Done alert to display the results as HTML list items below txtCustomer.

     

    jQuery Tip:

    $(function() {

    is a shortcut to:

    $(document).ready(function () {

     

    jQueryUI

    Instead of doing all that work we will use jQueryUI for AutoComplete.

    You can see at jQueryUI.com an interactive demo of the different Widgets and Effects available at jQueryUI. One of the Widget available is the Autocomplete, you should start by looking at the source code.

    The application has only one important line of code – the input tag:

    <label for="tags">Tags: </label>
    <input id="tags" />

    Note: the for="tags" in the label is a HTML5 effect that when the tags is unavailable the label becomes unavailable as well.

    Updating our Customers example jQuery code to use jQueryUI:

    Step 1: AutoComplete from a constant array (just like the example on the site):

    $(function () {
        var customers = [
          "ActionScript",
          "AppleScript",
          "Asp",
          "BASIC",
        ];
        $("#txtCustomer").autocomplete({
            source: customers
        });

    Running it with “a” and we get:

    jQueryUiAutoCompleteWithoutCss

    Clicking on a list item will cause the text to “Magically” appear in the textbox. But the UI is a bit ugly.

    Looking at the tag in Chrome F12, we see that when we used .autocomplete on our textbox jQueryUI changed our HTML to:

    <input id="txtCustomer" class="ui-autocomplete-input" autocomplete="off" role="textbox"
        aria-autocomplete="list" aria-haspopup="true">
    <ul class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all" role="listbox"
        aria-activedescendant="ui-active-menuitem"
        style="z-index: 1; top: 0px; left: 0px; display: none;"></ul>

    class=”ui-autocomplete-input” - if we used a CSS then the autocomplete would have looked nice

    autocomplete="off" - jQueryUI uses this variable and set it to “on” when it is working, so that when it is on it “knows” not to work.

    When results arrive (for example by entering “a”):

    <ul class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all" role="listbox"
        aria-activedescendant="ui-active-menuitem"
        style="z-index: 1; top: 29.88888931274414px; left: 8.88888931274414px; display: none; width: 136.78472208976746px;">
        <li class="ui-menu-item" role="menuitem">
            <a class="ui-corner-all" tabindex="-1">ActionScript</a>
        </li>
        <li class="ui-menu-item" role="menuitem">
            <a class="ui-corner-all" tabindex="-1">AppleScript</a>
        </li>
        <li class="ui-menu-item" role="menuitem">
            <a class="ui-corner-all" tabindex="-1">Asp</a>
        </li>
        <li class="ui-menu-item" role="menuitem">
            <a class="ui-corner-all" tabindex="-1">BASIC</a>
        </li>
    </ul>

    To add CSS to the application simply drag Content/themes/base/jQuery-Ui.css above the <script> in <head>. When developing a real application you should use just the css that you need, in this case we could have just used Content\themes\base\jquery.ui.autocomplete.css.

    Note: There are tools that analyze your page and give it a score that test you among other things on your CSS usage. For example W3C Validation Service checks for markup validity and helium-css tests for unused CSS classes.

    When using the AutoComplete we only used the source property, but there are others which can be viewed at the documentation.

    If we wanted an event such as search:

    $("#txtCustomer").autocomplete({
        source: customers,
        search: function (event, ui) {
            alert("Go");
        }
    });

    We can also interfere with the regular function by changing the event (for example if we don’t want to allow the user to search for a certain term):

    $("#txtCustomer").autocomplete({
        source: customers,
        search: function (event, ui) {
            event.isDefaultPrevented = true;
        }
    });

    In the source parameter you can pass:

  • an array of values: [ "Choice1", "Choice2" ]
  • an array of objects with value+label pairs: [ { label: "Choice1", value: "value1" }, ... ]
  • a string url to a service with a parameter of term: SomeUrl?term=X that return an array of values or an array of objects with value+label pairs
  • a function that returns the data

     

    So using the JSON action we already defined (how lucky was that Smile):

    $(function () {
        $("#txtCustomer").autocomplete({
            source: "Customer/GetCustomers"
        });

    And the end result:

    jQueryUiAutoCompleteResult

     

     

    Homework:

    1. Use a Textbox AutoComplete with a JSON method that returns an array of objects with value+label pairs

    2. Textbox with AutoComplete with select event that goes to the server and gets data. Then put that control in the existing view.

    3. Two Controllers with a hierarchy: Customer and Orders. Form Order add AutoComplete against Customer.

    4. From Customer add AutoComplete of Orders with select event that opens the Customer