Tuesday, June 26, 2012

Ajax loading images

Here's an awesome for creating and downloading loading images - http://ajaxload.info/

You can pick among several dozen styles, customize the background and download all for free.

Thursday, June 7, 2012

Internet explorer and AJAX caching headache in MVC

Spent several hours figuring our what was going wrong with my ajax calls. After the initial ajax call to a controller method that returns a JSONResult, the subsequent calls weren't even hitting the controller code. This was working fine in Chrome all along.

To fix this I had to create an ActionFilter attribute to specify no caching for httpgets. This post solved my problem - http://stackoverflow.com/questions/2027610/asp-net-mvc-2-rc-caching-problem

public class CacheControlAttribute : System.Web.Mvc.ActionFilterAttribute
    {
        public CacheControlAttribute(HttpCacheability cacheability)
        {
            this._cacheability = cacheability;
        }

        private HttpCacheability _cacheability;

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
            cache.SetCacheability(_cacheability);
        }
    } 

//in the controller
 [CacheControl(HttpCacheability.NoCache),HttpGet]
        public JsonResult GetUpcomingMatches(Guid id, int divisionId)
        {
            var reply = m_matchLogic.GetUpcomingMatches(id, divisionId);
            return Json(reply, JsonRequestBehavior.AllowGet);
        }

Wednesday, May 16, 2012

Javascript - Revealing Module pattern

Over the last couple of months I have grown to love structuring my JavaScript code using the "Revealing Module" pattern. I love the fact that it promotes the use of OO concepts in JS. With VS2011 adding more intellisense support to JS, it makes the use of this pattern so much better. Read more about it on Dan Wahlin's blog - http://weblogs.asp.net/dwahlin/archive/2011/08/02/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-module-pattern.aspx

Friday, May 11, 2012

Request for the permission of type 'System.Web.AspNetHostingPermission

I moved my asp.net app from a Win 2003 Server to a Win 2008 Server running IIS7 and I started getting Permission denied for "System.Web.AspNetHostingPermission" errors for my .ascx files.

Turns out that you have to set the "Load User Profile" for the specific application pool to True. That took care of the issue. 

Sql Express LocalDb

LocalDb - introduced around the Sql 2012 RC release is a geared toward developers and dev machines. Acting much like Sql Express simplifies development, without having to maintain a full blown Sql express instance. Localdb is spawned on demand via Visual studio without having to keep a SQL process/service running in the background all the time - adding a little more processing power to dev machines.

You can connect to the LocalDb instance like this - (LocalDb)\v11.0

Read more about LocalDb - http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql-express.aspx

Change default database name in EF 4.3 Code First

While using Code first in EF 4.3 the default generated db name will look like your namespace something.datacontext.

To change this behavior and use a custom name:

public class StockWatchDataContext:DbContext
    {
        public StockWatchDataContext(): base("StockWatch") //add your db name and override the base constructor
        { }

        public DbSet Security { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove();
        }
    }
Also make sure that you are not using localdb as the db server instance or you wont see that in SQL management studio.

Thursday, May 10, 2012

YQL + JSON issues

Tried almost everything to get some JSON from YQL and just could not loop through the items. What worked was to parse the JSON using JSON.parse(jsondata). No problems there after.

