Specializations

Tuesday, September 13, 2016

angularjs basics

Current market with angular js is very good. we need to know some basics about angular js.


CDN URL:



  • Features
Think of your model as the single-source-of-truth for your application. Your model is where you go to to read or update anything in your application.
Data-binding is probably the coolest and most useful feature in AngularJS. It will save you from writing a considerable amount of boilerplate code. A typical web application may contain up to 80% of its code base, dedicated to traversing, manipulating, and listening to the DOM. Data-binding makes this code disappear, so you can focus on your application.
Think of your model as the single-source-of-truth for your application. Your model is where you go to to read or update anything in your application. The data-binding directives provide a projection of your model to the application view. This projection is seamless, and occurs without any effort from you.
Traditionally, when the model changes, the developer is responsible for manually manipulating the DOM elements and attributes to reflect these changes. This is a two-way street. In one direction, the model changes drive change in DOM elements. In the other, DOM element changes necessitate changes in the model. This is further complicated by user interaction, since the developer is then responsible for interpreting the interactions, merging them into a model, and updating the view. This is a very manual and cumbersome process, which becomes difficult to control, as an application grows in size and complexity.
There must be a better way! AngularJS' two-way data-binding handles the synchronization between the DOM and the model, and vice versa.
Here is a simple example, which demonstrates how to bind an input value to an <h1> element.
This is extremely simple to set up, and almost magical…
It's important to realize that at no point does AngularJS manipulate the template as strings. It's all the browser DOM.
In AngularJS, a template is just plain-old-HTML. The HTML vocabulary is extended, to contain instructions on how the model should be projected into the view.
The HTML templates are parsed by the browser into the DOM. The DOM then becomes the input to the AngularJS compiler. AngularJS traverses the DOM template for rendering instructions, which are called directives. Collectively, the directives are responsible for setting up the data-binding for your application view.
It is important to realize that at no point does AngularJS manipulate the template as strings. The input to AngularJS is browser DOM and not an HTML string. The data-bindings are DOM transformations, not string concatenations or innerHTML changes. Using the DOM as the input, rather than strings, is the biggest differentiation AngularJS has from its sibling frameworks. Using the DOM is what allows you to extend the directive vocabulary and build your own directives, or even abstract them into reusable components!
One of the greatest advantages to this approach is that it creates a tight workflow between designers and developers. Designers can mark up their HTML as they normally would, and then developers take the baton and hook in functionality, via bindings with very little effort.
Here is an example where I am using the ng-repeat directive to loop over the images array and populate what is essentially an img template.
It is also worth mentioning, as a side note, that AngularJS does not force you to learn a new syntax or extract your templates from your application.
AngularJS incorporates the basic principles behind the original MVC software design pattern into how it builds client-side web applications.
The MVC or Model-View-Controller pattern means a lot of different things to different people. AngularJS does not implement MVC in the traditional sense, but rather something closer to MVVM (Model-View-ViewModel).
The model is simply the data in the application. The model is just plain old JavaScript objects. There is no need to inherit from framework classes, wrap it in proxy objects, or use special getter/setter methods to access it. The fact that we are dealing with vanilla JavaScript is a really nice feature, which cuts down on the application boilerplate.
viewmodel is an object that provides specific data and methods to maintain specific views.
The viewmodel is the $scope object that lives within the AngularJS application. $scope is just a simple JavaScript object with a small API designed to detect and broadcast changes to its state.
The controller is responsible for setting initial state and augmenting $scope with methods to control behavior. It is worth noting that the controller does not store state and does not interact with remote services.
The view is the HTML that exists after AngularJS has parsed and compiled the HTML to include rendered markup and bindings.
This division creates a solid foundation to architect your application. The $scope has a reference to the data, the controller defines behavior, and the view handles the layout and handing off interaction to thecontroller to respond accordingly.
AngularJS has a built-in dependency injection subsystem that helps the developer by making the application easier to develop, understand, and test.
Dependency Injection (DI) allows you to ask for your dependencies, rather than having to go look for them or make them yourself. Think of it as a way of saying "Hey I need X', and the DI is responsible for creating and providing it for you.
To gain access to core AngularJS services, it is simply a matter of adding that service as a parameter; AngularJS will detect that you need that service and provide an instance for you.
You are also able to define your own custom services and make those available for injection as well.
Directives are my personal favorite feature of AngularJS. Have you ever wished that your browser would do new tricks for you? Well, now it can! This is one of my favorite parts of AngularJS. It is also probably the most challenging aspect of AngularJS.
Directives can be used to create custom HTML tags that serve as new, custom widgets. They can also be used to "decorate" elements with behavior and manipulate DOM attributes in interesting ways.
Here is a simple example of a directive that listens for an event and updates its $scope, accordingly.
Then, you can use this custom directive, like so.
Creating your application as a composition of discrete components makes it incredibly easy to add, update or delete functionality as needed.
The AngularJS team feels very strongly that any code written in JavaScript needs to come with a strong set of tests. They have designed AngularJS with testability in mind, so that it makes testing your AngularJS applications as easy as possible. So there's no excuse for not doing it.
Given the fact that JavaScript is dynamic and interpreted, rather than compiled, it is extremely important for developers to adopt a disciplined mindset for writing tests.
AngularJS is written entirely from the ground up to be testable. It even comes with an end-to-end and unit test runner setup. If you would like to see this in action, go check out the angular-seed project athttps://github.com/angular/angular-seed.
Once you have the seed project, it's a cinch to run the tests against it. Here is what the output looks like:
AngularJS Essentials
The API documentation is full of end-to-end tests that do an incredible job of illustrating how a certain part of the framework should work. After a while, I found myself going straight to the tests to see how something worked, and then maybe reading the rest of the documentation to figure something out.




