Saturday, October 29, 2016

XML parsing: line 1, character 38, unable to switch the encoding

Hello all,
Given the task at hand that your going to insert XML data into an XML column in SQL Server and you encounter this error "XML parsing: line 1, character 38, unable to switch the encoding", it seems the insertion of XML data failed due to this line here: <?xml version="1.0" encoding="utf-8" ?>. After doing some research, I found a tutorial on how to avoid unicode issues when inserting XML data into an XML column in SQL Server which is the basis of the solution. I just change the Encoding of the stream to UTF8 to match the encoding of the XML file.
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
 SqlCommand command = new SqlCommand("Insert into XMLTable(name, xmlData) values (@name, @xmlData)", con);
 con.Open();

 string xmlFile = File.ReadAllText(location);

 using (MemoryStream stream = new MemoryStream())
 {
  using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) 
  {
   writer.Write(xmlFile);
   writer.Flush();
   stream.Position = 0;

   SqlParameter parameter = new SqlParameter("@xmlData", SqlDbType.Text);
   parameter.Value = new SqlXml(stream);
   command.Parameters.Add("@name", SqlDbType.VarChar).Value = "Products.xml";
   command.Parameters.Add(parameter);
   command.ExecuteNonQuery();
  }
 }
}
Reference: Avoiding Unicode issues when inserting XML into a SQL Database

Wednesday, October 26, 2016

Seed Roles and Users to an existing database in ASP.NET MVC 5 using Identity

Hello,

In this tutorial, I will demonstrate seeding roles and users to an existing database in an ASP.NET MVC 5 application using Identity framework. For simplicity, I will use a Northwind. This database doesn't have membership tables at all.
To begin with, accomplish the steps below:
1. Create an ASP.NET MVC application and then change web.config connectionStrings element to connect to an existing database (Northwind as my example).
2. Under Package Manager Console type
PM> Enable-Migrations
3. Under Package Manager Console type
PM> Add-Migration ASPMembership
* This will create a file Timespan_ASPMembership.cs inside Migrations folder with scripts to create Membership Tables such as AspNetUsers, AspNetRoles and etc.
4. Under Package Manager Console type
PM> Update-Database
* This will add membership tables to Northwind database.
5. To seed Roles and Users, create a class SeedRolesAndUsers.cs inside Models folder. This class references Microsoft.AspNet.Identity and Microsoft.AspNet.Identity.EntityFramework namespaces. The code below adds Customer or Manager role if they didn't exist. And then the remaining part of the code, creates a user assigned to a specific role.
public class SeedRolesAndUsers
    {        
        protected static void Seed(ApplicationDbContext context)
        {
            var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
            var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

            if (!roleManager.RoleExists("Customer"))
            {
                var roleresult = roleManager.Create(new IdentityRole("Customer"));
            }
            if (!roleManager.RoleExists("Manager"))
            {
                var roleresult = roleManager.Create(new IdentityRole("Manager"));
            }

            string userName = "jimmymgr01";
            string password = "jimmymgr01";
            ApplicationUser user = userManager.FindByName(userName);
            if (user == null)
            {
                user = new ApplicationUser()
                {
                    UserName = userName
                };

                IdentityResult userResult = userManager.Create(user, password);
                if (userResult.Succeeded)
                {
                    var result = userManager.AddToRole(user.Id, "Manager");
                }
            }
        }
    }
6. In Global.asax.cs, call the seed method and then pass an ApplicationDBContext object to it's parameter.
 protected void Application_Start()
    {
         AreaRegistration.RegisterAllAreas();
         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
         RouteConfig.RegisterRoutes(RouteTable.Routes);
         BundleConfig.RegisterBundles(BundleTable.Bundles);
   
   //call seed method
         ApplicationDbContext context = new ApplicationDbContext();
         SeedRolesAndUsers.Seed(context);
    }
7. Run the application. You should see the tables AspNetRoles, AspNetUsers, AspNetUserRoles populated with data.
VB.NET Version of this tutorial: Seed Roles and Users to an existing database in ASP.NET MVC 5 using Identity