var getStockQuote = function () {
        var url = "/api/stockquote/sd";
       
        $.getJSON(url, function (data) {
            var json = JSON.parse(data);
            $.each(json.query.results, function (i, results) {
                formatting.updateSecurity(results);
            });
        });

Wednesday, April 25, 2012

Upgrading Sql 2008 express to SP2

Apparently you will need to run the exe for Sql Server 2008 SP2 to upgrade you Sql 2008 Express instances to SP2. The installer for the express SP2 editions will only let you create a new instance, but not upgrade an existing instance.

Download the SQL 2008 SP2 from here - http://www.microsoft.com/download/en/details.aspx?id=12548

Tuesday, April 24, 2012

Wednesday, April 18, 2012

Encrypt/Decrypt data from within SQL server using a pass phrase

SQL server has two functions EncryptByPassPhrase and DecryptByPassPhrase which encrypt/decrypt data with a passphrase using a TripleDES algorithm with a 128 bit key.

EncryptByPassPhrase - http://technet.microsoft.com/en-us/library/ms190357.aspx

Thursday, February 9, 2012

Entity Framework 4.3 released.

Check out what's new in the EF 4.3 - http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-released.aspx

Multiple Submit button on a single MVC form

Leaving the question of weather this is a good practice or not, there is a way to have multiple submit buttons on a single form. Clicking on any of the buttons will post to the same action, so how do you tell which one was clicked. On your View:
@using (Html.BeginForm())
{
 //other fields here.....
 
 
}
On your controller that the form posts to:
[HttpPost]
public ActionResult Profile(Model model,string submitButton)
{
  Member member = new Member();
  switch (submitButton)
  {
     case "Save1": //do something;
        break;
     case "Save2": //do something;
        break;
  }
   return View(model);
}

Tuesday, February 7, 2012

Dynamically adding a collection of objects in a MVC view

In one of my projects I needed to dynamically display fields to enter information for a collection of objects. Specifically speaking I had a POCO "User" class with FK to a POCO "Child" class. I needed a way to generate text boxes based on how many kids a user had. This involves several steps and here's what I had to do.

1. Create a partial view with the fields you need to capture the info for a "Child"

@{
    var seed = ViewBag.Seed;
      
    
@{ @*MVC renders fields for a collection by appending an index, which I am setting up below*@ var ageIdText = "Children_" + seed + "__Age"; var ageNameText = "Children[" + seed + "].Age"; var genderIdText = "Children_" + seed + "__Gender"; var genderNameText = "Children[" + seed + "].Gender"; var deleteIdText = "Children_" + seed + "__Delete"; var deleteNameText = "Children[" + seed + "].Delete"; }    Remove
}
MVC renders controls for collections by attaching an index for the collection. I had to code this in to render based on the number of controls that need to be displayed. Ex: the age text field will be Children_[1]__Age and so forth. I will explain the reason for having a delete field a little later. 2. Create an action in the controller that will return the partial view
public ActionResult RenderChildren(int? id, int? seed, string viewType)
        {
            //if no of children to be rendered in the view was not send in the request url, then render only one child
            if (id.HasValue)
                ViewBag.Children = id;
            else
                ViewBag.Children = 1;

            //if the collection index was not indicated, then start rendering the controls from 0. 
            //This will come in handy when there are already controls on the page and we want to add more.
            if (seed.HasValue)
                ViewBag.Seed = seed;
            else
                ViewBag.Seed = 0;
            return PartialView(viewType);
        }
It is important to keep track on the index for the collection, or you will get unexpected results.

3. Create the javascript that will call the action above from another control. ex: onclick event of a link that should add the control for adding a "Child"
function addChild(method,container,type) {
    var noofChild = $(container).find('.mark-for-delete').length;
    $.get('/account/'+method+'?seed=' + (noofChild)+"&viewtype="+type, function (template) { $(container).append(template); });
}
4. Call the javascript
Add a child
function deleteChildren(element, deleteElement) {
    $container = $(element).parent();
    $container.find(deleteElement).val('True');
    $container.hide();
}
This will take care of dynamically rendering the required number of fields for "Child" 5. Handling the deletes - I also needed to provide the user to delete existing fields
Remove
To handle the delete I need some more javascript code that will add some value to the hidden field that I added to my partial view. This value can then be picked up via the model while updating the database. I do have a property in the "Child" POCO class for setting the delete value. This field is not mapped to the database.

Wednesday, February 1, 2012

The different WCF bindings

It's awesome that WCF support all the different bindings and protocols. Connect with multiple apps running different protocols all with the same code. Here's a list of all the different bindings that WCF support. I snagged this from - http://msdn.microsoft.com/en-us/library/bb310550.aspx. This link is a highly recommended read - has info on speed comparisons etc.


Bindings Description
BasicHttpBinding A binding that is suitable for communication with WS-Basic Profile conformant Web Services like ASMX-based services. This binding uses HTTP as the transport and Text/XML as the message encoding.
WSHttpBinding A secure and interoperable binding that is suitable for non-duplex service contracts.
WSDualHttpBinding A secure and interoperable binding that is suitable for duplex service contracts or communication through SOAP intermediaries.
WSFederationHttpBinding A secure and interoperable binding that supports the WS-Federation protocol, enabling organizations that are in a federation to efficiently authenticate and authorize users.
NetTcpBinding A secure and optimized binding suitable for cross-machine communication between WCF applications
NetNamedPipeBinding A secure, reliable, optimized binding that is suitable for on-machine communication between WCF applications.
NetMsmqBinding A queued binding that is suitable for cross-machine communication between WCF applications.
NetPeerTcpBinding A binding that enables secure, multi-machine communication.
MsmqIntegrationBinding A binding that is suitable for cross-machine communication between a WCF application and existing MSMQ applications.

Thursday, January 26, 2012

Creating a self-executing installer with Winrar

You can use Winrar to create self-executing installer from the msi's and setup files you create from a Visual Studio Setup project.

Here are the steps:

1. Put your MSI and exe files in a folder.
2. Right click folder and select "Add to Archive"

3. Make sure that the archive format is set to "RAR" and check "Create SFX Archive" and "Create Solid Archive". The archive name extension automatically changes to ".exe"

4. Click on the "Advanced" tab and click on the "SFX Options" button.

5. In the "Advanced SFX Options" dialog - enter the path name to your .exe file. In my case "\Program\Setup.exe".

6. Click on the "Modes" tab and select "Hide all" under "Silent Mode" radio button group.

7. Click on Update tab. I set the "Overwrite All Files" as my  overwrite mode. This will replace all install files.

8. To set an icon to your installer, click on the "Text and Icon" tab and set your options

9. Click OK on both the open dialogs and you'll have your self-extracting exe

There are several other options you can change based on your needs.

Tuesday, January 24, 2012

Single sign on between a domain and a subdomain using forms authentication

I ran into an interesting situation on a site using forms authentication, where the user had to be logged into both a domain and its subdomain once authenticated. Here's what I had to do to get this to work.

Both sites being seperate applications in themselves the authentication cookies generated by asp.net would be different due the encryption keys used by the sites. The Auth cookie generate by domain.com cannot be read by subdomain.domain.com. To get over this issue we need to add a machine key element in the web.config's of the both the apps. This key is going to be the same in both apps.

There are several different options in setting up these keys. Read more about it in this page. It also includes some code on how to generate a machine key using a console app - http://msdn.microsoft.com/en-us/library/ff649308.aspx

Once this is taken care of, the next issue we are going to have is the cookie itself. When a cookie is created - it is domain specific, so a cookie created by a sub domain will not be accessible to its parent level domain. In my case, the user authentication was to be performed on a subdomain using MVC. So I had to generate cookies for both the sub domain and domain upon authentication from my subdomain.

For Login

 public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

                    Account account = new Account();
                    //modify the Domain attribute of the cookie to the second level domain
                    HttpCookie MyCookie = FormsAuthentication.GetAuthCookie(model.UserName, model.RememberMe);
                    MyCookie.Domain = "domain.com";//the second level domain name
                    Response.AppendCookie(MyCookie);

                    string userName = account.GetUserName(model.UserName);
                    Session["ActualName"] = userName;
                    HttpCookie userCookie = new HttpCookie("IGNUS");
                    userCookie.Domain = "domain.com";
                    userCookie.Values["Name"] = userName;
                    if (model.RememberMe)
                        userCookie.Expires = DateTime.Now.AddDays(2);
                    Response.Cookies.Add(userCookie);

                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Member");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
For LogOut

 public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            HttpCookie userCookie = new HttpCookie("IGNUS");
            userCookie.Domain = "domain.com";
            userCookie.Expires = DateTime.Now.AddDays(-1);

            HttpCookie staticAuthCookie = new HttpCookie(".ASPXAUTH");
            staticAuthCookie.Domain = "domain.com";
            staticAuthCookie.Expires = DateTime.Now.AddDays(-1);

            Response.Cookies.Add(userCookie);
            Response.Cookies.Add(staticAuthCookie);

            return RedirectToAction("LogOn");
        }

How to get a Dell Service Tag remotely

If you are near the server you can just look around and find the Service Tag sticker. But, if you are logged in remotely here's how to get the service tag
Type "wmic bios get serialnumber" into the command prompt and press enter.