Example: Syntax of angular js

 <script>
           angular.module('myApp', []).controller('namesCtrl', function ($scope) {
});
</script>


<body ng-app="myApp">



</body>


Example HOW TO PRINT Value using angular js




Example: Syntax of angular js

 <script>
           angular.module('myApp', []).controller('namesCtrl', function ($scope) {
$scope.Message="Hello world";
});
</script>


<body ng-app="myApp">
<div ng-controller="namesCtrl">

{{Message}}

</div>
</body>


Wednesday, August 27, 2014

4-wheeler Ownership Transfer in Bangalore, Karnatka

4-wheeler Ownership Transfer in Bangalore, Karnatka

Hello everybody,
Recently, I got opportunity to interact with Regional Transport Office (RTO) for my car’s ownership transfer. My friends suggested to take help of an agent and get it done but I wasn’t in mood to pay kickbacks, hence I chose to do it my self. I faced bit of difficulty but I overpowered it with patience and persistence. The purpose of writing this blog is to ensure that others are benefitted out of my experience and eventually avoid paying any kickbacks  or bribe to the agents.
In my case, my vehicle was registered under Kormangala, RTO and I’ve to get it registered in Indiranagar RTO.  The ownership transfer process is listed below:
At original RTO, Kormangala:
  1. Get Clearance Certificate and Hypothecation (If the vehicle is on Loan) Cancelled from original RTO. In my case it was Koramangala. You need to produce the following documents.
    1. NOC letter issued from the owner.
    2. Form No. 35 in duplicate(hypothecation cancellation)
    3. Original RC Book.
    4. Self Addressed Clothed Envelope with 12 rs. ticket affixed on it for Local Speed Post.http://www.indiapost.gov.in/netscape/speedpost.html
  2. Next take all the documents to a verifier clerk in office and get it verified. Once verified you have to pay a fee of 100 rs for hypothecation cancellation and attach the chalan with the form. Finally you submit the application.
  3. After 1 week, you will receive the clearance certificate along with your RC book modified.
  4. Next you have to contact the new RTO office where the vehicle has to be registered.