Monday, October 24, 2016

The term 'Enable-Migrations' is not recognized as the name of a cmdlet

Hello,

When I started creating an ASP.NET MVC application in VB.NET and decided to add Membership tables using the Enable-Migrations command in Package Manager Console, I encountered this error 'The term 'Enable-Migrations' is not recognized as the name of a cmdlet'. In C#, I haven't encountered this issue. So, what I did was to Rebuild the project, and then restart Visual Studio IDE.
Eureka,the problem was fixed. :-)
Cheers! :)

Set WPF DataGridCell and DataGridRow color using Triggers

Hi,

There was a question on the forums on how to set the color of DataGridCell or DataGridRow using XAML without code. I always thought that the solution will be to use code using IValueConverter. After doing some searching on MSDN and google, the answer is straightforward using Triggers. To set the color of DataGridRow, you set the DataGrid.CellStyle just below the DataGrid markup.
<DataGrid Grid.Row="0" Grid.Column="0" AutoGenerateColumns="False" CanUserAddRows="False"  Name="dgStudents">
 <DataGrid.CellStyle>
  <Style TargetType="{x:Type DataGridCell}">
   <Style.Triggers>
    <DataTrigger Binding="{Binding Age}" Value="28">
     <Setter Property="Background" Value="Gray"></Setter>
    </DataTrigger>
   </Style.Triggers>
  </Style>
 </DataGrid.CellStyle>
 <DataGrid.Columns>               
  <DataGridTextColumn Header="ID" Binding="{Binding Path=ID}" Width="120" IsReadOnly="True" />
  <DataGridTextColumn Header="Age" Binding="{Binding Path=Age}" MinWidth="100" IsReadOnly="True" />
  <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" MinWidth="150" IsReadOnly="True" />
  <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}" MinWidth="150" IsReadOnly="True" />
 </DataGrid.Columns>
</DataGrid>
To set the DataGridCell color, you need to apply the Style of a specific column such as DataGridTextColumn.
<DataGrid Grid.Row="0" Grid.Column="0" AutoGenerateColumns="False" CanUserAddRows="False"  Name="dgStudents">
 <DataGrid.Columns>               
  <DataGridTextColumn Header="ID" Binding="{Binding Path=ID}" Width="120" IsReadOnly="True" />
  <DataGridTextColumn Header="Age" Binding="{Binding Path=Age}" MinWidth="100" IsReadOnly="True">
   <DataGridTextColumn.CellStyle>
    <Style TargetType="DataGridCell">
     <Style.Triggers>
      <DataTrigger Binding="{Binding Path=Age}" Value="28">
       <Setter Property="Background" Value="Gray"/>
      </DataTrigger>
     </Style.Triggers>
    </Style>
   </DataGridTextColumn.CellStyle>
  </DataGridTextColumn>
  <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" MinWidth="150" IsReadOnly="True" />
  <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}" MinWidth="150" IsReadOnly="True" />
 </DataGrid.Columns>
</DataGrid>
Note: Both markups will set the color of the row and cell based from the value of Age which is 28.

Thursday, October 20, 2016

@Html.EnumDropDownListFor() with Html Attributes

Hello,
I did some research on how to use enums as model for DropDownListFor() for a current application and will format it with Bootstrap classes. For ASP.NET MVC 4, it does not have that kind of helper yet. Luckily, I found an article here Creating a DropDownList helper for enums which supports enums as data source. However, it does not have an argument where in you can pass a boostrap class such as form-control. To achieve the desired output, all you need to do is modify the helper and add another parameter for html attributes which will then be used by the DropDownListFor().
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, 
 Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
 ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
 IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum)).Cast<TEnum>();

 IEnumerable<SelectListItem> items = values.Select(value => new SelectListItem
          {
           Text = value.ToString(),
           Value = value.ToString(),
           Selected = value.Equals(metadata.Model)
          });

 return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}

Thanks to the author of this extension. :-)

Monday, October 17, 2016

Model binding with ASP.NET MVC @Html.ListBoxFor().

