Tuesday, January 31, 2012

using .ResolveUsing with AutoMapper

If you had an AutoMapper map like so:

Mapper.CreateMap<Person, PersonInputModel>().ForMember(personInputModel => personInputModel.FullName, person => person.ResolveUsing<PersonNameResolver>());

 
 

.ResolveUsing would allow you to reach out to another method to undertake a tricky translation.

using System.Linq;

using OurApp.Core.Entities;

using AutoMapper;

namespace OurApp.Web.UI.Config.AutoMapper.Resolvers

{

   public class OrderStatusReasonResolver : ValueResolver<Person, string>

   {

      protected override string ResolveCore(Person source)

      {

         var fullName = source.FirstName + " " + source.LastName;

         return fullName.Trim();

      }

   }

}

Monday, January 30, 2012

sabotage the ability to tab to a control with tabindex="-1"

If you are doing something hacky and you need an "invisible" HTML input that is:

  1. not a hidden input type
  2. not hidden by a style of display: none;

You can always move the control off the page's edge with a style of margin-left:-9999px;

...but, yes, the control is accessible by way of tabbing unless you take steps to sabotage the ability to tab to the control with: tabindex="-1"

only show something in a Razor view if debugging

@if (Context.IsDebuggingEnabled)

{

   
whatever

}

Friday, January 27, 2012

Here is some interesting AJAX we started to roll and then abandoned today!

This controller action...

public RenderJsonResult Foo(Guid id)

{

   var program = ProgramRepository.GetById(id);

   var ppMap = new Dictionary<ProgramPlan, string>();

   program.ProgramPlans.ForEach(pp =>

      {

         ppMap.Add(pp, pp.NameStaticAttribute.GetSelectedValue(pp.Id).ToString());

      });

   var result = ppMap.Keys.Select(pp => new

   {

      Id = pp.Id,

      Name = ppMap[pp],

      Offerings = pp.ProgramOfferings.Select(po => new { po.Id, po.Name })

   });

   return RenderJson(result);

}

 
 

...made some new objects and returned them as JSON which kind of looked like this:

{\"PreventCyclicRedundancy\":false,\"Result\":[{\"Plan\":{\"Id\":\"01583ab6-3b8a-4af7-ac68-9fe500ec99a0\",\"Name\":\"alpha\",\"Offerings\":[{\"Id\":\"2660ce9a-73b2-406a-9ff6-9fe500ee6617\",\"Name\":\"one\"},{\"Id\":\"294eac05-83d2-42a6-9cdf-9fe500ee9f17\",\"Name\":\"two\"},{\"Id\":\"80c4ac8b-b2b8-4043-8207-9fe500eef13d\",\"Name\":\"three\"}]}},{\"Plan\":{\"Id\":\"bdf3d257-573d-4685-88d5-9fe500ecaffc\",\"Name\":\"beta\",\"Offerings\":[]}},{\"Plan\":{\"Id\":\"926cf94f-c546-4ec4-a860-9fe500ed8e9a\",\"Name\":\"gamma\",\"Offerings\":[{\"Id\":\"4e729423-3ff9-4abc-bb3c-9fe500ef8ffc\",\"Name\":\"four\"},{\"Id\":\"c3879ef4-80ed-40f9-8a7d-9fe500efc899\",\"Name\":\"five\"}]}}]}

 
 

There was a Razor view like this...

<div class="contentBlock" id="qux">

</div>

<script src="/whatever.js" type="text/javascript"></script>

<script type="text/javascript">

   var programId = '@Model.Program.Id';

   var planLinksContainerSelector = 'qux';

   bar(programId, planLinksContainerSelector);

</script>

 
 

...which reached out to a .js file which called on the Controller Action:

function bar(programId, containerSelector) {
   $.ajax({
      url: '/Program/Foo',
      data: 'id=' + programId,
      success: function (result) {
         var container = $(planLinksContainerSelector);
         _.each(result, function (plan) {
            var planLink = $('<a />');
            planLink.attr('href', '/programplan/edit/?programId=' + programId + '&id=' + plan.Id);
            planLink.text(plan.Name);
            container.append(planLink);
            _.each(plan.Offerings, function (offering) {
               //do offs here
            });
         });
      },
      error: function (a, b, c) {
      }
   });
}

Thursday, January 26, 2012

demystify NuGet error messages

Today Jorge and I encountered this really vague NuGet error in Visual Studio:

Error 7 The command ""C:\AMD\trunk\src\Tools\nuget" update -self
"C:\AMD\trunk\src\Tools\nuget" install "C:\AMD\trunk\src\AMD.Avalanche.Web.UI\packages.config" -o "C:\AMD\trunk\src\Packages" -source file://BUILDS/nuget-lib" exited with code 1. AMD.Avalanche.Web.UI

 
 

Jorge suggested I open a command window and paste in the contents of the outer most quotes, namely:

"C:\AMD\trunk\src\Tools\nuget" update -self
"C:\AMD\trunk\src\Tools\nuget" install "C:\AMD\trunk\src\AMD.Avalanche.Web.UI\packages.config" -o "C:\AMD\trunk\src\Packages" -source file://BUILDS/nuget-lib

 
 

This revealed better error messages:



I'm not that in love with NuGet. I would prefer just keeping the needed .dlls in the lib folder. Rafael did mention that, when installing some .dlls, that NuGet will doctor up a Web.config file as is appropriate to be accommodating. I guess that is one thing in favor of the automation. I'm mostly turned off however. :(

of what bubbles up from repositories

The beauty of the typical repository pattern is you know if something has been "popped off" (forgive my injection of SMTP slang) when you encounter it in another layer. For example consider going into a method and finding:

var bars = foo.Bars;

 
 

If foo is handed in from another method and Bars is a collection of Bar objects on foo, how can we know if the Bars have been lazy loaded by NHibernate yet or not. We can't. We have to start walking upstream to see if there is any place previously in code where foo.Bars was used. Grrr. If there is a policy in which everything that comes over from repositories has already been loaded, then this isn't a problem. A variation of this problem can happen with IQueryable too. When IQueryables are allowed into other layers from the repositories, one does not know, when looking at many spots in code, if an IQueryable had been popped off to a list or not somewhere upstream of the line of code at hand. To counter this pattern, it is probably best to only have objects already cast to lists come over the wall from repositories.

keep ids unique with Razor

<div class="contentBlock" id="@{<text>PlansFor</text>@Model.Program.Id}">

...makes...

<div id="PlansFora9c7326d-1006-4d0e-ac37-9fe30142aab6" class="contentBlock">

see all files that have changed in a changeset in TFS

  1. in Visual Studio go to Team Explorer and click on Source Control
  2. in Source Control Explorer right-click on the trunk and select View History
  3. right-click on a changeset to see any one file that has changed

uninstall and reinstall NuGet

At Tools > Extension Manager... in Visual Studio, you should be able to see Nuget and uninstall it.

Go right back to the Extension Manager to reinstall NuGet. Go to the "Online Gallery" and "Sort by" the highest ranked.

Restart Visual Studio after an install or uninstall

Wednesday, January 25, 2012

some CSS3

For every even table row in the table body of a table with an id of "listingTable" make the background color #eaf0f7 unless the "detail" class is applied to the row.

table#listingTable tbody tr:nth-child(even):not(.detail) {

   background-color:#eaf0f7;

}

 
 

For every input in "foo" that is not a checkbox, radio button, or a file control, add a pixel of padding to the top and bottom.

#foo input:not([type="checkbox"]):not([type="radio"]):not([type="file"])

{

   padding-top:1px;

   padding-bottom:1px;

}

event.which == 13

$(".submitButton").keydown(function (event) {
   if (event.which == 13) {
      window.location = "/program/Edit?id=@Model.Program.Id";
   }
});

pull in the HTML from an ASP.NET MVC partial into a view by way of jQuery AJAX

What if I had a controller like this?

using System.Web.Mvc;

namespace GenericPartialScrappingTest.Controllers

{

   public class LambController : Controller

   {

      public ActionResult Index()

      {

         return View();

      }

      

      public ActionResult _TwelveCells()

      {

         return PartialView();

      }

   }

}

 
 

The Index view looks like this:

<h2>Lamb Page</h2>

<p>This is a page with a partial:</p>

@Html.Partial("_TwelveCells")

 
 

The Index view pulls in this partial:

<table>

   <tr>

      <td>Mary</td>

      <td>had</td>

      <td>a</td>

   </tr>

   <tr>

      <td>lit-</td>

      <td>tell</td>

      <td>lamb</td>

   </tr>

   <tr>

      <td>lit-</td>

      <td>tell</td>

      <td>lamb</td>

   </tr>

   <tr>

      <td>lit-</td>

      <td>tell</td>

      <td>lamb</td>

   </tr>

</table>

 
 

In a different view, summoned by a different controller, I may pull in the partial by way of jQuery AJAX:

<h2>Home Page</h2>

<p>The div below should be filled by way of AJAX.</p>

<div id="whatever"></div>

<script type="text/javascript">

   var actionURL = '@Url.Action("_TwelveCells", "Lamb")';

   $.ajax({

      type: "POST",

      url: actionURL,

      data: "",

      success: function (r) {

         $("#whatever").html(r);

      },

      complete: function () {

         

      },

      error: function (req, status, error) {

         $("#whatever").html(error);

      }

   });

</script>

Tuesday, January 24, 2012

display a partial in Razor

@Html.Partial("_Whatever")

I like AJAX... and it is getting easier :P

$.ajax({

   url: '/SiliconSampleDefinition/GetLinkableDefinitions',

   type: "POST",

   dataType: "json",

   data: { id: '@(Model.SiliconSampleDefinition.Id)', query: request.term },

   success: function (data) {

      response($.map(data, function (item) {

         return {

            id: item.Id,

            label: item.DisplayName,

            firstShipDate: item.FirstShipDate,

            firstExternalShipDate: item.FirstExternalShipDate,

            lastShipDate: item.LastShipDate

         };

      }));

   }

});

Monday, January 23, 2012

the better POST fix

The POST AJAX implementation here should really be like the following. The problem with what I had before was that I was STILL passing too much gunk in the URL line. Duh.

var url = "@ViewBag.WhereAmI";

url = url + "/home/validate";

var data = "value=" + content;

data = data + "&isRequired=true";

data = data + "&maxSize=5000";

var message = $.ajax({

   type: "POST",

   url: url,

   data: data,

   async: false

}).responseText;

break up a big GET AJAX call into chunks

Here is another solution for the problem described here. In this approach I am breaking a GET AJAX call up into chunks. Hmmm. I'm realizing that I went about my POST AJAX call the wrong way as I was still crafting a URL line. Ah, but I digress. Does it seem silly to even use an AJAX call to an MVC action? For this code, it sure does. I'm assuming that the code that my friend is working does more sanity checking than I am doing and that the action call by way of AJAX is just needed, but then there is an old joke about the word assume.

<form id="SubmissionFacilitator" method="POST"

      action="/home/successfulsubmission/">

   <textarea name="BlobOfCopy"></textarea>

   <div id="ErrorHint" style="color: #CC0000;"></div>

   <input type="submit" value="submit"/>

</form>

<script type="text/javascript">

   $(function () {

      var wrapper = $('#SubmissionFacilitator');

      var textarea = wrapper.find('textarea[name=BlobOfCopy]');

      $(textarea).keyup(function () {

         var junkbool = assesssanityconcerns($.trim(textarea.val()));

      });

      $('#SubmissionFacilitator').submit(function () {

         return assesssanityconcerns($.trim(textarea.val()));

      });

   });

   function assesssanityconcerns(content) {

      var maxsize = 5000;

      if (content.length > maxsize) {

         var gap = content.length - maxsize;

         var error = "There are " + gap + " too many characters.";

         $('#ErrorHint').html(error);

         return false;

      } else {

         if (content.length > 1000) {

            var one = "";

            var two = "";

            var three = "";

            var four = "";

            var five = "";

            for (i = 0; i < 1000; i++) {

               one = one + content.charAt(i);

            }

            for (i = 1000; i < 2000; i++) {

               if (i < content.length) {

                  two = two + content.charAt(i);

               }

            }

            if (content.length > 2000) {

               for (i = 2000; i < 3000; i++) {

                  if (i < content.length) {

                     three = three + content.charAt(i);

                  }

               }

            }

            if (content.length > 3000) {

               for (i = 3000; i < 4000; i++) {

                  if (i < content.length) {

                     four = four + content.charAt(i);

                  }

               }

            }

            if (content.length > 4000) {

               for (i = 4000; i < 5000; i++) {

                  if (i < content.length) {

                     five = five + content.charAt(i);

                  }

               }

            }

            var url = "@ViewBag.WhereAmI";

            url = url + "/home/validate?value=" + one;

            url = url + "&isRequired=true";

            url = url + "&maxSize=" + maxsize;

            var message = $.ajax({

               url: url,

               async: false

            }).responseText;

            url = "@ViewBag.WhereAmI";

            url = url + "/home/validate?value=" + two;

            url = url + "&isRequired=true";

            url = url + "&maxSize=" + maxsize;

            var messagealt = $.ajax({

               url: url,

               async: false

            }).responseText;

            if (message != messagealt) {

               if (message == "good") {

                  message = messagealt;

               }

            }

            if (three != "") {

               url = "@ViewBag.WhereAmI";

               url = url + "/home/validate?value=" + three;

               url = url + "&isRequired=true";

               url = url + "&maxSize=" + maxsize;

               messagealt = $.ajax({

                  url: url,

                  async: false

               }).responseText;

               if (message != messagealt) {

                  if (message == "good") {

                     message = messagealt;

                  }

               }

            }

            if (four != "") {

               url = "@ViewBag.WhereAmI";

               url = url + "/home/validate?value=" + four;

               url = url + "&isRequired=true";

               url = url + "&maxSize=" + maxsize;

               messagealt = $.ajax({

                  url: url,

                  async: false

               }).responseText;

               if (message != messagealt) {

                  if (message == "good") {

                     message = messagealt;

                  }

               }

            }

            if (five != "") {

               url = "@ViewBag.WhereAmI";

               url = url + "/home/validate?value=" + five;

               url = url + "&isRequired=true";

               url = url + "&maxSize=" + maxsize;

               messagealt = $.ajax({

                  url: url,

                  async: false

               }).responseText;

               if (message != messagealt) {

                  if (message == "good") {

                     message = messagealt;

                  }

               }

            }

            if (message == "good") {

               $('#ErrorHint').html("");

               return true;

            } else {

               $('#ErrorHint').html(message);

               return false;

            }

         } else {

            var url = "@ViewBag.WhereAmI";

            url = url + "/home/validate?value=" + content;

            url = url + "&isRequired=true";

            url = url + "&maxSize=" + maxsize;

            var message = $.ajax({

               url: url,

               async: false

            }).responseText;

            if (message == "good") {

               $('#ErrorHint').html("");

               return true;

            } else {

               $('#ErrorHint').html(message);

               return false;

            }

         }

      }

   }

</script>

Sunday, January 22, 2012

another example of a POST .ajax call

$.ajax({

   type: "POST",

   url: '/session/set',

   context: self,

   data: "key=" + id + "&payload=" + sobj,

   success: dfr.resolve,

   error: function (a, b, c) {

      debugger;

      alert(b);

   }

});

the POST fix

It seems that one potential solution for the problem described here is to make the AJAX call use POST instead of GET. I'm not sure if it will work or not. I am having trouble reproducing the environment my friend has. I can't get IE to fail in Cassini and in IIS environments IIS itself seems to have a problem with the length of the call before IE specifically does. Maybe my theory is wrong. Code for a potential fix:

<form id="SubmissionFacilitator" method="POST"

      action="/home/successfulsubmission/">

   <textarea name="BlobOfCopy"></textarea>

   <div id="ErrorHint" style="color: #CC0000;"></div>

   <input type="submit" value="submit"/>

</form>

<script type="text/javascript">

   $(function () {

      var wrapper = $('#SubmissionFacilitator');

      var textarea = wrapper.find('textarea[name=BlobOfCopy]');

      $(textarea).keyup(function () {

         var junkbool = assesssanityconcerns($.trim(textarea.val()));

      });

      $('#SubmissionFacilitator').submit(function () {

         return assesssanityconcerns($.trim(textarea.val()));

      });

   });

   function assesssanityconcerns(content) {

      var url = "@ViewBag.WhereAmI";

      url = url + "/home/validate?value=" + content;

      url = url + "&isRequired=true";

      url = url + "&maxSize=5000";

      var message = $.ajax({

         type: "POST",

         url: url,

         async: false

      }).responseText;

      if (message == "good") {

         $('#ErrorHint').html("");

         return true;

      } else {

         $('#ErrorHint').html(message);

         return false;

      }

   }

</script>

a problem I am chewing on

A friend has asked that I help with a problem she is fighting in the app she is working on. It is an interesting puzzle. In an existing ASP.NET MVC2 application, form field validations are done through jQuery AJAX calls to control actions that return a string that will be interpreted for validation validity like so:

var url + "http://www.example.com/whatever/validate?value=" + content;

url = url + "&isRequired=true";

url = url + "&maxSize=5000";

var message = $.ajax({

   url: url,

   async: false

}).responseText;

 
 

content, as suggested above, would be the copy out of a form field such as a textarea. Correct me if I'm wrong, but as we are not specifying POST in the synchronous AJAX call, we are thus sending gunk across the URL line by way of a GET call to the controller action. When I inspect with firebug, this theory holds up. I see calls like this being made:

http://www.example.com/whatever/validate?value=The%20quick%20red%20fox%20jumps%20over%20the%20lazy%20brown%20dog.&isRequired=true&maxSize=5000

 
 

The original developer who rolled this no longer works were my friend works, so there is now to be some pain in supporting it. I think you can see some of the things that may go wrong:

  1. An ampersand in the value variable will sabotage the isRequired and maxSize variables downstream of the value variable. (It would have made more sense to send the value variable last.)
  2. If the value variable's value is too long the call will break as there are limits on how long the URL line may be in different browsers.

 
 

The second problem above is the problem we are trying to beat. In trying to find a fix, I set up a little form that emulates the problem. Copy may be put into a textarea and on a keyup event there is a sanity check SYNCHRONOUSLY WITH GET AJAX to see if the copy is good.


 
 

My controller:

using System.Configuration;

using System.Web.Mvc;

namespace AjaxTests.Controllers

{

   public class HomeController : Controller

   {

      public ActionResult Index()

      {

         ViewBag.WhereAmI = ConfigurationManager.AppSettings["WhereAmI"];

         return View();

      }

      

      public ActionResult SuccessfulSubmission()

      {

         return View();

      }

      

      public string Validate(string value, bool? isRequired, int maxSize)

      {

         string qualityOfCopy = "good";

         if (isRequired == true && string.IsNullOrEmpty(value))

         {

            qualityOfCopy = "You must give copy!";

         }

         if (value.Length > maxSize)

         {

            int gap = value.Length - maxSize;

            qualityOfCopy = "There are " + gap + " too many characters.";

         }

         return qualityOfCopy;

      }

   }

}

 
 

My view:

<form id="SubmissionFacilitator" method="POST"

      action="/home/successfulsubmission/">

   <textarea name="BlobOfCopy"></textarea>

   <div id="ErrorHint" style="color: #CC0000;"></div>

   <input type="submit" value="submit"/>

</form>

<script type="text/javascript">

   $(function () {

      var wrapper = $('#SubmissionFacilitator');

      var textarea = wrapper.find('textarea[name=BlobOfCopy]');

      $(textarea).keyup(function () {

         var junkbool = assesssanityconcerns($.trim(textarea.val()));

      });

      $('#SubmissionFacilitator').submit(function () {

         return assesssanityconcerns($.trim(textarea.val()));

      });

   });

   function assesssanityconcerns(content) {

      var url = "@ViewBag.WhereAmI";

      url = url + "/home/validate?value=" + content;

      url = url + "&isRequired=true";

      url = url + "&maxSize=5000";

      var message = $.ajax({

         url: url,

         async: false

      }).responseText;

      if (message == "good") {

         $('#ErrorHint').html("");

         return true;

      } else {

         $('#ErrorHint').html(message);

         return false;

      }

   }

</script>

 
 

I set this up as an MVC4 project. I stripped a lot of the noise out of the master page such as CSS classes. I left the call to jQuery there.

Saturday, January 21, 2012

There is a 2048 character cap on the length of urls in MVC4 apps.

Put <httpRuntime maxQueryStringLength="8000" /> in the <system.web> portion of Web.config to deal with this error message in an ASP.NET MVC4 project:

The length of the query string for this request exceeds the configured maxQueryStringLength value.

 
 

As there is a 2,083 character limit for the URL line in Internet Explorer this sort of restraint makes sense.

Friday, January 20, 2012

there is a 2,083 character limit for the URL line in Internet Explorer

There are character limits for the URL line. Different browsers have different limits. IE looks to be the "weakest" so to speak.

using .Aggregate in C#

foreach (KeyValuePair<string, string> keyValuePair in dictionary) concatenatedValues += keyValuePair.Value;

 
 

I was able to refactor the line above into the line below by just following ReSharper's suggestion.

concatenatedValues = dictionary.Aggregate("", (current, keyValuePair) => current + keyValuePair.Value);

 
 

I'm still inclined to think in terms of the old foreach thing and then see what I may make of it that is more modern. .Aggregate is a first for me.

the double exclamation mark operator in JavaScript

Addendum 9/17/2013: Please see this for a better explanation as what follows is goofy.

getSelectedIds: function (backingStore) {

   var selectedIds = backingStore.find('option:selected').map(function () {

      return $(this).val();

   });

   return !!selectedIds ? selectedIds : [];

}

   

The second to last line above uses the double exclamation mark operator which fishes for not zero, not false, and not undefined in a variable's shape and allows one to do the sort of one line if/then operations that one associates with ?: in C#. This line empowers: If selectedIds is not zero, not false, and not undefined, then return selected Ids, otherwise return a new range in JavaScript that is empty.

Thursday, January 19, 2012

cool use of Razor's Html.IdFor in jQuery

$('#@(Html.IdFor(m => m.Foo))').change(function() {

   alert('Hey');

});

 
 

.change() is not unlike .toggle() in some ways.

jQuery date comparison

var foo = $('#whatever').val();

   if (foo != null) {

      if ((new Date(foo)).getTime() < (new Date()).getTime()) {

         
yet more code...

how to use jquery.validate.js along side Razor @Html.ValidationMessageFor controls

http://develoq.net/2011/asp-net-mvc-3-remote-validation-with-jquery/ seems at a glance like a pretty good resource for understanding how to use jquery.validate.js along side Razor @Html.ValidationMessageFor controls. I'm reading up on it now. We have this going on in our app.

 
 

Addendum 3/26/2014: This and this are some other posts I wrote on this topic which actually show off some code. I feel like mentioning it here because for some reason this vapid posting is the posting that everyone finds while Googling.

Wednesday, January 18, 2012

jasmine-jquery widgets do not need to be cast to variables

<script type="text/javascript">

   (function () {

      $(document).ready(function () {

         var filterForm = $('#formfiltering');

         var pager = $('#pager');

         var widget = pager.PagerWidget({

            form: filterForm,

            page: @Model.ListView.Page,

            pageSize: @Model.ListView.PageSize

         });

         var foo = widget.PagerWidget('getOption', 'pageSize');

         alert(foo);

      });

   })();

</script>

 
 

The above, can be made simpler or more complicated (depending on your perspective) like so:

<script type="text/javascript">

   (function () {

      $(document).ready(function () {

         var filterForm = $('#formfiltering');

         var pager = $('#pager');

         pager.PagerWidget({

            form: filterForm,

            page: @Model.ListView.Page,

            pageSize: @Model.ListView.PageSize

         });

         var foo = pager.PagerWidget('getOption', 'pageSize');

         alert(foo);

      });

   })();

</script>

SQL injection attacks are no longer a current problem?

http://msdn.microsoft.com/en-us/library/ff649310.aspx leads me to believe that yellow-and-red-screen-of-death errors in the name of preventing SQL injection attacks are no longer a current problem. Perhaps this went away with VS2005.

potential LinqSpecs security hole

The collection IdsOfManagedAllocationPrograms cannot be empty here or we'll get an NHibernate error:

public static Specification<Order> AllocationManagerCriteria(AccessMap accessMap)
{
   return new AdHocSpecification<Order>(o => o.OrderItems.Where(oi =>

         accessMap.IdsOfManagedAllocationPrograms.Contains(oi.ProgramOffering

         .ProgramPlan.Program.Id)).Count() > 0);
}

 
 

...so, we are trying to sanity check if we should run the spec like so:

using OurApp.Core.Entities;

using OurApp.Core.Infrastructure;

using OurApp.Core.Specs;

using OurApp.Core.Utils;

using OurApp.Core.Utils.LinqSpecifications;

namespace OurApp.Web.UI.LinqSpecifications.OrderSpecifications

{

   public class OrderSecuritySpecForAllocationManager :

         SecurityBasedSpecificationRuleBase<Order>,

         ISecurityBasedSpecificationRule<Order>

   {

      public override bool ShouldApply(UserContext userContext)

      {

         return userContext.AccessMap.IdsOfManagedAllocationPrograms.Count > 0;

      }

      

      public override SpecificationBuilder<Order> Apply(SpecificationBuilder<Order>

            specificationBuilder, UserContext userContext)

      {

         specificationBuilder.AddOr(OrderSpecs.AllocationManagerCriteria(userContext

               .AccessMap));

         return specificationBuilder;

      }

   }

}

 
 

We are aggregating applicable security specs and then running a query based upon those specs. We have to have at least one spec however (or face error) so, if at the end our of spec-building, if we have nothing to use in an IQueryable (due to none of the ShouldApply conditions being met) we use one of these specs.

using OurApp.Core.Entities;

using LinqSpecs;

namespace OurApp.Core.Specs

{

   public class BaseSpecs<T> where T : BaseEntity

   {

      public static Specification<T> Noop()

      {

         return new AdHocSpecification<T>(ssd => ssd != null);

      }

      

      public static Specification<T> EmptySet()

      {

         return new AdHocSpecification<T>(ssd => ssd == null);

      }

   }

}

 
 

We’ve been using Noop everywhere as the failover spec. I realized today that in security-filtering a list of objects that if may be possible to fall through all of the ShouldApply conditions and erroneously return an unfiltered list. It seems like the EmptySet spec is superior for anything that uses security based filtering.

Tuesday, January 17, 2012

OAuth

We watched http://railscasts.com/episodes/241-simple-omniauth which touches on OAuth today. This made me look through my old tweets from this summer's No Fluff Just Stuff on OpenID and OAuth. I dug up the following which includes a few pics of Brian Sletten:

  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic
  • Share photos on twitter with Twitpic

what types should be in a view model?

Joel, Rafael, Byron and I just had a conversation about flattening domain objects to view models with AutoMapper. Rafael suggested that almost everything should end up as a string on the display model as that is what any one data point displayed in HTML is going to end up as anyway. This means that when one flattens a DateTime to a string, that there is a need to make the DateTime presentable as it is being flattened. For example, the absence of .AddFormatter<TextBoxDateFormatter>() below would make the string version of the DateTime by way of a .ToString() operation, creating a very ugly string for a user to see.

private static void CreateGlobalFormatters()

{

   Mapper.ForSourceType<DateTime>().AddFormatter<TextBoxDateFormatter>();

}

 
 

TextBoxDateFormatter:

using System;

using OurApp.Core.Infrastructure;

using AutoMapper;

namespace OurApp.Web.UI.Config.AutoMapper.Formatters

{

   public class TextBoxDateFormatter : IValueFormatter

   {

      public string FormatValue(ResolutionContext context)

      {

         DateTime? value = context.SourceValue as DateTime?;

         return value.HasValue ? value.Value.ToString(DefaultFormats.TextBoxDate) : null;

      }

   }

}

 
 

DefaultFormats:

namespace OurApp.Core.Infrastructure

{

   public static class DefaultFormats

   {

      public const string DatePickerDate = "yy-mm-dd";

      public const string JavaScriptDate = "yyyy-mm-dd";

      public const string TextBoxDate = "yyyy-MM-dd";

      public const string ListItemDelimiter = ", ";

      public const string CustomAttributeEmptySelectionText = "Any";

   }

}

 
 

Now our point of debate: Should this be done or should the DateTime just end up as a DateTime at the DTO for a view? Joel wondered how one might conditionally set a date to be bright red in the view if the date signified something a month overdue? Rafael suggested that for such a calculation, a separate Boolean value would also need to be kept on the DTO in lieu of making a calculation in the view off of a DateTime on the DTO.

Monday, January 16, 2012

crafting set up and tear down steps for Jasmine tests and overriding options when using jasmine-jquery widgets

Set up and tear down like so:

jasmine.getFixtures().fixturesPath = './';

describe("Sorter controlling table", function () {

   var widget = null;

   var filterForm = null;

   beforeEach(function () {

      loadFixtures('fixture1.html');

      var target = $('#listingTableWrapper');

      filterForm = $('#filterForm');

      widget = target.SorterWidget({ form: filterForm });

   });

   afterEach(function () {

      widget.SorterWidget('destroy');

   filterForm = null;v
   });

   describe("
whatever...

 
 

Note: SorterWidget has the following options meaning that line 9 above is overriding the default for one of the options:

options: {

   form: null,

   container: null,

   sortBy: 'Id',

   sortOrder: 'ASC'

}

call a method from another method within the SAME widget within the jasmine-jquery framework

It is different from calling a method from the outside and is probably a lot more like what you are used to.

setSorting: function () {

   var self = this;

   self.sort();

},

sort: function () {

   var self = this;

   
more code follows...

Sunday, January 15, 2012

lacking link :(

Here I elude to bad code here but never give a link. :(

of both null checks in both C# and JavaScript and the null coalescing operator of C#

Doing null checks in C# is tacky. In JavaScript it is impossible. You instead have to see if a thing has a length of 0.

if (sortOrderInput.length == 0) {

 
 

As an aside: The better thing to do in C# is a preventative step like this:

foo = foo ?? new List<Bar>();

 
 

The null coalescing operator is used in the line above. It is the ??

add form fields to a form within the jasmine-jquery framework

Here is how one might put form fields into a form if they are not already there within a jasmine-jquery framework widget:

ensureInputsExist: function () {

   var self = this;

   

   var sortByInput = self.options.form.find('input[name=sortBy]');

   var sortOrderInput = self.options.form.find('input[name=sortOrder]');

   

   if (sortByInput.length == 0) {

      sortByInput = $('');

      self.options.form.append(sortByInput);

   }

   

   if (sortOrderInput.length == 0) {

      sortOrderInput = $('');

      self.options.form.append(sortOrderInput);

   }

   

   sortByInput.val(self.options.sortBy);

   sortOrderInput.val(self.options.sortOrder);

}

 
 

If the above is kept in whatever.js then the following might be tests in whatever.spec.js:

it('should ensure that the hidden inputs are in the form', function () {

   var sortByInput = filterForm.find('input[name=sortBy]');

   var sortOrderInput = filterForm.find('input[name=sortOrder]');

   expect(sortByInput.length).toEqual(1);

   expect(sortOrderInput.length).toEqual(1);

});

   

it('should ensure that the hidden inputs are in the form', function () {

   var sortByInput = filterForm.find('input[name=sortBy]');

   var sortOrderInput = filterForm.find('input[name=sortOrder]');

   expect(sortByInput).toHaveValue('Id');

   expect(sortOrderInput).toHaveValue('ASC');

});

in C# call .GetType() on any object to make a new object of the type of Type

In writing some code with Azadeh today, Reflection started to make more sense to me. One may call .GetType() on any object to make a new object of the type of Type. The new object will have properties such as FullName which reveals the name of the original object and methods like GetMethods() which returns an array of MethodInfo objects that have data notes for each of the methods hanging off the object. Cool stuff. This was one of those ah-ha moments for me.

public void Whatever()

{

   Person person = new Person();

   MakeSenseOfObject(person);

}

   

public void MakeSenseOfObject(object obj)

{

   Type type = obj.GetType();

   string nameOfObject = type.FullName;

   MethodInfo[] methods = type.GetMethods();

   foreach (MethodInfo method in methods)

   {

      string methodName = method.Name;

      
more code follows and goes where you'd like...

Ctrl-G in Visual Studio will allow you to jump to a specific line of code (you give a number) in the class at hand.

Azadeh just taught me this.

how to read from an .asmx web service and how to build your own .asmx web service


I made a simple calculator in a new ASP.NET Web Forms project. There were two textboxes for users to enter numbers and a button one could click to display the sum of the two numbers entered. Here is the web form:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master"

   AutoEventWireup="true" CodeBehind="Default.aspx.cs"

   Inherits="CalculatorThatUsesWebService._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">

</asp:Content>

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

   <h2>The Calculator!</h2>

   <asp:TextBox ID="FirstTextBox" Width="30" runat="server"></asp:TextBox>

   <asp:Label ID="FirstLabel" Width="15" runat="server">+</asp:Label>

   <asp:TextBox ID="LastTextBox" Width="30" runat="server"></asp:TextBox>

   <asp:Button ID="EqualsButton" runat="server" Text="="

         onclick="EqualsButton_Click" />

   <asp:Label ID="LastLabel" runat="server"></asp:Label>

</asp:Content>

 
 

Now here is the code behind's C#. Note that I hand the values to something called "Reference" to do the calculation and then get back the calculation from Reference.

using System;

namespace CalculatorThatUsesWebService

{

   public partial class _Default : System.Web.UI.Page

   {

      protected void Page_Load(object sender, EventArgs e)

      {

      }

      

      protected void EqualsButton_Click(object sender, EventArgs e)

      {

         Reference.CalculatorWebService calculator =

               new Reference.CalculatorWebService();

         int firstInteger = Convert.ToInt32(FirstTextBox.Text);

         int lastInteger = Convert.ToInt32(LastTextBox.Text);

         int magicNumber = calculator.AddTwoIntegers(firstInteger, lastInteger);

         LastLabel.Text = magicNumber.ToString();

      }

   }

}

 
 

Reference is a pointer to an .asmx web service hosted outside of this application at http://www.damisam.com/CalculatorWebService.asmx. Here is how I added it to my application in Visual Studio 2010:

  1. From the Solution Explorer, I right-clicked on the one project in my solution and selected: Add Service Reference...
  2. The "Add Service Reference" dialog appeared and I clicked on the "Advanced..." button.
  3. I ended up at the "Service Reference Settings" dialog box and from here I clicked "Add Web Reference..."
  4. The third dialog box I then saw was "Add Web Reference" and I herein put http://www.damisam.com/CalculatorWebService.asmx in the URL field.
  5. I clicked the green right arrow at the right of the URL field.
  6. I was informed that CalculatorWebService was found.
  7. There was a button for me to click to create a reference that said "Add Reference" on it, but before I clicked the button I changed the suggested name from "com.damisam.www" to just be "Reference."
Addendum 8/22/2015: I am commenting out http://a.yfrog.com/img878/1734/sbf7.jpg which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

 
 

The content above naturally begs the question: "How does one author a web service?" It is pretty easy. Spin up a new web application that you will put online. If you right-click on project in the Solution Explorer and pick Add > New Item... you should be able to find a possibility that is vaguely called "Web Service" at the bottom of the list of items in the "Web" subset of the Visual C# options. Web Services can take many shapes, but we are using an .asmx web service in this case.

Addendum 8/22/2015: I am commenting out http://a.yfrog.com/img878/9611/uyp3.jpg which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

 
 

The .asmx I made just looks like this one line of code when published to be put online at http://www.damisam.com/CalculatorWebService.asmx:

<%@ WebService Language="C#" CodeBehind="CalculatorWebService.asmx.cs"

      Class="WebServiceApplication.CalculatorWebService" %>

 
 

...but it also has a code behind that will get compiled:

using System.Web.Services;

namespace WebServiceApplication

{

   [WebService(Namespace = "http://tempuri.org/")]

   [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

   [System.ComponentModel.ToolboxItem(false)]

   public class CalculatorWebService : System.Web.Services.WebService

   {

      [WebMethod]

      public string HelloWorld()

      {

         return "Hello World";

      }

      

      [WebMethod]

      public int AddTwoIntegers(int initialInteger, int integerToAppend)

      {

         return initialInteger + integerToAppend;

      }

   }

}

 
 

I suppose it is important to note that one must publish an .asmx web service for another to use it. Once made, an .asmx it can't just sit on your laptop. It needs to end up on a web site somewhere so that someone may latch onto it by way of a url such as http://www.damisam.com/CalculatorWebService.asmx.

That is really all there is to it. The .asmx approach is really an old school one. I have familiarized myself with .asmx anew today as I am going to help a friend with this manner of web services in a few minutes. I was able to just dig back into my old notes from Visual Studio 2005 era projects. I'm glad I've kept such good notes over time.

Addendum 8/22/2015: I am commenting out http://a.yfrog.com/img876/8194/fxx1.jpg which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

Saturday, January 14, 2012

touch event handlers in the mobile space and some of the extra data that goes with them

I caught dinner with Jagruthi Mamidi and Azadeth Razaghian yesterday. Jagruthi spoke of a project she had worked on in the android development space in which she calculated the movement of a shape based upon a "touch event." She mentioned that the event carried with it a variable for the amount of force the user gave in touching the touch screen and another variable for the direction the finger was drug across the touch screen.

six bullets on how to get started with the jasmine-jquery framework

We are using the jasmine-jquery widget framework in our application. I've learned how to use it over the past two days and I have written a few job posting on as much. If you'll follow the links below I hope it will give you a high level understanding of the ABCs. There should be more postings after this one too.

how one calls "methods" and passes parameters to the "methods" of Jasmine-friendly widgets

I'll blog more about the framework for using Jasmine later. I want to mention now how one calls methods and passes parameters to the methods of Jasmine-friendly widgets. If one has this in whatever.js...

getOption: function (name) {

   var self = this;

   return self.options[name];

},

options: {

   foo: "bar",

   baz: "qux"

}

 
 

One may interface with getOption method in whatever.js from whatever.spec.js like so:

var currentFoo = widget.Whatever('getOption', 'foo');

 
 

The first "parameter" is the name of the "method" and the subsequent parameters are the parameters for the method. I put "method" in quotes, because I'm not sure what to call these "things" just yet. (I'm learning. Cut me some slack.)

I promise this is the last blog posting on this subject.

In milking the comparison made here to death and in the name of writing blog postings that will interest no one but me: I dug up some old NAAK screen grabs I made from when I maintained an older version of headspring.com before the site was the slick WordPress work that Katie Barbaro crafted. But first, a failing Jasmine test:

 
 

A failing NAAK test:

 
 

Adding in widget.children("#mover").click(); makes the Jasmine test pass:

 
 

Adding in <h1>Hello World!</h1> makes the NAAK test pass.

 
 

I promise this is the last blog posting on this subject.

It's hard to imagine a project using both Jasmine and NAAK.

I woke up this morning and thought of my comparison between Jasmine and NAAK. It makes me chuckle. They kind of display results alike, but they are so very different. Every time a Jasmine test passes I'm guessing (not positive) a NAAK test is going to fail given that it validates accessibility. There was no JavaScript whatsoever (in the name of accessibility compliance) on the Headspring project where NAAK was used. Jasmine and NAAK are almost of two opposite approaches to JavaScript. One is of the roman orgy and the other of puritan abstinence. :P

Friday, January 13, 2012

how to run a Jasmine test

To run the Jasmine test detailed here, I just open SpecRunner.html in a browser and get a red (well, pink) screen in the event of a failure (for example when I take widget.children("#mover").click(); out of widgetExample.spec.js) and a green screen in the event of a success. It kind of reminds me of Kevin Hurwitz's NAAK in this regard.

widgetExample.spec.js tests widgetExample.js. That is the naming convention.

my first Jasmine test!

I wrote widgetExample.js as described in my last posting. I got it under a Jasmine test by having the following three files sit in the same folder with it:

 
 

1. fixture.html:

<div id="wrapper">
   <input id="lefty" />
   <button type="button" id="mover">Move Right -></button>
   <input id="righty" />
</div>

 
 

2. SpecRunner.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

   <title></title>

   <script src="/Scripts/jquery-latest.js" type="text/javascript"></script>

   <script src="/Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>

   <script src="/Scripts/underscore.js" type="text/javascript"></script>

   <link rel="stylesheet" type="text/css" href="/Scripts/jasmine/jasmine.css" />

   <script type="text/javascript" src="/Scripts/jasmine/jasmine.js" ></script>

   <script type="text/javascript" src="/Scripts/jasmine/jasmine-html.js" ></script>

   <script type="text/javascript" src="/Scripts/jasmine/lib/jasmine-jquery.js" ></script>

   

   <!-- target script for testing -->

   <script type="text/javascript" src="widgetExample.js"></script>

   

   <!-- specs for target script for testing -->   

   <script type="text/javascript" src="widgetExample.spec.js"></script>

</head>

<body>

   <table>

      <tr>

         <td>

            <div id="tests">

               <script type="text/javascript">

                  $(document).ready(function () {

                     _.defer(function () {

                        setTimeout(function () {

                           jasmine.getEnv().addReporter(new jasmine.TrivialReporter());

                           jasmine.getEnv().execute();

                        },

                        1000);

                     });

                  });

               </script>

            </div>

         </td>

      </tr>

   </table>

</body>

</html>

 
 

3. widgetExample.spec.js:

//path relative to SpecRunner.html

jasmine.getFixtures().fixturesPath = './';

   

describe("excersise your component's behavior", function () {

   describe("clicking the button copies data appropriately", function () {

      it('copies data successfully', function () {

   

         //arrange

         loadFixtures('fixture1.html');

         var target = $('#wrapper');

         target.children("#lefty").val('foo');

         var widget = target.Example();

         

         //act

         widget.children("#mover").click();

         

         //assert

         expect(widget.children("#righty")).toHaveValue('foo');

      });

   });

});

last refactoring for preparing for Jasmine

Joel gave a deep dive into Jasmine testing today, and I have now successfully written a Jasmine test. Woo hoo! I originally wrote this to test and refactored it to be like this earlier today when I realized I needed to wrap the controls in a div so that I might latch onto the div with jQuery. What the HTML and JavaScript do is present a simple form that allows one to duplicate the contexts of one field (at the left) to another field (at the right) by clicking the only button displayed.

 
 

But, how to test this? Well, I had to do another refactoring. My JavaScript ended up in a file called widgetExample.js and looked like this:

var Example = {

   _create: function () {

   },

   _init: function () {

      var self = this;

      self.setup(self.element);

   },

   setup: function (container) {

      var self = this;

      self.options.container = container;

      self.setupAccessibility();

   },

   getOptions: function () {

      var self = this;

      return self.options;

   },

   getOption: function (name) {

      var self = this;

      return self.options[name];

   },

   setOption: function (key, value) {

      var self = this;

      self.options[key] = value;

   },

   setupAccessibility: function () {

      var self = this;

      self.options.container.children(":button").click(function () {

         var leftvalue = self.options.container.children(0).val();

         self.options.container.children("#righty").val(leftvalue);

      });

   },

   options: {

   }

};

$.widget("amd.Example", Example);

 
 

widgetExample.js was called by this HTML:

<!DOCTYPE html>

<html lang="en">

<head>

   <title></title>

   <script src="/Scripts/jquery-latest.js" type="text/javascript"></script>

   <script src="/Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>

   <script src="/Scripts/underscore.js" type="text/javascript"></script>

   

   <!-- target script -->

   <script type="text/javascript" src="widgetExample.js"></script>

</head>

   <body>

      <div id="wrapper">

         <input id="lefty" />

         <button type="button" id="mover">Move Right -></button>

         <input id="righty" />

      </div>

      <script type="text/javascript">

         $(document).click(function () {

            var target = $('#wrapper');

            var widget = target.Example();

         });

      </script>

   </body>

</html>

latch onto children of an element with jQuery

I rewrote what is here a smidge in the name of getting it under a Jasmine test. In doing so, my rewrite put relevant HTML controls in a wrapping div and then interacted with them as children of the div.

 
 

myscript.js:

$(document).ready(function() {

   $("#wrapper").children(":button").click(function() {

      var leftvalue = $("#wrapper").children(0).val();

      $("#wrapper").children("#righty").val(leftvalue);

   });

});

 
 

myscript.js is called by:

<!DOCTYPE html>

<html lang="en">

   <head>

      <script src="jquery-1.5.js" type="text/javascript"></script>

      <script src="myscript.js" type="text/javascript"></script>

   </head>

   <body>

      <div id="wrapper">

         <input id="lefty" />

         <button type="button" id="mover">Move Right -></button>

         <input id="righty" />

      </div>

   </body>

</html>

 
 

Content put in the left text field gets moved to the right text field when the button is clicked.

Don't query against calculated fields when using IQueryable and LinqSpecs. It doesn't work.

If you have an object called Person with a FirstName and a LastName being hydrated from a database and a FullName being exposed by way of a method on Person as a calculation of the two results...

Expect IQueryable to fail when trying to run a query against FullName.

Wednesday, January 11, 2012

do NOT create collections in JavaScript by splitting flattened gunk out of a string

Why?

In my undertaking of the work outlined in the first link of the second bullet above, I dove deep into collections in JavaScript which I had not before worked with. I made a sloppy mess. There was want for changes. Firstly, when one selected programs and a sample type, it was desired that all of the potential program plans end up selected outright instead of merely becoming potentially selectable. This change wasn't too hard to accommodate in what I wrote, but, later on, when it was discovered that if one had a period in a program name that it would sabotage my code which split strings on periods, there was the need for a ground-up rewrite. Joel's recommendations guided the course taken:

  1. move collections from C# to JavaScript by way of serialization
  2. keep collections as collections, do not flatten collections to strings
  3. do not recreate collections by way of splitting strings as the character one splits with may end up being needed
  4. use hashes instead of arrays, allowing for key value pairs, escaping using a plain-text name as both a unique key and a value, as there may be significant pain in using a plain string as a key (what if one name contains another as in Arkansas containing Kansas?)
  5. use the Guid keys out of the database for rows of records as the unique keys for collection items (there will never be an Arkansas/Kansas conflict)

 
 

This whiteboarding by Joel shows off his ideas. The erased line touches on "it was desired that all of the potential program plans end up selected outright instead of merely becoming potentially selectable" as suggested above. At the right we see a key/value pair data structure for a collection in which the key is a Guid for a program and the value is another key/value pair data structure. The collections within the collection have a Guid-of-program-plan/plain-text-name-of-program-plan key/value shape. The greater collection structure shows how all of the potential program plans for each program in a collection of programs may be kept in a digestible manner.