At New RTO, IndiraNagar:
  1. Have following documents ready before you reach to RTO office.
      1. Form no CMV 29 in duplicate.
      2. Form no. CMV 30. If vehicle is covered under Hypothecation/HPA/Lease.
      3. Consent of financier. Original
      4. Registration Certificate(RC) Book. Original.
      5. Valid insurance. Photocopy
      6. Emission Certificate. Photocopy
      7. Address proof ( Ration Card, Voter ID). If you don’t have either of these, get an affidavit for address proof. You’ll find public notary in RTO premise who would endorse your affidavit at a nominal fee.
      8. PAN card . If there is no PAN number form no 61 in case of agriculturists and form no. 60 in case of others.
      9. Clearance Certificate issued by previous registering authority. Original
      10. Two passport size photographs of the transferee.
      11. Self Addressed Clothed Envelope with 12 rs. ticket affixed on it for Local Speed Post.
  2. Next take all the documents to a verifier clerk in office and get it verified. After documents are verified the clerk will redirect you to the next counter where you have to raise the Chalan.
  3. Go to next counter and have chalan raised by entering the details of your RC book in the system.
  4. Got to bill payment counter and pay the amount and obtain the chalan.
  5. Now submit all the documents along with the chalan to verifier clerk once again. Once verifier is done with the verification, he/she will redirect you to form submission counter. You submit all the forms and document and obtain an acknowldegement receipt.  After 1 week, you should receive RC book/Smart card with your name and address in it.
Reference:

Sunday, August 10, 2014

how can we get duration using c#.net

 private int GetDuration(DateTime startDate, DateTime endDate)
        {
            try
            {
                return (int)Math.Round((endDate - startDate).TotalMilliseconds);
            }
            catch (Exception ex)
            {
                ex.ErrorLogger();
                return 0;
            }
        }

How to get CPU Usage and memory Utilization

Use performace Counter for this.


CPU Usage
Prepare PerformanceCounter object.


  Cpuperf.CategoryName = "Processor";
                Cpuperf.CounterName = "% Processor Time";
                Cpuperf.InstanceName = "_Total";
                float first = Cpuperf.NextValue();
 float second= Cpuperf.NextValue();

Note: first value is always 0. So better to take zecond nect value. then it will return the exact value for this.



Memory Utilization:

 PerformanceCounter ramCounterAvailable = new PerformanceCounter("Memory", "Available Bytes");
                PerformanceCounter ramCounterCommitted = new PerformanceCounter("Memory", "Committed Bytes");
                PerformanceCounter ramCounterComitLimit = new PerformanceCounter("Memory", "Commit Limit");
MemoryAvailable = ramCounterAvailable.NextValue();
                MemoryCommitted = ramCounterCommitted.NextValue();
                MemoryComitLimit = ramCounterComitLimit.NextValue();
                var total = MemoryAvailable + MemoryCommitted;
                var MemoryAvailablePercentage = MemoryAvailable / total * 100;
                var MemoryUtilizationPercentage = MemoryCommitted / total * 100;
                second = Cpuperf.NextValue();
                var MemoryUtilizationvalue = (int)Math.Round(MemoryUtilizationPercentage);


Example:
  public void GetCpuAndMemory()
        {
            float second = 0;
            try
            {
PerformanceCounter Cpuperf=new PerformanceCounter();
                PerformanceCounter ramCounterAvailable = new PerformanceCounter("Memory", "Available Bytes");
                PerformanceCounter ramCounterCommitted = new PerformanceCounter("Memory", "Committed Bytes");
                PerformanceCounter ramCounterComitLimit = new PerformanceCounter("Memory", "Commit Limit");

                //Cpuperf = new PerformanceCounter();
                Cpuperf.CategoryName = "Processor";
                Cpuperf.CounterName = "% Processor Time";
                Cpuperf.InstanceName = "_Total";
                float first = Cpuperf.NextValue();
                ramCounterAvailable.NextValue();
                ramCounterCommitted.NextValue();
                ramCounterComitLimit.NextValue();
                var MemoryAvailable = ramCounterAvailable.NextValue();
                var MemoryCommitted = ramCounterCommitted.NextValue();
                var MemoryComitLimit = ramCounterComitLimit.NextValue();
                System.Threading.Thread.Sleep(500);
                MemoryAvailable = ramCounterAvailable.NextValue();
                MemoryCommitted = ramCounterCommitted.NextValue();
                MemoryComitLimit = ramCounterComitLimit.NextValue();
                var total = MemoryAvailable + MemoryCommitted;
                var MemoryAvailablePercentage = MemoryAvailable / total * 100;
                var MemoryUtilizationPercentage = MemoryCommitted / total * 100;
                second = Cpuperf.NextValue();
                var finalCPUusageValue = (int)Math.Round(second);
                var MemoryUtilizationvalue = (int)Math.Round(MemoryUtilizationPercentage);
            }
         
            catch (Exception ex)
            {
             
            }
        }

Friday, May 9, 2014