Hi,

In this tutorial, I will present three ways on model binding with the @Html.ListBoxFor() helper using a ViewModel class and a simple model class. The Index view below has three @Html.ListBoxFor() controls inside a form that will be populated with different ways using MultiSelectList class, List<SelectListItem>, and IEnumerable<CountryInfo>.
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
 <div class="form-group">
  <div class="form-group">
   @Html.ListBoxFor(x => x.SelectedPhoneNumbers, Model.phoneNumbers, new { @class = "form-control " })
  </div>
  <div class="form-group">
   @Html.ListBoxFor(x => x.SelectedItemIds, Model.Items, new { @class = "form-control " })
  </div>
  <div class="form-group">
   @Html.ListBoxFor(x => x.Country.SelectedCountry, new MultiSelectList(Model.Country.Countries, "Code", "Text"), new { @class = "form-control " })

  </div>
 </div>
 <button id="btnRegisterSubmit" type="submit" class="btn btn-primary">Register</button>
}
Given the model (Country.cs) and ViewModel (MyViewModel.cs) classes below:
public class Country
{
     public IEnumerable<CountryInfo> Countries { get; set; }
     public IEnumerable<string> SelectedCountry { get; set; }
}

public struct CountryInfo
{
 public int Code { get; set; }
 public string Text { get; set; }
}

public class MyViewModel
{
 public int[] SelectedItemIds { get; set; }
 public MultiSelectList Items { get; set; }
 public string[] SelectedPhoneNumbers { get; set; }
 public List<SelectListItem> phoneNumbers { get; set; }
 public Country Country { get; set; }
}
In the controller method, populate the ViewModel properties with dummy records. Make sure to reference the Models folder so you can access the ViewModel class. I also added comments to each property with their associated ListBox control.
public ActionResult Index()
{
 var model = new MyViewModel
 {
                // @Html.ListBoxFor(x => x.SelectedItemIds, Model.Items, new { @class = "form-control " })
  Items = new MultiSelectList(new[] {    
    new { Id = 1, Name = "item 1" },
    new { Id = 2, Name = "item 2" },
    new { Id = 3, Name = "item 3" },
   }, "Id", "Name", null     
  ),
                // @Html.ListBoxFor(x => x.SelectedPhoneNumbers, Model.phoneNumbers, new { @class = "form-control " })
  phoneNumbers = new List<SelectListItem>()
  {
   new SelectListItem(){ Text ="312-4455", Value="1", Selected= false},
   new SelectListItem(){ Text ="255-5035", Value="2", Selected= false},
   new SelectListItem(){ Text ="253-3441", Value="3", Selected= true},
   new SelectListItem(){ Text ="262-1111", Value="4", Selected= false}
  },
                // @Html.ListBoxFor(x => x.Country.SelectedCountry, new MultiSelectList(Model.Country.Countries, "Code", "Text"), new { @class = "form-control " })
  Country = new Country()
  {
   Countries = new List<CountryInfo>(){
      new CountryInfo{ Code = 1001, Text = "USA"},
      new CountryInfo{ Code = 1002, Text = "United Kingdom"}
    },
   SelectedCountry = new List<string>()
  }
 };

 return View(model);
}

Screenshot

Friday, October 14, 2016

Read or Parse JSON using JavaScriptSerializer class

