Monday, July 29, 2019

JQuery Ajax With Class Arrays

OK, I took some flack from a buddy of mine who is starting JQuery about my AJAX samples.  AJAX with JQuery is all fun and games until you start passing complex data (apparently).  So here is a quick demo of how to call a web method that returns a list of custom objects via JQuery.Ajax ($.ajax).
Starting off with the class we are going to return:
   1: public class Customer
   2: {
   3:     public int ID { get; set; }
   4:     public string Name { get; set; }
   5:     public string Company { get; set; }
   6:     public string StartDate { get; set; }
   7: }
Now the web method that returns the data:
   1: [System.Web.Script.Services.ScriptService]
   2: public class CustomerService : System.Web.Services.WebService
   3: {
   4:     [WebMethod]
   5:     public List<Customer> GetCustomers()
   6:     {
   7:         var list = new List<Customer>
   8:                        {
   9:                            new Customer { ID =1, Name = "Chris Brandsma", Company="Company 1", StartDate = new DateTime(2004, 3, 14).ToShortDateString()},
  10:                            new Customer { ID =2, Name = "Jason Grundy", Company="Company 2", StartDate = new DateTime(2005, 1, 1).ToShortDateString()},
  11:                            new Customer { ID =3, Name = "Scott Nickols", Company="Company 3", StartDate = new DateTime(2007, 7, 1).ToShortDateString()},
  12:                            new Customer { ID =4, Name = "Tony Rasa", Company="Company 4", StartDate = new DateTime(2009, 6, 14).ToShortDateString()},
  13:                        };
  14:         return list;
  15:     }
  16: }
So far nothing really special here.  Standard web method.  I uncommented the ScriptService attribute on the class to allow for JSON style results, just like I always do.  And I’m returning data.
Ok, on think you might have noticed: StartDate is a string – not a DateTime.  This is because DateTime gets converted to “DATE(1231231231231)” when passed to the browser.  Now I could parse that out using JavaScript and regular expressions, but I find it is much easier to just convert the date to a string that I want to look at in the first place.  If you think I am wacked, read Dave Ward.
Next I am going to load the data into a table in the most raw way I know how.  First the table:
   1: <table id="CustomerTable">
   2:     <thead><tr>
   3:         <td>ID</td>
   4:         <td>Name</td>
   5:         <td>Company</td>
   6:         <td>Start Date</td>
   7:         </tr>
   8:      </thead>
   9:     <tbody>
  10:     </tbody>
  11: </table>
That table just defines the bare structure of the table for us to load into.   Now to call the web method and then  load it into the table:
   1: function GetCustomerList() {
   2:     $.ajax({
   3:         type: "POST",
   4:         url: "CustomerService.asmx/GetCustomers",
   5:         data: "{}",
   6:         contentType: "application/json; charset=utf-8",
   7:         dataType: "json",
   8:         success: function(data) { LoadCustomers(data.d); },
   9:         failure: function() { alert("Sorry, we were unable to find the customers."); }
  10:     });
  11: }
The url is the relative url.  So in this case my page is in the same directory as my web service (CustomerService.asmx).  Then, in success, I take the data (data.d because Microsoft AJAX calls wrap everything in d for security purposes) and send the to LoadCustomers:
   1: function LoadCustomers(data) {
   2:     var tbody = $("#CustomerTable > tbody").html("");
   3:     
   4:     for (var i in data) {
   5:         var customer = data[i];
   6:  
   7:         var rowText = "<tr><td>" + customer.ID + "</td><td>" + customer.Name + "</td><td>" + customer.Company + "</td><td>" + customer.StartDate + "</td></tr>";
   8:         $(rowText).appendTo(tbody);
   9:     }
  10: }    
When I was talking about raw JQuery, I was really talking about the LoadCustomers method.  Here I am creating a table row as a string by hand, handing that to JQuery to load, the appending it to the table’s tbody.
Finally we call the method when the page loads:
   1: $(document).ready(function() {
   2:     GetCustomerList();
   3: });
Now complete, my table (as defined above) ends up looking like this:
   1: <table id="CustomerTable">
   2:    <thead><tr>
   3:             <td>ID</td>
   4:             <td>Name</td>
   5:             <td>Company</td>
   6:             <td>Start Date</td>
   7:             </tr>
   8:    </thead>
   9:    <tbody>
  10:      <tr><td>1</td><td>Chris Brandsma</td><td>Company 1</td><td>3/14/2004</td></tr>
  11:      <tr><td>2</td><td>Jason Grundy</td><td>Company 2</td><td>1/1/2005</td></tr>
  12:      <tr><td>3</td><td>Scott Nickols</td><td>Company 3</td><td>7/1/2007</td></tr>
  13:      <tr><td>4</td><td>Tony Rasa</td><td>Company 4</td><td>6/14/2009</td></tr>
  14:    </tbody>
  15:  </table>
Note: I reformatted the html to look nice.  Otherwise, everything between the tbody tags would have been in one long string.

c# Function CalculateYourAge

  1. public static string CalculateYourAge(DateTime Dob)    
  2.        {    
  3.            DateTime Now = DateTime.Now;    
  4.            int _Years = new DateTime(DateTime.Now.Subtract(Dob).Ticks).Year - 1;    
  5.            DateTime _DOBDateNow = Dob.AddYears(_Years);    
  6.            int _Months = 0;    
  7.            for (int i = 1; i <= 12; i++)    
  8.            {    
  9.                if (_DOBDateNow.AddMonths(i) == Now)    
  10.                {    
  11.                    _Months = i;    
  12.                    break;    
  13.                }    
  14.                else if (_DOBDateNow.AddMonths(i) >= Now)    
  15.                {    
  16.                    _Months = i - 1;    
  17.                    break;    
  18.                }    
  19.            }    
  20.            int Days = Now.Subtract(_DOBDateNow.AddMonths(_Months)).Days;      
  21.                
  22.            return $"Age is {_Years} Years {_Months} Months {Days} Days";    
  23.        }   

Monday, July 22, 2019

The Name BundleConfig Does Not Exist in the Current Context

สรุป
 - เพิ่ม  BundleConfig.RegisterBundles(BundleTable.Bundles); ใน    file Global.asax
 - เพิ่ม using System.Web.Optimization; 


Given that there are currently no results on The Web that give a good answer to the following error, I thought I’d help out and supply the information.
The error is…
“The name ‘BundleConfig’ does not exist in the current context”
Usually this means you have the following line of code in your Global.asax.cs file, perhaps in an ASP.NET MVC project.
BundleConfig.RegisterBundles(BundleTable.Bundles);
There are two possible reasons for this error.

Namespace

The most obvious and easy to fix error will be that when you added your App_Start/BundleConfig class, Visual Studio put in the namespace YourApp/App_Start namespace. All of the other App_Start classes will be in the YourApp namespace. So go edit:
namespace YourApp.App_Start
{
    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            //...
And change it to:
namespace YourApp
{
    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            //...

Optimization Package

The second most obvious reason will be that you don’t have the System.Web.Optimization assembly.
To fix this, right-click on your solution, click on “Manage NuGet packages for solution” and search for…
Microsoft ASP.NET Web Optimization Framework
Then just install the package and you’re good to go.