How to close iframe using javascript + C# script registery

<html>


<head>

<script language="javascript">

function myclose1()
{
window.close();

}


function myclose2()
{
parent.window.close();

}



function myclose3()
{
top.window.close();

}



function myclose4()
{
parent.parentClose();

}

function parentClose()
{
window.close();
}





function myclose1()
{
window.close();

}


</script>

</head>
<body>

<input type="button" value="Close" onclick="myclose1();"/>
<br/>
<input type="button" value="Close" onclick="myclose2();"/>
<br/>
<input type="button" value="Close" onclick="myclose3();"/>
<br/>
<input type="button" value="Close" onclick="myclose4();"/>
<br/>
<input type="button" value="Close" onclick="myclose5();"/>
<br/>
<a href="javascript: window.parent.closeIframe()">Close</a>
<br/>
<a href="window.parent.document.getElementById('theIframe').parentNode.removeChild(window.parent.document.getElementById('theIframe'))">Close</a>
</body>
</html>


C#.net

 string JsScriptValue = "top.window.close();";
           
                 
                ScriptManager.RegisterStartupScript(this, GetType(), "YourUniqueScriptKey", JsScriptValue, true);

Thursday, May 8, 2014

Data table to Excel file using C#.net


     
Data table to Excel file using C#.net

Note: before doing this verify your refernces for  "Microsoft.Office.Interop.Excel.dll".
1) you have to find the Microsoft.Office.Interop.Excel.dll file
2) Microsoft.Office.Interop.Excel.dll refer in your project (or) put this dll in your bin folder
3) Add this below name spacess in your class file.
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

4) Dont open your excel file when you are using to modify through code. Before running this close that excel file. 
5) If file is not exists it will take care to create new file.

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Visual Studio Tools for Office\PIA\Office14