Hello,
Here's a simple demonstration on how to parse JSON data using .NET's JavaScriptSerializer class. Given the sample JSON data below:
{
  "catalog": {
    "book": [
      {
        "id": "bk101",
        "author": "Gambardella, Matthew",
        "title": "XML Developer's Guide",
        "genre": "Computer",
        "price": "44.95",
        "publish_date": "2000-10-01",
        "description": "An in-depth look at creating applications 
      with XML."
      },
      {
        "id": "bk102",
        "author": "Ralls, Kim",
        "title": "Midnight Rain",
        "genre": "Fantasy",
        "price": "5.95",
        "publish_date": "2000-12-16",
        "description": "A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world."
      },
      {
        "id": "bk103",
        "author": "Corets, Eva",
        "title": "Maeve Ascendant",
        "genre": "Fantasy",
        "price": "5.95",
        "publish_date": "2000-11-17",
        "description": "After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society."
      },
      {
        "id": "bk104",
        "author": "Corets, Eva",
        "title": "Oberon's Legacy",
        "genre": "Fantasy",
        "price": "5.95",
        "publish_date": "2001-03-10",
        "description": "In post-apocalypse England, the mysterious 
      agent known only as Oberon helps to create a new life 
      for the inhabitants of London. Sequel to Maeve 
      Ascendant."
      },
      {
        "id": "bk105",
        "author": "Corets, Eva",
        "title": "The Sundered Grail",
        "genre": "Fantasy",
        "price": "5.95",
        "publish_date": "2001-09-10",
        "description": "The two daughters of Maeve, half-sisters, 
      battle one another for control of England. Sequel to 
      Oberon's Legacy."
      },
      {
        "id": "bk106",
        "author": "Randall, Cynthia",
        "title": "Lover Birds",
        "genre": "Romance",
        "price": "4.95",
        "publish_date": "2000-09-02",
        "description": "When Carla meets Paul at an ornithology 
      conference, tempers fly as feathers get ruffled."
      },
      {
        "id": "bk107",
        "author": "Thurman, Paula",
        "title": "Splish Splash",
        "genre": "Romance",
        "price": "4.95",
        "publish_date": "2000-11-02",
        "description": "A deep sea diver finds true love twenty 
      thousand leagues beneath the sea."
      },
      {
        "id": "bk108",
        "author": "Knorr, Stefan",
        "title": "Creepy Crawlies",
        "genre": "Horror",
        "price": "4.95",
        "publish_date": "2000-12-06",
        "description": "An anthology of horror stories about roaches,
      centipedes, scorpions  and other insects."
      },
      {
        "id": "bk109",
        "author": "Kress, Peter",
        "title": "Paradox Lost",
        "genre": "Science Fiction",
        "price": "6.95",
        "publish_date": "2000-11-02",
        "description": "After an inadvertant trip through a Heisenberg
      Uncertainty Device, James Salway discovers the problems 
      of being quantum."
      },
      {
        "id": "bk110",
        "author": "O'Brien, Tim",
        "title": "Microsoft .NET: The Programming Bible",
        "genre": "Computer",
        "price": "36.95",
        "publish_date": "2000-12-09",
        "description": "Microsoft's .NET initiative is explored in 
      detail in this deep programmer's reference."
      },
      {
        "id": "bk111",
        "author": "O'Brien, Tim",
        "title": "MSXML3: A Comprehensive Guide",
        "genre": "Computer",
        "price": "36.95",
        "publish_date": "2000-12-01",
        "description": "The Microsoft MSXML3 parser is covered in 
      detail, with attention to XML DOM interfaces, XSLT processing, 
      SAX and more."
      },
      {
        "id": "bk112",
        "author": "Galos, Mike",
        "title": "Visual Studio 7: A Comprehensive Guide",
        "genre": "Computer",
        "price": "49.95",
        "publish_date": "2001-04-16",
        "description": "Microsoft Visual Studio 7 is explored in depth,
      looking at how Visual Basic, Visual C++, C#, and ASP+ are 
      integrated into a comprehensive development 
      environment."
      }
    ]
  }
}
I have created a model class that handles the deserialization of the JSON data into a C# object.
public class Book
{
 public string id { get; set; }
 public string author { get; set; }
 public string title { get; set; }
 public string genre { get; set; }
 public string price { get; set; }
 public string publish_date { get; set; }
 public string description { get; set; }
}

public class Catalog
{
 public List<Book> book { get; set; }
}

