Javascript http post data to new window or pop up
Posted in ASP .NET, javascript on July 8th, 2010 by taswar
So was going through some legacy code to fix some security issues. One of them was there were links that were passing the data on url request. e.g NewFile.aspx?uid=1234
Rather than storing data in a session sometimes developers use shortcuts to do this, could be due to the pressure or time limit we have in shipping a product.
Aside from that lets see how we can fix this issue, what we want to accomplish is to post some data without calling server code and we can achieve that by some tricks in javascript.
Lets say you have a link that will say <a onclick=”javascript:NewFile()”>New File</a>
(Note I know this is not good again its legacy code)
1 2 3 4 | function NewFile() { window.open("NewFile.aspx?uid=1234", "", "width=800,height=600,left=100,top=100,resizable=yes,scrollbars=yes"); } |
Now we want to make a post request to the window and pass in the data.
Here is how we do it, I created a blank html page first and used this javascript.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function OpenWindowWithPost(url, windowoption, name, params) { var form = document.createElement("form"); form.setAttribute("method", "post"); form.setAttribute("action", url); form.setAttribute("target", name); for (var i in params) { if (params.hasOwnProperty(i)) { var input = document.createElement('input'); input.type = 'hidden'; input.name = i; input.value = params[i]; form.appendChild(input); } } document.body.appendChild(form); //note I am using a post.htm page since I did not want to make double request to the page //it might have some Page_Load call which might screw things up. window.open("post.htm", name, windowoption); form.submit(); document.body.removeChild(form); } function NewFile() { var param = { 'uid' : '1234'}; OpenWindowWithPost("NewFile.aspx", "width=730,height=345,left=100,top=100,resizable=yes,scrollbars=yes", "NewFile", param); } |
By doing so we can pass in the data to the NewFile.aspx page with a post request now, also note if you are using Request.QueryString['uid'] in the NewFile.aspx page you will need to change it to Request['uid']
Hope this helps
Stubbing out ServiceLocator for unit testing
Posted in Agile, Design, aspmvc, unit testing on June 30th, 2010 by taswar
There are certainly many ways to stub out dependency, using constructor injection, etc etc. Here is one way to quickly stub out ServiceLocator rather than implementing ServiceLocatorStub.
Lets say you have code that uses a helper and the dependency is not quite the responsibility of that object but its the sub object that uses it. As an example the IAccessHelper uses some security server to check some values. But the AccountController doesnt use it so why inject security service in AccountController? In that case you will call a service locator to get you the AccessHelper object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class AccountController: Controller { public bool DoSomething() { var accessHelper = ServiceLocator.Current.GetInstance<IAccessHelper>(); if(accessHelper.IsValid(user)) { //do something return true; } return false; } } |
Now if you wish to unit test this you will need to do quite a few things to stub it out. The quick way to do this is using property in C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class AccountController: Controller { public boolean DoSomething() { if(AccessHelperObject.IsValid(user)) { //do something return truel } return false; } private IAccessHelper _accessHelper; public IAccessHelper AccessHelperObject { get { return _accessHelper ?? ServiceLocator.Current.GetInstance<IAccessHelper>(); } set { _accessHelper = value; } } } |
So that now when you write your unit test you dont have to care about service locator you can just stub out your IAccessHelper by just passing in a mock or stub to it.
1 2 3 4 5 6 7 8 9 10 11 | [Test] public void Account_DoSomething() { var account = new AccoutController(); var stubAccess = MockRepository.GenerateStub<IAccessHelper>(); stubAccess.Expect(x => x.IsVaid("user")).Return(true); account.AccessHelperObject = stubAccess; var wasCalled = account.DoSomething(); Assert.That(wasCalled, Is.True); } |
This helps one to quickly break out the dependency of an object, that would otherwise take too many lines of code to test out a simple idea.
Json A circular reference was detected while serializing an object of type … in my asp mvc app
Posted in aspmvc on June 9th, 2010 by taswar
I found this weird error when I was testing a no trivial test case in my app and was not able to find out what was wrong with it.
It appears like a Json error in my asp mvc app, although the stack really doesn’t help
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | ystem.InvalidOperationException: A circular reference was detected while serializing an object of type 'TermBaseMvc.ViewModels.Udf.UdfValueViewModel'. at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) at System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) at System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass14.<InvokeActionResultWithFilters>b__11() at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass14.<>c__DisplayClass16.<InvokeActionResultWithFilters>b__13() at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass14.<>c__DisplayClass16.<InvokeActionResultWithFilters>b__13() at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass14.<>c__DisplayClass16.<InvokeActionResultWithFilters>b__13() at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) |
Basically what is happening is Json does not like to have circular reference ie. A -> B -> A
The easiest fix is to use [ScriptIgnore] in your ViewModel to tell it not to serialize object that may cause such a circulate issue.
Add the System.web.extensions reference to your viewmodel and make the elements that may cuase issue to scriptIgnore
example
1 2 3 4 5 6 7 8 9 10 11 | using System.Web.Script.Serialization; public class UserViewModel { public int Id { get; set; } public string FirstName { get; set; } [ScriptIgnore] public List<User> ManagerOf { get; set; } } |
By doing so now your json would look more like { Id: 3, FirstName: ‘Taswar’ }.
Also there is JSON.NET that provides [JsonIgnore] attribute if you are using json .net
JQuery print part of div only
Posted in JQuery, Uncategorized on May 19th, 2010 by taswar
So here is an interesting jquery plugin called jqprint it allows one to specify any element and sent it to print.
Assuming you have an element with id printButton and a content area called divToPrint
1 2 3 | $('#printButton').live('click', function() { $('#divToPrint').jqprint(); }); |
This will pop up the print functionality in your browser and send it with the default media=”print” css or else it picks up your default css. Kind of neat.
One thing to be mindful of in Firefox is the overflow attribute in your css stylesheet if you have overflow: hidden you will only get one page to print only.
Example:
1 | body { overflow: hidden; } |
Remove the overflow and it would print all the pages of a div.
JQuery get ajax call not working in IE
Posted in JQuery on May 5th, 2010 by taswar
So for some reason IE just loves to cache things for you when you call an ajax method.
Something like
1 2 3 4 5 | $('#mybutton').live('click', function() { $.post('SaveLanguage', { lang : $(this).val(), null, null); $.get('GetLanguage', null, function(html) { $('#myDiv').replaceWith(html); }); }); |
This will work every time in firefox but IE will just call the cache version, thus whatever you have changed in the post version would not matter.
To fix this one can use datetime to append to the query string in each call or just use jquery ajaxSetup like
1 2 3 4 5 6 7 | $.ajaxSetup({ cache: false}); $('#mybutton').live('click', function() { $.post('SaveLanguage', { lang : $(this).val(), null, null); $.get('GetLanguage', null, function(html) { $('#myDiv').replaceWith(html); }); }); |
or use the $.ajax call and pass in cache: false.
JQuery live ‘change’ doesn’t work in IE
Posted in JQuery on May 4th, 2010 by taswar
So was having issues as in why does my checkbox doesn’t work in IE when I do
1 2 3 | $('.checkbox').live('change', function() { alert('Checkbox clicked'); }); |
And found out that jquery does not bind live “change” events, I was told that it works in 1.4.2 but for some reason I still was not able to get it working.
The solution that I found was to use the livequery or bind method thus the code would become
1 2 3 | $('.checkbox').bind('change', function() { alert('Checkbox clicked'); }); |
or if you are using Ajax then
1 2 3 | $('.checkbox').livequery('change', function() { alert('Checkbox clicked'); }); |
That should do the trick, remember to add jquery.livequery.js if you are using livequery in your file.
ASP .NET MVC2 Changes: GetControllerInstance & DataAnnotationsModelBinder
Posted in aspmvc on March 30th, 2010 by taswar
So was in the process of updating my mvc app, there is a tool that does it for you and also a manual way .
But once you have updated there are also 2 more changes that you may need if you are using IoC or DataAnnotations.
First you will need to change the method in your Ioc to look for controller
1 2 3 4 5 6 7 8 9 10 11 | public class CommonServiceLocatorControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(Type controllerType) { if (controllerType == null) base.GetControllerInstance(controllerType); return ServiceLocator.Current.GetInstance(controllerType) as IController; } } |
into, notice the RequestContext in the parameter
1 2 3 4 5 6 7 8 9 10 | public class CommonServiceLocatorControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { if (controllerType == null) base.GetControllerInstance(requestContext, controllerType); return ServiceLocator.Current.GetInstance(controllerType) as IController; } } |
The other change is in DataAnnotationsModelBinder if you have one, rather than inherit from Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder inherit from DefaultModelBinder
Hope this helps
SparkViewEngine: Highlight Table Alt Row
Posted in aspmvc on March 29th, 2010 by taswar
Here is how one highlights an alt row with spark, quite clean I tell you.
Assuming you have a css that like below.
1 2 3 4 5 6 | tr.alt { text-align: left; padding: 2px; border: 1px solid #000; background: #ADDFFF; } |
And in your template you will call it like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <table> <tr> <th>ID</th> <th>FirstName</th> <th>LastName</th> <th>Gender</th> </tr> <tr each="var person in people" class="alt?{personIndex % 2 == 0}"> <td>${person.Id}</td> <td>${person.FirstName}</td> <td>${person.LastName}</td> <td>${person.Gender}</td> </tr> </table> |
Note: How I am using personIndex. It basically goes with the item, thus if you have var order in Orders, you would then say orderIndex
Linq: Sequence contains no matching element
Posted in Misc on March 26th, 2010 by taswar
So sometimes you will get these strange errors or exceptions when using linq.
For example if you use
1 | var result = myEnumerableCollection.First(x => x.Name == person.Name); |
This will throw InvalidOperationException with Sequence contains no matching element.
But if you use
1 2 3 | var result = myEnumerableCollection.FirstOrDefault(x => x.Name == person.Name); if(result == null) //did not find in the collection something went wrong or ..... |
Which will return you a null if its not found then you can check if the result is null and continue on with your work
Hope this helps
Asp .NET Redirect To SSL HttpModule
Posted in ASP .NET on February 18th, 2010 by taswar
There are tones of blog post out there on how to redirect http to https. As in when a user request for http://myserver.com/Login.aspx
they will be redirected to https://myserver.com/Login.aspx
One can do it with IIS but I find that way a bit ugly since you have create another site and set the 403 to redirect to another location. Not as elegant as apache mod rewrite.
A more elegant approach I found when using asp .net is by using an HttpModule in your code, so that the entire site is redirected. There are other solutions to redirect individual pages but for this post we will focus on redirecting all traffic to SSL.
To begin with we will code up an RedirectToSSL.cs page and place it into our App_Code folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using System; using System.Web; namespace SolutionName.App_Code { public class RedirectToSSL : IHttpModule { #region IHttpModule Members public void Dispose() { } public void Init(HttpApplication context) { context.BeginRequest += ContextBeginRequest; } private static void ContextBeginRequest(object sender, EventArgs e) { HttpApplication application = sender as HttpApplication; if (application == null) return; if (application.Request.IsSecureConnection) return; // send user to SSL string serverName = HttpUtility.UrlEncode(application.Request.ServerVariables["SERVER_NAME"]); string filePath = application.Request.FilePath; application.Response.Redirect("https://" + serverName + filePath); } #endregion } } |
Then all we have to do is add this line in our web.config file in order to enable it.
1 2 3 | <httpModules> <add name="RedirectToSSL" type="SolutionName.App_Code.RedirectToSSL"/> </httpModules> |
Replace the solutionName with your project name and voila you now have the entire site in SSL and you don’t have to worry about talking to an admin for IIS configuration or anything like that.