static void Main(string[] args)
        {
            string conString = "server =PRASADPA1 ;User ID=XXXX; Password=XXXXX; database=dbName";
            SqlConnection sqlCon = new SqlConnection(conString);
            sqlCon.Open();
            DataSet ds = new DataSet();
            SqlDataAdapter da1 = new SqlDataAdapter("Exec TestSP", sqlCon);
         
            da1.Fill(ds);

            SqlDataAdapter da = new SqlDataAdapter("SELECT * from PecerTestTable", sqlCon);
            System.Data.DataTable dtMainSQLData = new System.Data.DataTable();
            da.Fill(dtMainSQLData);
           // ExportToExcel(dtMainSQLData, @"c:\test456.xls");

            DataColumnCollection dcCollection = dtMainSQLData.Columns;
            // Export Data into EXCEL Sheet
            Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new
            Microsoft.Office.Interop.Excel.ApplicationClass();
            ExcelApp.Application.Workbooks.Add(Type.Missing);


            // ExcelApp.Cells.CopyFromRecordset(objRS);
            for (int i = 1; i < dtMainSQLData.Rows.Count + 2; i++)
            {
                for (int j = 1; j < dtMainSQLData.Columns.Count + 1; j++)
                {
                    if (i == 1)
                    {
                        ExcelApp.Cells[i, j] = dcCollection[j - 1].ToString();
                    }
                    else
                        ExcelApp.Cells[i, j] = dtMainSQLData.Rows[i - 2][j - 1].ToString();
                }
            }

            ExcelApp.ActiveWorkbook.SaveCopyAs(@"C:\test1b.xls");

         
            foreach (System.Data.DataTable dt in ds.Tables)
            {
                AddWorksheetToExcelWorkbook(@"C:\test1b.xls",dt.TableName, dt);
            }
         
        }
        private static void AddWorksheetToExcelWorkbook(string fullFilename, string worksheetName, System.Data.DataTable dtMainSQLData)
        {
            Microsoft.Office.Interop.Excel.Application xlApp = null;
            Workbook xlWorkbook = null;
            Sheets xlSheets = null;
            Worksheet xlNewSheet = null;

            try
            {
                xlApp = new Microsoft.Office.Interop.Excel.Application();

                if (xlApp == null)
                    return;

                // Uncomment the line below if you want to see what's happening in Excel
                // xlApp.Visible = true;

                xlWorkbook = xlApp.Workbooks.Open(fullFilename, 0, false, 5, "", "",
                        false, XlPlatform.xlWindows, "",
                        true, false, 0, true, false, false);

                xlSheets = xlWorkbook.Sheets as Sheets;

                // The first argument below inserts the new worksheet as the first one
                xlNewSheet = (Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
                xlNewSheet.Name = worksheetName;
                DataColumnCollection dcCollection = dtMainSQLData.Columns;
                for (int i = 1; i < dtMainSQLData.Rows.Count + 2; i++)
                {
                    for (int j = 1; j < dtMainSQLData.Columns.Count + 1; j++)
                    {
                        if (i == 1)
                        {
                            xlNewSheet.Cells[i, j] = dcCollection[j - 1].ToString();
                        }
                        else
                            xlNewSheet.Cells[i, j] = dtMainSQLData.Rows[i - 2][j - 1].ToString();
                    }
                }
             

                xlWorkbook.Save();
                xlWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
                xlApp.Quit();
            }
            finally
            {
                Marshal.ReleaseComObject(xlNewSheet);
                Marshal.ReleaseComObject(xlSheets);
                Marshal.ReleaseComObject(xlWorkbook);
                Marshal.ReleaseComObject(xlApp);
                xlApp = null;
            }
        }

Tuesday, March 4, 2014

ASP.NET MVC and KnockoutJS

In our Getting Started with KnockoutJS in ASP.NET MVC article, we started off with the intention of weaning web client devs away from hacking up the DOM and using client side ViewModels with Knockout as much as possible. We got some good questions regarding the article of which the main ones are:
1. Why do we have to get the empty View using the Get Action method and then do a second HTTP Get using AJAX after Document load to get the actual data? We’ll see one of the ways to avoid the second Get.
2. Why are we using jQuery’s $(element).on(…) to assign click handlers instead of having the click handler functions in the ViewModel itself. Well we can, so we’ll see how to do so.
3. Why did we disable AntiForgeryToken? Do we really need to make our code ‘insecure’ to use JavaScript based clients? Nope, we don’t have to make our code ‘insecure’, we’ll see how we can put the AntiForgeryToken back and use it to validate input.
Finally we’ll see how we can avoid manual mapping between the Server side ViewModel and Client Side ViewModel.
We start off with the code from the first article so you can download the code or fork the code on GithubThis article has been written by Sumit Maitra and I. 

Avoid doing a second AJAX GET to get Data as JSON

On way to send data to Client as JSON from the server is to serialize the Data as a JSON string, stick it in a ViewModel property and bind it to an HTML element (like a Hidden Field) or use Razor syntax to include the data in a Hidden field directly.
We’ll use the second technique today.

Changes in LookupsController

We update the Index action method to pass the list of Lookups into the ViewResult.
public ActionResult Index()
{
    return View(db.Lookups.ToList());
}
Just to ensure that we are not calling old code by mistake, we’ll comment out the GetIndex Action method too.

Updating the Index View

We put back the Model declaration on top of the View and add the Hidden Input variable that will save the JSON serialized Model.
@model IEnumerable<KnockoutSamples.Models.Lookup><title>Index</title>
<h2>Index</h2>
<input type="hidden" id="serverJSON"
value="@Newtonsoft.Json.JsonConvert.SerializeObject(Model)" />
<!-- rest of the markup -->
If you went through the first article carefully, you’ll realize this works because all Razor syntax is evaluated on the server when generating final HTML markup that’s sent back to the Browser. So here the @Newtonsoft.Json.JsonConvert.SerializeObject will be evaluated on the server for the data that we passed into the View(…) function in the Index Action method. So value of the hidden field will essentially end up with a long JSON string.

Updating the JavaScript to use the Hidden Field as the Data Source

We update the $(document).ready function to retrieve the data object from the Hidden Field instead of a AJAX call to the server. I’ve kept the code that we remove as commented and highlighted in gray. The code to convert the JSON string to JS object is highlighted in Yellow. Note the rest of the code remains the same.
$(document).ready(function () {
 //$.ajax({
//    type: "GET",
//    url: "/Lookups/GetIndex",
//}).done(function (data) {

var data = JSON.parse($("#serverJSON").val());$(data).each(function (index, element) {
  var mappedItem =
  {
   Id: ko.observable(element.Id),
   Key: ko.observable(element.Key),
   Value: ko.observable(element.Value),
   Mode: ko.observable("display")
  };
  viewModel.lookupCollection.push(mappedItem);
});
ko.applyBindings(viewModel);
 //}).error(function (ex) {
//    alert("Error");
//});

//… Rest of the code
}
With that we are all done, if we run the application now, we’ll see the three default items come up in the Index.
If you run F12 dev tools, you’ll see that there is only one AJAX Get that’s made by Visual Studio’s browser link tech by the injected SignalR code.
knockout-ajax-get-server-side

Handling Edit, Update, Delete in ViewModel functions rather than external Event handlers

There were some protestations on why were we using jQuery ‘On’ function to attach Click event handlers for Edit, Delete etc. and it was suggested that we add the functions to the View Model and be done with it.
To Use KO View Model functions, we need to declare two more functions in the ViewModel. As you can see below, we’ve added two functions Edit and Update. KO automatically passes the data in current context, so we don’t have to extract it using ko.dataFor. The rest of the implementation is copied over from the older event handler.
$(data).each(function (index, element) {
var mappedItem =
{
  Id: ko.observable(element.Id),
  Key: ko.observable(element.Key),
  Value: ko.observable(element.Value),
  Mode: ko.observable("display"),
  Edit: function (current) {
   //var current = ko.dataFor(this);
   current.Mode("edit");
  },
  Update: function (current) {
   //var current = ko.dataFor(this);
   saveData(current);
   current.Mode("display");
  }
};
viewModel.lookupCollection.push(mappedItem);
});

Binding the Button Click handlers

We now have functions to handle the events but we need to assign them to the respective button’s click events. Since the new methods are a part of the View Model, we’ll use KO’s click binding in the markup.
The Edit Button:
<button class="btn btn-success kout-edit" data-bind="click: Edit">Edit</button>
The Update Button:
<button class="btn btn-success kout-update" data-bind="click: Update">Update</button>
If you run the app now, things will work as before. Pretty neat and doesn’t seem to be a troublemaker, so let’s keep it as is and go ahead!

Getting the Anti Forgery token back

We have covered what Anti Forgery tokens are and how they help prevent CSRF attacks here. We also saw how to use it in Web API services. So lets see how we can continue using it in our KO based app.
1. First we restore the AntiForgeryToken Razor syntax in the Index.cshtml. We add the following at the top of the page just below the @model declaration.
@Html.AntiForgeryToken()
This simply adds a Hidden field to the final HTML page.
2. Next we enable the Token Verification on the Controller method, so we uncomment the highlighted line below in the LookupsController
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Lookup lookup)
{
if (ModelState.IsValid)
{
  db.Entry(lookup).State = EntityState.Modified;
  db.SaveChanges();
  return Json(lookup.Id);
}
return View(lookup);
}
3. If we try submitting now, we’ll get the AntiForgeryToken validation failed error. So finally, we update the saveData function in the knockout.samples.js. We make three simple changes:
a. Add the __RequestVerificationToken to the JS object that we are submitting on Save. The property name is so because that’s what MVC looks for in the submitted form and that also happens to be the name of the hidden field in which it is stored.
b. Change contentType to from-url-encoded
c. And finally since we are sending a url-encoded form, so we no longer JSON.stringify submitData and send the JavaScript object instead
function saveData(currentData) {
var postUrl = "";
var submitData = {
  Id: currentData.Id(),
  Key: currentData.Key(),
  Value: currentData.Value(),
  __RequestVerificationToken: $("input[name='__RequestVerificationToken']").val()
};
if (currentData.Id && currentData.Id() > 0) {
  postUrl = "/Lookups/Edit";
}
else {
  postUrl = "/Lookups/Create";
}
$.ajax({
  type: "POST",
  contentType: "application/x-www-form-urlencoded",
  url: postUrl,
  data: submitData
}).done(function (id) {
  currentData.Id(id);
}).error(function (ex) {
  alert("ERROR Saving");
})
}
Okay, that’s three different questions solved and a different perspective towards using KO achieved.

Conclusion

Today we revisited some of the questions that rose in our previous article and explored some alternate techniques when using Knockout JS and ASP.NET MVC. We also saw how we could secure our application using the AntiForgery Token that we had ignored previously. In the next part of the series, we’ll step it up and learn more techniques using Knockout JS in near production scenarios.