public class RootObject
{
 public Catalog catalog { get; set; }
}
Given the model class and the JSON data, the function below will read the JSON using StreamReader and will deserialize it using the Deserialize() method of the JavaScriptSerializer object.
private static void ReadBooks()
{
 string executableLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
 string xslLocation = Path.Combine(executableLocation, "books.json");
 RootObject objBooks = new RootObject();

 using (var reader = new StreamReader(xslLocation))
 {
  var responseBody = reader.ReadToEnd();
  var deserializer = new JavaScriptSerializer();
  objBooks = deserializer.Deserialize<RootObject>(responseBody);
 }

 foreach (var item in objBooks.catalog.book)
 {
  Console.WriteLine("id: {0} \nauthor: {1} \ntitle: {2} \ngenre:{3} \nprice:{4} \npublish date: {5} \ndescription:{6}",
      item.id, item.author, item.title, item.genre, item.price, item.publish_date, item.description);
  Console.WriteLine("================================");
 }
}

Thursday, October 13, 2016

Return View() statement not redirecting to View in ASP.NET MVC using $.ajax() post.

Hello,
Normally, you submit client-side data to a controller action via @Html.BeginForm(), then perform processing statements and lastly invoke the return View(); statement inside the controller action which will redirect you to the view which basically works.

However, in a scenario where-in you will post data to a controller action using jQuery Control Event such as Button Click, the return View() statement in the controller action won't redirect to the specified view given the sample controller action below.
[HttpPost]
public ActionResult UpdatedEmpTrainings(string empId)
{
 _context = new EmployeeEntities();
 model = new List<EmployeeTrainingsViewModel>();
 model = (from emp_trainings in _context.EmployeeTrainings.AsEnumerable()
    join training in _context.Trainings.AsEnumerable()
     on emp_trainings.TrainingID equals training.TrainingID
    where emp_trainings.EmployeeID == Convert.ToInt32(empId)
    select new EmployeeTrainingsViewModel
    {
     TrainingID = emp_trainings.TrainingID.GetValueOrDefault(),
     TrainingTitle = training.TrainingTitle,
     EmployeeID = emp_trainings.EmployeeID.GetValueOrDefault()
    }).OrderBy(t => t.TrainingID).ToList();

 return View(model);
}
So, to resolve the issue in order for the return View() statement to redirect to the said view. In your jQuery $.ajax() success property, set the window.location.href value with the url data returned from the action method.
 $("#tblEmployee").on("click", "#save", function () {
 if (ids.length > 0) {
  $.ajax({
   type: "POST",
   dataType: "json",
   traditional: true,
   data: { courseID: ids, empId: JSON.stringify($('#empTextBox').val()) },
   url: "/Employee/DeleteEmpTrainings",
   success: function (dataUrl) {
    window.location.href = dataUrl;
   }
  });
 }
});
In your action result method, pass the url of the controller action with the return View() statement. Make sure to include the necessary query strings that matches the parameter list of the controller action. This action method below will call the UpdatedEmpTrainings controller action above.
public JsonResult DeleteEmpTrainings(List<string> courseID, string empId)
{
 _context = new EmployeeEntities();
 if(courseID != null)
 {
  foreach (var item in courseID)
  {
   EmployeeTraining emp_training = _context.EmployeeTrainings.AsEnumerable()
    .FirstOrDefault(t => t.TrainingID.GetValueOrDefault() == Convert.ToInt32(item) && t.EmployeeID == Convert.ToInt32(empId));
   _context.EmployeeTrainings.Remove(emp_training);
  }

  _context.SaveChanges();                
 }
 
 return Json(Url.Action("UpdatedEmpTrainings", "Employee", new { empId = empId }), JsonRequestBehavior.AllowGet); 
}
 

Wednesday, October 12, 2016

Method Line Separator in Visual Studio 2013

Hello,

There was a question in the forums on how to add a line separator in every method written in Visual Studio 2013 C# IDE. Well, there's a plugin for Visual Studio called Productivity Power Tools 2013 which you can download and install. After installing it, then proceed to making changes to your IDE.

To show line separator in your Visual Studio 2013 IDE, perform the steps below:
Click on Tools Menu -> Options -> Productivity Power Tools -> Other Extensions -> Show a separator between methods in the Editor
Screenshot:
Note: Make sure to restart Visual Studio to affect those changes.
Reference: Visual Studio 2013 Goodies