Wednesday, September 30, 2015

I again saw Joseph Reynolds speak on web performance and load testing.

Unlike the first talk I saw at last year's Code Camp, this talk, at MeasureUP, had as a tangent discussion a bit on how to cast a web test, which records a series of actions and takes health measurements on how snappy it was, to a Selenium test which is more or less the same thing with a validation of a particular workflow's results in lieu of a gauge of how fast the workflow went. I didn't come away with an understanding of how to do it, but it is possible! I guess this means you can write one set of tests for both things if you put your mind to it. You have to have the highest SKU (stock keeping unit) of Visual Studio to do the load testing stuff and it is called "Enterprise" for Visual Studio 2015 though it is "Ultimate" in Visual Studio 2013. Anyhow, a series of web tests can, as a suite, make a load test which may be run repeated emulating x number of users (and thus simultaneous hits) for y number of hours wherein both x and y are variables you set. Joseph had a formula for whether or not your web app can handle the traffic it needs to handle that utilized the x and the y and also had z for "time spent per user" which itself is driven by a different formula that he didn't delve into. If you divide y by z and then take THAT number and divide x by it you will have your answer! The image shown here shows some sample calculations with the x and the y and the z. If you are making your target, try to go beyond it. You need to know where your app breaks because... What if your Mickey Mouse little web site takes off and starts getting flooded with traffic as you hoped it would? You need to know when it is going to fall down as you yet watch things get "better and better" traffic-wise, right? You may see the talk for yourself here and I know this because I found it here which was advertised to me by an email from MeasureUp's keepers a few hours ago. All or at least most (not sure which) of the talks from Saturday were recorded and are watchable online. Per Joseph: Don't start performance testing at the end of a project. Don't think you can just slip that in in the last few months. By then the little problems have metastasized into big ones and you will have your work cut out for you. That said, you really can't start the performance testing in the first iteration either as there is little to test then. Joseph recommends starting six to eight weeks in. That is the sweet spot.

put a method on a function in JavaScript?

Instead of bolting all of the properties from an object onto another object as suggested in the seventh bullet here, prototype may be similarly used to attach just one new property to a function like so:

function Foo(name) {
   this.name = name;
}
 
Foo.prototype.myName = function() {
   return this.name;
}
 
var a = new Foo("a");
var b = new Foo("b");
 
alert(a.myName());
alert(b.myName());

 
 

This example is pretty much just stolen from page 97 of Kyle Simpson's book "this & OBJECT PROTOTYPES as the only thing I've added myself is the alerts wrapping the two last lines. The second to last line will give us "a" in an alert and the last line will afterwards give us "b" in an alert. However, if I were to remove the word prototype from the code above (and, yes, also one of the periods either leading it or following it) the code would not work at all. It would break. You have you use prototype as a keyword to append a property to a function which is kinda ghetto to begin with, eh? This allows a method on a function (is it a "method" if it's not on an object?) to be found via delegation when using a "constructor" which Mr. Simpson's book will make quite clear to you is not really a constructor but instead just a convenience thing that feels like a constructor in another language.

Tuesday, September 29, 2015

Why should I care about Twitter Bootstrap?

This has a list of reasons that I've glanced at and I suppose the bottom line is that a stylesheet has been baked for you so that you don't have to build it from the ground up. If it has both a grid and responsive design built into it then it is not trival to remake. From the outside looking in it feels like a straightjacket and I bet I would start adding dirty hacks to make it do things it wasn't meant to do. Perhaps if you don't know CSS/LESS well you could teach it to yourself by cannibalizing stuff from Bootstrap.

Be careful of the number of decimal places you hand into {0:P} formatting for percentages in C#.

This suggests that .ToString("P", CultureInfo.InvariantCulture)); is going to use the first two decimal places as the first two digits of the percentage so if you want to show a percentage with two decimal places you need to Math.Round what you hand in to four decimals places instead of two. Does that make sense?

Monday, September 28, 2015

Zoom All Windows

You may have to explictly uncheck this checkbox as an option for the Zoom Tool in Adobe Photoshop CS6. With it checked, if you zoom in or out on an image, the other images will zoom comparably. If you have one image zoomed to 200% and you open a new image at 100% size and you then try to zoom out the first image to 100% the second image will shrink too (to 50%). It's annoying.

Sunday, September 27, 2015

Slack?

I was invited to join Slack which sure seems a lot like Microsoft's Lync. Maybe it's Austin geek community specific. I dunno.

 
 

Addendum 12/17/2015: See also https://slack.com/

Saturday, September 26, 2015

Fluent NHibernate is deprecated!

The Austin .NET User Group put on "Code Camp" an all-day-long/one-Saturday-a-year event every year from 2007 to 2014, but there wasn't one this year. Instead, Clear Measure seems to have stepped up to fill the vacuum with its own thing dubbed MeasureUP which sure felt an awful lot like Code Camp and was even held at Saint Eds! What's going on? Technically these things are two separate events, and yet... bah, maybe it's best not to think too hard about it. I saw numerous talks today at MeasureUp and they were all put on by Clear Measure staffers. It was awesome. Expect this blog to have write ups of all the talks I saw yet be patient while I type them up progressively. The keynote or opening or welcome-to-our-event-thing was given by Jeffrey Palermo who runs Clear Measure and once ran The Austin .NET User Group too. This warm up talk was about cyclical patterns in human history and cyclical patterns in software development too. More interesting than this formal talk was a discussion a friend and I had with Jeffrey beforehand, wherein he mentioned that Fluent NHibernate has fallen out of vogue as it has not been kept current with NHibernate itself! It seems that plain Jane NHibernate now has newer features that make it only make sense to use it directly instead of Fluent NHibernate. This caught me by surprise as I really never use NHibernate or Fluent NHibernate anymore. Actually, one of the insights to come from my current employment takes its shape in that I've fallen back in love with stored procedures again. I can live without the second level cache and I can certainly live without the bad SQL ORMs write under the covers and I don't think right-hand/left-hand mappings from datasets to POCOs are the end of the world. I think the right-hand/left-hand stuff is normal. You have to write maps after all in NHibernate anyways, right? The only way out of the right-hand/left-hand problem is with the overhead of reflection. Meh, I digress. I won in a raffle a license for Spread COM and whole experience of the day was really awesome, exactly the sort of fun I'd expect from Code Camp! Again, this is the first of many blog posts to come! Bonus: The picture here contains the password for the guest wireless!

Friday, September 25, 2015

how to make a row below each regular row in a DevExpress ASPxGridView to advertise a verbose data point

  1. in the ASPxGridView tag put inline...
    PreviewFieldName="Whatever"
    ...and herein "Whatever" will be the the appropriate getsetter/property on the POCO for which a collection has been databound to the ASPxGridView.
  2. in the Settings tag inside the ASPxGridView tag put inline...
    ShowPreview="True"

STUFF in T-SQL will let you flatten the values across numerous rows (for one column) into a comma-separated string!

I really don't understand how to use STUFF yet myself.

 
 

Addendum 10/25/2015: Here is an example of STUFF:

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp
SELECT b.RecruiterId, t.Name
INTO #Temp
FROM Bridge b
JOIN Techies t
ON b.TechId = t.TechId
SELECT r.Name AS Recruiter,
STUFF((SELECT ', ' + Name
   FROM #Temp t
   WHERE r.RecruiterId = t.RecruiterId
   FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)')
   , 1, 2, '')
AS Prospects
FROM Recruiters r

 
 

This SQL will give us a report of which candidates recruiters are talking to. (It's a silly example.) There are separate tables for recruiters and the tech people they court. There is also a bridge table called bridge for managing the many-to-many relationship. The tables and their contents look like this:

 
 

In my query I pull a join between the bridge table and the candidates into a temp table and then stuff the temp tables contents into concatenated strings with comma separations between candidate names like so:

 
 

In case you are curious, I used the following SQL to set up the three tables:

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Recruiters
   (
   RecruiterId int NOT NULL IDENTITY (1, 1),
   Name varchar(8) NOT NULL
   ) ON [PRIMARY]
GO
ALTER TABLE dbo.Recruiters ADD CONSTRAINT
   PK_Recruiters PRIMARY KEY CLUSTERED
   (
   RecruiterId
   ) WITH( STATISTICS_NORECOMPUTE = OFF,
   IGNORE_DUP_KEY = OFF,
   ALLOW_ROW_LOCKS = ON,
   ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Recruiters SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
SET IDENTITY_INSERT [dbo].[Recruiters] ON
INSERT INTO Recruiters (RecruiterId, Name) VALUES (1,'Heather')
INSERT INTO Recruiters (RecruiterId, Name) VALUES (2,'Ingrid')
INSERT INTO Recruiters (RecruiterId, Name) VALUES (3,'Jennifer')
INSERT INTO Recruiters (RecruiterId, Name) VALUES (4,'Kristy')
SET IDENTITY_INSERT [dbo].[Recruiters] OFF
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Techies
   (
   TechId int NOT NULL IDENTITY (1, 1),
   Name varchar(6) NOT NULL
   ) ON [PRIMARY]
GO
ALTER TABLE dbo.Techies ADD CONSTRAINT
   PK_Techies PRIMARY KEY CLUSTERED
   (
   TechId
   ) WITH( STATISTICS_NORECOMPUTE = OFF,
   IGNORE_DUP_KEY = OFF,
   ALLOW_ROW_LOCKS = ON,
   ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Techies SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
SET IDENTITY_INSERT [dbo].[Techies] ON
INSERT INTO Techies (TechId, Name) VALUES (1,'Larry')
INSERT INTO Techies (TechId, Name) VALUES (2,'Marty')
INSERT INTO Techies (TechId, Name) VALUES (3,'Norman')
INSERT INTO Techies (TechId, Name) VALUES (4,'Oliver')
INSERT INTO Techies (TechId, Name) VALUES (5,'Pete')
SET IDENTITY_INSERT [dbo].[Techies] OFF
BEGIN
CREATE TABLE dbo.Bridge
(
   BridgeId int IDENTITY NOT NULL,
   RecruiterId int NOT NULL,
   TechId int NOT NULL
) ON [PRIMARY]
ALTER TABLE dbo.Bridge ADD CONSTRAINT
   PK_Bridge PRIMARY KEY CLUSTERED
   (
   BridgeId
   ) WITH (
   STATISTICS_NORECOMPUTE = OFF,
   IGNORE_DUP_KEY = OFF,
   ALLOW_ROW_LOCKS = ON,
   ALLOW_PAGE_LOCKS = ON
   ) ON [PRIMARY]
ALTER TABLE dbo.Bridge ADD CONSTRAINT
   FK_Bridge_To_Recruiters FOREIGN KEY
   (
   RecruiterId
   ) REFERENCES dbo.Recruiters (
   RecruiterId
   ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.Bridge ADD CONSTRAINT
   FK_Bridge_To_Techies FOREIGN KEY
   (
   TechId
   ) REFERENCES dbo.Techies (
   TechId
   ) ON UPDATE NO ACTION ON DELETE NO ACTION
END
GO
INSERT INTO Bridge (RecruiterId, TechId) VALUES (1, 1)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (1, 2)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (1, 3)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (2, 2)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (2, 3)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (2, 4)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (2, 5)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (3, 1)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (3, 3)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (3, 5)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (4, 1)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (4, 2)
INSERT INTO Bridge (RecruiterId, TechId) VALUES (4, 4)

 
 

I'm glad I keep such good notes. I used the following as a crutch I crafting what is immediately above:

  1. http://tom-jaeschke.blogspot.com/2013/03/insert-into-numeric-primary-key-column.html
  2. http://tom-jaeschke.blogspot.com/2015/06/the-classic-mssql-bridge-table.html
  3. http://tom-jaeschke.blogspot.com/2015/09/cursors-are-ghetto-just-select-directly.html

Cursors are ghetto. Just select directly to temp tables and table variables.

Note the difference between the two in T-SQL here and the how-to explaination here. For a table variable you will approach it like so:

DECLARE @Widgets TABLE
(
   WidgetId int NOT NULL,
   WidgetName NVARCHAR(50) NOT NULL
)
INSERT INTO @Widgets
SELECT WidgetId, WidgetName FROM dbo.Widget
SELECT * FROM @Widgets

 
 

A temp table can be approached in an easier manner:

IF OBJECT_ID('tempdb..#Widgets') IS NOT NULL DROP TABLE #Widgets
SELECT WidgetId, WidgetName INTO #Widgets FROM dbo.Widget
SELECT * FROM #Widgets

Thursday, September 24, 2015

how to use the stamp tool in Adobe Photoshop

https://40.media.tumblr.com/b260c05d8459dbeee868932b257b073c/tumblr_num9i1Qs0z1rocrnwo1_r1_1280.jpg has a photo of Sarah Gadon which was taken by David Cronenberg's daughter Caitlin which I found online at tumblr. I thought it was pretty good, but clearly it also needs some love.
The first step in using the Rubber Stamp Tool is to select it. I guess it's called the Clone Stamp Tool in modern incarnations of Photoshop. Whatever.
When you just click and drag with this tool it will start copying the image from a second predefined point so before you just click and drag you will need to pick the predefined point. If you don't, Photoshop will squawk at you in objection. If you hold the Alt key and then left-click you may pick the "copy from" point. Above I have the cursor over the center of Sarah's left eye and I'm holding the Alt key. I click the mouse to pick this point.
I now release both the Alt key and the mouse and move the cursor to the center of Sarah's forehead. Once I left-click and drag I start drawing over the image at the "copy to" point the portion of the image at the "copy from" point. Get it?
There! Now Sarah is even more beautiful! Who would have thought that was possible?

Upgrade a Visual Studio solution to use DevExpress 15.1.

After you've run the installer you oughta be able to open Visual Studio 2013 and just go: DEVEXPRESS > Project Converter > Project Converter v15.1...

The way canned GridViewCommandColumn buttons are specified in web forms has changed between version 13.1.9.0 and 15.1.4.0 of DevExpress.

<dx:GridViewCommandColumn Width="150px">
   <ClearFilterButton Visible="true">
   </ClearFilterButton>
   <EditButton Visible="true">
   </EditButton>
   <NewButton Visible="true">
   </NewButton>
   <DeleteButton Visible="true">
   </DeleteButton>
</dx:GridViewCommandColumn>

 
 

...now becomes one long, single line of markup like so...

<dx:GridViewCommandColumn Width="150px" ShowClearFilterButton="True"
      ShowEditButton="True" ShowNewButton="True" ShowDeleteButton="True" />

 
 

The old markup will cause an error so you have you make the change.

How do I put a user in a group for the IsUserInRole trick in C#?

if (!System.Web.Security.Roles.IsUserInRole("Whatever"))
{

 
 

I can't get this to work. A coworker thought that the "roles" were really "groups" (under "Server Manager" at Windows Server 2008 at "Groups" beneath "Local Users and Groups" beneath "Configuration") but that's not panning out for me.

Wednesday, September 23, 2015

In TortoiseSVN, instead of right-clicking on a folder and picking "Export..."

...just click on the folder and click "OK" and you will get a new folder named consistent with the folder you are downloading from in/at the folder at your PC that you were within. (You would have wanted to right-click in the white space within that folder to begin with to pick "TortoiseSVN" to make the association.)

Use a DevExpress ASPxGridViewExporter to make an Excel sheet of the rows in an ASPxGridView!

Put one in the markup like so...

<dx:ASPxGridViewExporter ID="MyExporter" runat="server" GridViewID="MyGrid">
</dx:ASPxGridViewExporter>

 
 

...wherein MyExporter is wired up to scrape the rows of MyGrid, and then, at the right spot in C# in your workflow, call out to it (MyExporter) like so:

GridExporter.FileName = "Whatever";
GridExporter.WriteXlsToResponse();

 
 

Google Chrome will just start downloading Whatever.xls based upon the C# above once it's triggered. Note that if you don't want to show a column in the excel sheet you need to first hide it at the ASPxGridView. There may also be another way to go about this at the ASPxGridViewExporter itself, but I haven't researched it and I'm just keeping it simple for this example. Other options beyond dumping to a .xls seem to include:

  • WriteCsvToRepsonse
  • WritePdfToResponse
  • WriteXlsxToResponse

Throw away the pagination and always show all records at a DevExpress ASPxGridView.

This touches on a C# side solution, but I just shoved it into the app I'm working on at the markup like so:

<SettingsPager Mode="ShowAllRecords"/>

Tuesday, September 22, 2015

Does a value exist in a dictionary in C#?

This test passes...

using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Tests
{
   [TestClass]
   public class DictionaryTests
   {
      [TestMethod]
      public void Test()
      {
         Dictionary<int, string> dictionary = new Dictionary<int, string>();
         dictionary.Add(13, "foo");
         dictionary.Add(42, "bar");
         dictionary.Add(69, "baz");
         dictionary.Add(88, "qux");
         Assert.AreEqual(dictionary.ContainsValue("foo"), true);
      }
   }
}

Set the background color in CSS back to having no setting at all!

.overpowerMe {
   background-color: transparent !important;
}

Mozy

...is an online backup service.

A DevExpress ASPxGridView column may be grabbed ahold of not only by position like any other item in a list in C# but also by FieldName and Caption!

These are legit:

  1. var foo = myGrid.Columns[13];
  2. var foo = myGrid.Columns["NumberOfCats"];
  3. var foo = myGrid.Columns["Kitty Count"];

"if any" is a little easier to read than "if count is greater than zero" in C#

List<AwfulError> awfulErrors = GetAwfulErrors();
if (awfulErrors.Any())
{

 
 

...is less ghetto than...

List<AwfulError> awfulErrors = GetAwfulErrors();
if (awfulErrors.Count > 0)
{

Sunday, September 20, 2015

React.js 101

On Tuesday night I saw Travis Swicegood (center left) speak on Flux and Tim Tyrrell (center right) speak specifically on the views concept within Flux at Austin JavaScript. What is Flux? It is an architecture that Facebook uses in which data flows in one direction. In an AngularJS app there may be two way data data-binding, but there is none of that in Flux. Data flows from actions to dispatches to stores to views and then views may allow users to call out to actions such that the cycle recycles. In keeping with drawing a contrast to AngularJS, just as you might be told in a stereotypical what-is-Angular? orientation that the four concepts to understand are filters, services, directives, and controllers there are also four concepts to get your head around in Flux and I've just mentioned them too. Let's dig deeper. They are:

  1. actions
    These are the events in your app, the click and/or double-click of a button and the like.
     
     
  2. dispatches
    These keep track of everything that is happening. They are switchboard operators. What is supposed to be the reaction to an action on the code's part? ...and so on. It used to be that Flux, which is node-based, was only a concept, but now one may run...
    npm install flux
     
    ...and actually get a skeleton for a Flux project! The code you will be given will be pretty sparse, but what there is to see will largely be in the shape of dispatches. The actions, stores, and views will be less fleshed out. This is a way to get started. Dispatches push data into the data stores and as much updates what users see in the views.
     
     
  3. stores
    Keep data here. How they work and what shapes they take is left almost completely undefined in formal Flux dogma. Don't expect any guidance from the node package. It's not even true to say that stores have to be hydrated by something persistent beyond in-memory JavaScript state and to sync up against such an other service. At this other talk I did hear, before the talk started, a chunk of an intellectual discourse on whether it was wise to have just one store or many and in the case of many if child stores are updating a fat central parent what some of the challenges might be. Again, this is all up in the air and up to you. It seems like I might one day, after this all shakes out, go to a tech talk on the "right way" to do stores, but that isn't going to happen in 2015.
     
     
  4. views
    The presentation layer in a Flux app is always going to be written in React.js. That is how views take shape. They may live non-intrusively in an existing page within an existing app. Tim somehow had... I dunno, a plugin for Google Chrome perhaps, which highlighted the areas which were React.js-driven in red at various web sites that used it and sometimes there would be a red box in a sidebar and sometimes there would red tint washing over the whole of a site. Go nuts as deeply or as little as you'd like. This is not all-chips-in gambling. Just use it where you want to use it. Again, in drawing a contrast to AngularJS, Tim suggested that he did not think it was wise to learn a very heavily-baked and do-things-our-way massive API for writing JavaScript, not given how quickly things change in the JS space. He has a history of slogging through jQuery taco hell (tacos are groupings of .js and .css files perhaps using something called JavascriptManager???) and would rather see you get your hands dirty than to be so "mature" that you're above playing in the mud. In React.js there are stateless components, smart components, and high order components, but I didn’t really take away from the talk what the distinction was between the three. Anyways, React.js is component-based. It's simple and declarative and easy to troubleshoot. Imagine, how in AngularJS how when something breaks and you try to step through the code to figure out what's up and you end up bouncing around in the thousands of lines of rat's nest that is Angular before things blow up and throw up an opaque unhelpful error message which cannot be googled. (All you can do in these scenarios is walk backwards from what you just did.) That shouldn't happen in the React.js space. Use webpack to wire up React.js. It's like browserify. index.js is the entry point for a React.js app. Some of Tim's code:
    import React from 'react';
    import Editor from './inlineEdit';
     
    React.render(
       <Editor text={false}/>,
       document.getElementById('root')
    );

     
    I think the above is his index.js. The render above is going to put a component to the screen. It's going to call out to inlineEdit.js which will give you some text that you may then click to edit in a textarea. Pressing the escape key makes the editable area just copy again without saving your change and pressing return makes the editable area text again while retaining you change.
    import React, { Component, PropTypes } from 'react';
    import $ import 'jquery';
     
    class InlineEdit extends Component {
       constructor(props){
          super(props);
       }
       
       state = {
          editing: false,
          text: this.props.text
       }
       
       static propTypes = {
          text: PropTypes.string
       }
       
       static defaultProps = {
          text "Some words"
       }
       
       _goToEditMode = () => {
          this.setState({editing: true}, () => {
             $(this.refs.editText.getDOMNode()).select();
          });
       }
       
       _keyAction = (e) => {
          if(e.keyCode === 27){
             this.setState({editing: false});
          } else if (e.keyCode === 13)
             this.setState({editing: false, text: e.target.value});
          }
       }
       
       render() {
          if(this.state.editing){
             return <input type="text"
                defaultValue={this.props.text}
                onKeyUp={this._keyAction}
                ref='editText'
             />
          } else {
             return <div onDoubleClick={this._goToEditMode}>{this.props.text}</div>;
          }
       }
    }

     
    There might be something between ref='editText' ...and... /> above. I'm not sure. Tim coded on the fly and I took a bunch of pictures of it (it was projected on a screen) with my phone. What is above is what I've pieced together in looking back at the photos I took. You can see how he loops in jQuery as an external dependency. Also, the HTML-within-JavaScript craziness is JSX a JavaScript syntax extension that is kinda XMLesque.

 
 

Addendum 10/8/2015: TACO may actually reference Tools for Apache Cordova. I'm not sure.

The ECMA of ECMAScript stands for European Computer Manufacturers Association.

stupid acronyms, I hate chasing down your long forms

Saturday, September 19, 2015

GC.Collect(); forces garbage collection in C#. Hey, I didn't know that!

This was one of many tricks I was treated to on Monday night. I saw Cap Diebel of Denim Group (pictured at right) speak on security in the ASP.NET space at the Austin .NET Users Group. He used OWASP's ZAP (Zed Attack Proxy) to record HTTP requests and then doctor them up and resend them reshaped in the name of pen testing and he suggested that Barb and Sweet (hope I have those names right) were similar tools. He suggested that the validator controls in web forms were a very good thing to embrace and beyond this in a bigger way seemed to prefer web forms to MVC. He said that early versions of MVC had a gremlin in which the Anti-CSRF (!Cross-Site Request Forgery) token will be checked to see if it exists but not if it belongs to the right person. He offered that ASP.NET in general, not just web forms, offers the best out-of-the-box security of any framework, but yet cautioned that there is still plenty to worry about. He detailed nine "Domains of Application Security" as he saw them. They were as follows:

  1. Trust Boundaries
    _EventValidation is a token that one may use to verify that a web form, when posted to, was posted to from itself as opposed to from elsewhere. This can guard against faking/forcing the button click of a disabled button.
    <pages enableEventValidation="false" />
     
    ...goes in Web.config inside the system.web stuff if you want to explicitly turn it off. You have to explicitly turn off the event validation in AngularJS apps that tie into .NET. Angular oversteps. The ViewState is Base64 encoded. If you do security checks inside of your Page_Load event make sure you do it every time. Do not conditionally sidestep it in the Page.IsPostBack scenarios. ASP.NET Sessions are really just kept in cookies and when "logging out" of a web app it has been recommended that one go about it like so:
    Session.Abandon();
    Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));

     
    However, Cap suggested that SessionIDManager is the more modern way to go about this. His code snippet looked like this:
    SessionIDManager Manager = new SessionIDManager();
    string newSessionID = Manager.CreateSessionID(Context);
    Manager.SaveSessionID(Context, newSessionID, out redirected, out isAdded);

     
     
  2. Authentication
    Be sure your client's claim ticket distinguishes who they are, why they are there, and what application they are authenticated for. Claims-based authentication is Microsoft's way of doing OAuth type stuff. The code snippet that Cap had for it looked like this:
    [RoutePrefix("api/claims")]
    public class ClaimsController : BaseApiController
    {
       [Authorize]
       [Route("")]
       public IHttpActionResult GetClaims()
       {
          var identity = User.Identity as ClaimsIdentity;
          var claims = from c in Identity.Claims
             select new
             {
                subject = c.SubjectName,
                type = c.Type,
                value = c.Value
             };
          return Ok(claims);
       }
    }

     
     
  3. Authorization
    ACLs (Access Control Lists) are probably fine. Some of Cap's configuration markup for as much looked like this:
    <configuration>
       <system.webServer>
          <security>
             <authorization>
                <remove users="*" roles="" verbs="" />
                <add accessType="Allow" users="" roles="Staff" />
             </authorization>
          </security>
       </system.webServer>
    </configuration>

     
    How can you keep inappropriate users from accessing uploaded PDFs? I once worked on an app where the solution was to associate the PDFs with the wrong mime type in IIS and then fix the problem conditionally, but Cap's solution was to build a page whose sole purpose is to stream PDFs in a response. By the way, what if someone is uploading the PDFs so that they may be downloaded? You probably want to put a limit on the size of what can be shoved up to your hosting. It's hard to fill up memory and kill it in an attack, but Disk I/O is pretty easy to abuse if an avenue for abuse is provided.
     
     
  4. Input Validation
    Use positive validation for inputs. Screen for what you want and not what you don't want (negative validation). How do you do this? That's right. You use regular expressions. The .NET Validator Framework will perform RegEx validations both client-side and server-side. SDL Regex Fuzzer is a tool Cap suggested using to see if regular expressions are wasteful. For example:
    ^[hc]at
     
    ...is going to match against either "hat" or "cat" and as it has a finite length it has a pretty great shape, however...
    ^(\d+)^$
     
    ...can match any length of digits greater than zero (replace the + with a * to match ANY number of digits) and thus can spin and spin trying to validate a sinister input that is really long!
     
     
  5. Information and Error Handling
    If one injects a script tag with...
    document.body.innerHTML = whatever;
     
    ...in it they may rewrite your page should the contents bubble back up in a Literal or a Label in web forms because both of these controls allow for HTML to be interpreted as HTML and, hence, a script tag may be injected.
     
     
  6. Non-Repudiation and Auditing
    Be wary of attempts to inject something into your logs to making the logging stop to hide a problem downstream! log4net will only end a log file if the file size is too big and that should be the standard for as much, but a more Mickey Mouse solution may come with some pitfalls! The Event Viewer is not a good triage tool. You need logs of your own beyond those for IIS.
     
     
  7. Data Protection
    Don't put the encryption key for your password hashing in Web.config. It should be kept in a tightly controlled directory or as a registry key. Don't get creative and write your own algorithm for password hashing and don't use an existing implementation that is dated.
     
     
  8. Configuration and Deployment
    Sign assemblies to protect your Microsoft intermediate language (MSIL) code.
     
     
  9. Defense in Depth
    Don't rely on one safeguard! Two backend systems which talk only to each other and do so behind a firewall should, nonetheless, do so securely. Don't bank exclusively on the firewall's protection, etc.

Friday, September 18, 2015

It's a convention in JavaScript to name classes in Pascal case instead of camel case.

But of course, they are not really classes. In this example though...

var bar = new foo();

 
 

...the function the foo function corresponds to should probably have been named Foo not foo if the author envisioned it being used in this manner. Again, this is all just goofy tomfoolery as there are no classes in JavaScript. This note about conventions comes from Kyle Simpson's book "this & OBJECT PROTOTYPES" which is all about JavaScript.

compound assignment operators in C#

We've probably all seen the &= in string concatenation but did you know that is also exists in boolean assignments?

isFoo &= isBar;

 
 

...is kind of like...

isFoo = (isFoo && isBar);

 
 

...assuming both isFoo and isBar are bool types. There is also...

isFoo |= isBar;

 
 

...should one of the two be true per this.

.eml is a file format for emails

Installing Antix does not install a reader for .eml files. I am going to drag these files to my main machine where Outlook is running in order to open them.

Thursday, September 17, 2015

Put a Lambda expression inside of a Single() or a FirstOrDefault in C#.

Category category = categories.Where(x => x.CategoryId == whatever).Single();

 
 

...may be rewritten as...

Category category = categories.Single(x => x.CategoryId == whatever);

 
 

This is also legit code:

Category category = categories.FirstOrDefault(x => x.CategoryId == whatever);

If you query a bridge table into a simple type and you then want to cast the pairs of ids to a dictionary in C#...

Lambda magic for that is:

List<Bridge> bridges = GetStuff();
Dictionary<int, List<int>> cleanResults = bridges.GroupBy(foo =>
      foo.FooId).ToDictionary(bar => bar.Key, bar => bar.Select(x => x.BarId).ToList());

 
 

Without the .ToDictionary you would just have...

List<Bridge> bridges = GetStuff();
IEnumerable<IGrouping<int,int>> cleanResults = bridges.GroupBy(foo =>
      foo.FooId);

Wednesday, September 16, 2015

psql

It is an "interactive terminal" which serves as a front end for interacting with PostgreSQL. You shove in command line commands to do stuff.

Tuesday, September 15, 2015

Lists and Arrays may be upcast to IEnumerable collections in C#!

Consider this:

using System.Collections.Generic;
namespace Whatever.Models
{
   public class Smasher
   {
      public string Smash(IEnumerable<int> numbers)
      {
         string concatenation = "";
         foreach (int number in numbers)
         {
            concatenation = concatenation + number;
         }
         return concatenation;
      }
   }
}

 
 

These two tests pass without the compiler freaking out:

using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Whatever.Models;
namespace Whatever.Tests.Models
{
   [TestClass]
   public class SmasherTests
   {
      [TestMethod]
      public void TestWithArray()
      {
         
//arrange
         int[] numbers = new int[] { 13, 42 };
         Smasher smasher = new Smasher();
         
         
//act
         string feedback = smasher.Smash(numbers);
         
         
//assert
         Assert.AreEqual(feedback, "1342");
      }
      
      [TestMethod]
      public void TestWithList()
      {
         
//arrange
         List<int> numbers = new List<int>() { 13, 42 };
         Smasher smasher = new Smasher();
         
         
//act
         string feedback = smasher.Smash(numbers);
         
         
//assert
         Assert.AreEqual(feedback,"1342");
      }
   }
}

Drop something out of a dictionary by way of a unique key in C#.

myDictionary.Remove(13);

Just hover over the var keyword in Visual Studio and you'll be told what C# type the variable is.

I'm not sure if it's ReSharper that's doing this or not, and I'm not sure if I've already blogged of this.

star-followed-by-tab shortcut with Red Gate SQL Prompt

SELECT * FROM MyTableOfStuff

If you press tab after the asterisk SQL Prompt should replace the asterisk with a comma seperated list of all of the columns in MyTableOfStuff. In trying to get this to work a moment ago I actually had to backspace the asterisk away and press Shift-8 to recreate it before the tab did the act.

READONLY at a stored procedure variable

Why would you care? Well, you need to do it for stuff like this when you are handing a table as a variable as this suggests you will otherwise get an error.

type "Credential Manager" at the start menu of Windows 7 to get the Credential Manager

Whenever you change your LAN password you might also want to change it here to make sure it is synced so that you won't get shutout somehow do to a collision of concerns which causes failed login attempts with a bunk password. Make sure the application pools in IIS and Windows Services also don't have old passwords.

Saturday, September 12, 2015

Lyft is a rival to Uber.

I heard about it for the first time today. There is a smartphone app for it. (There, I made the blog posting about tech!)

make tabs with CSS

In this talk Tim Thomas showed off how to make tabbed content work without any JavaScript, using CSS exclusively. I tried to emulate what he had and could not. I ended up getting something working but it is a little more hacky than what he offered. It looks like this:

<!DOCTYPE html>
<html>
   <head>
      <title>Whatever</title>
      <style type="text/css" media="all">
         body {
            background-color: #DDEEEE;
         }
         #content {
            padding: 5px;
            width: 200px;
         }
         #content span {
            display: none;
         }
         #innerWrapper {
            border: 1px solid #000000;
            background-color: #FFFFFF;
         }
         input[type=radio] {
            display: none;
         }
         label {
            cursor: pointer;
         }
         #outerWrapper {
            display: table-cell;
            padding: 50px 20px 20px 20px;
         }
         #tabs {
            margin: -37px 20px 0 20px;
            border-left: 1px solid #000000;
         }
         #tabs div {
            display: table-cell;
            border-right: 1px solid #000000;
            border-top: 1px solid #000000;
            border-bottom: 1px solid #000000;
            height: 30px;
            padding: 5px 5px 0 5px;
            background-color: #F2F2F2;
            cursor: pointer;
         }
         #foo:checked ~ #content .foo {
            display: block;
         }
         #foo:checked ~ #tabs .foo {
            background-color: #FFFFFF;
            border-bottom: 1px solid #FFFFFF;
         }
         #bar:checked ~ #content .bar {
            display: block;
         }
         #bar:checked ~ #tabs .bar {
            background-color: #FFFFFF;
            border-bottom: 1px solid #FFFFFF;
         }
         #baz:checked ~ #content .baz {
            display: block;
         }
         #baz:checked ~ #tabs .baz {
            background-color: #FFFFFF;
            border-bottom: 1px solid #FFFFFF;
         }
         #qux:checked ~ #content .qux {
            display: block;
         }
         #qux:checked ~ #tabs .qux {
            background-color: #FFFFFF;
            border-bottom: 1px solid #FFFFFF;
         }
      </style>   
   </head>
   <body>
      blood stains, ball gowns, trashin' the hotel room...
      <div id="outerWrapper">
         <div id="innerWrapper">
            <input name="tab" id="foo" type="radio" checked />
            <input name="tab" id="bar" type="radio" />
            <input name="tab" id="baz" type="radio" />
            <input name="tab" id="qux" type="radio" />
            <div id="tabs">
               <div class="foo"><label for="foo">foo</label></div>
               <div class="bar"><label for="bar">bar</label></div>
               <div class="baz"><label for="baz">baz</label></div>
               <div class="qux"><label for="qux">qux</label></div>
            </div>
            <div id="content">   
               <span class="foo">My friends and I, we've cracked the code.</span>
               <span class="bar">We count our dollars on the train to the party.</span>
               <span class="baz">And, everyone who knows us knows that we're fine with
                     this.</span>
               <span class="qux">We didn't come from money.</span>
            </div>
         </div>
      </div>
      ...jet planes, islands, tigers on a gold leash
   </body>
</html>

 
 

What is above makes something like what is shown below. Notice the active tab is white and there is no black line at the bottom (I'm stamping over it with white line). I wish I didn't have to set a width on #content and I wish the width that the children of the div before it end up forcing upon their parent was the law of the land, but that is not to be. If I leave a width off of #content then the words in it will not wrap. My solution is kinda ghetto I guess.

Friday, September 11, 2015

Find the value (not the displayed text) of a particular item at a DevExpress ASPxComboBox, by matching against a string, and then make that item the selected item.

string whatever = "whatever";
MyList.Items.FindByValue(whatever).Selected = true;

private const strings which are class-wide, or controller-wide, or code behind-wide should probably be in Pascal Case (or maybe, alternatively all caps)

They should break with the camel-case-with-a-leading-underscore convention that private variables which are class-wide, or controller-wide, or code behind-wide typically deserve in C#.

when TortoiseSVN seems to only show on the latest revision for "Show log"

Well, if you're me you've just drug the vertically-adjustable expandable area for the revision line items completely closed and you just need to drag it back open again. I really struggled with this mistake. I pulled things down out of source control anew and I even reinstalled Tortoise. dumb, dumb, dumb

Don't expect display: table-cell; and margin settings to dance together.

It's pretty frustrating, but, hey, I got to eat today so maybe life's not all bad.

Thursday, September 10, 2015

see if a file exists with C#

public bool IsAnExistingFile(string filePath)
{
   return File.Exists(filePath);
}

AlternatingRow-Enabled

This is the setting to make rows alternate colors in a DevExpress ASPxGridView. Just inside of the dx:ASPxGridView tag you will need:

<Styles Header-Wrap="True" AlternatingRow-Enabled="True" />

UNC is Universal Naming Convention

As opposed to a file share paths which start with a drive letter, UNC paths start with double backslashes and look like this:

\\ABC123\Users\tjaeschke

 
 

In this example ABC123 is the name of the computer on the LAN.

How do I cast a DOM element to a string in JavaScript?

Can you get .innerHTML from its parent perhaps? If it's not the only child of the parent or if it has some text sitting beside it you would have to split the string in this approach.

Make an Eval in a DevExpress ASPxGridView format a datetime in a manner other than the ugly default.

<dx:GridViewDataColumn FieldName="MyDate" VisibleIndex="7">
   <DataItemTemplate>
      <%# Eval("MyDate") %>
   </DataItemTemplate>
</dx:GridViewDataColumn>

 
 

...needs to instead become...

<dx:GridViewDataColumn FieldName="MyDate" VisibleIndex="7">
   <DataItemTemplate>
      <%# Eval("MyDate", "{0:M/d/yyyy}") %>
   </DataItemTemplate>
</dx:GridViewDataColumn>

The rel attribute in HTML tags!

This suggests that the browser never uses it and that it is really just a place to keep some metadata that search engines might care about. nofollow links (put "nofollow" inside the rel attribute) used to be mildly trendy a while back. This suggests they are a way to tell search engines not to crawl a link. In this training rel was suggested to me to be good extra attribute to use in WatiN testing to store some bit of information at a tag. WatiN would then sniff out the whatever-it-was. It was wise to use this thing as it was recognized and yet you weren't really going to use it for something else. I really can't remember the context.

Wednesday, September 9, 2015

Periscope

This app lets you advertise your phone's camera so that others may see out of it from their phones for a window of time while you keep the service up.

try/catch in T-SQL

This suggests that you'll wrap a blob of SQL in bookends of BEGIN TRY and END TRY and follow it up with another blob with bookends of BEGIN CATCH and END CATCH such that END TRY is immediately follwed by BEGIN CATCH. To make the catch throw the error use THROW and if you don't the exception will be swallowed.

I guess with Lean one does not estimate and one just works on what one has to work on anyways.

Not so with Scrum. You'd better be getting something out of the points you're putting on stories to rationalize using Scrum over Lean. I say this having never working on a Lean team though. Story points are not exactly hour estimates but you are still ballparking something.

How do I break out of a DevExpress callback in favor of a postback while also carrying some state along for the ride?

To make a CustomButtonCallback event for a DevExpress ASPxGridView as suggested here download a file as suggested here you cannot have the act occur within a callback. Alright, well you can always use ASPxWebControl.RedirectOnCallback to redirect out of the callback (remember, you cannot use the familiar Response.Redirect of web forms land in a callback) and in redirecting you could just redirect to the same page and then put something at the URL line which you might then drink out of their as state in the Page_Load event. The applicable thing for the file download scenario might be a file path to the file, right? But what if someone then manually refreshes the page? That will cause a second download right? How do we wiggle away from that? I recommend doing something like so:

private void CleanAwayUrlLineVariablesAndSessionStateCounterParts()
{
   string filePath = Session["filePath"] as string;
   if (filePath != null)
   {
      Session["filePath"] = null;
      OfferUpDownload(filePath);
   }
   filePath = Request.QueryString["filePath"] as string;
   if (filePath != null)
   {
      Session["filePath"] = filePath;
      RedirectTheReportToItself(null);
   }
}

 
 

Alright, we are going to call this thing from the Page_Load as the very last act in the Page_Load. OfferUpDownload does what you'd expect and it is our end goal to run that method. If we can get that far then all of the hoops we've jumped through along the way were successfully navigated. RedirectTheReportToItself, as I envision it, will not just be called from this method. If we hand in null we are doing either an ASPxWebControl.RedirectOnCallback or Response.Redirect conditionally based upon...

if (Page.IsCallback)
{

 
 

...while not appending a variable at the URL line, but if the CustomButtonCallback event uses the same method it may hand in a string or something else which will signal the method to, yes, redirect while appending a variable at the URL line. Get it? Anyhow, once will have a URL variable there is no way to make it go away without another Response.Redirect, so let's tuck its contents into Session and then redirect the page to itself to clean up the URL. What will we do about the Session variable? If we yet refresh the page, won't the Session variable be there to force a file download a second time? I guess we have to destroy the Session too. Luckily we can do that without another redirect roundtrip. Could we have just put something in Session to begin with and skipped the Request.QueryString heartache. No we cannot. You cannot shove stuff into Session from a callback kids. Bonus: When I do all this, my page seems to retain other state crafted in callbacks, but I cannot explain why. Whatever.

Tuesday, September 8, 2015

Could not load file or assembly 'Foo.DLL' or one of its dependencies. The specified module could not be found.

This has a write up on how to find the name of a .dll that your .dll cannot seem to find itself when your .dll starts barfing up an opaque error like this. I haven't tried it myself. Dependency Walker might be a tool one may use for this challenge too. I'm not sure.

get custom buttons working at a DevExpress ASPxGridView

Make the button in/at one of the columns like so in the ASP.NET markup:

<dx:GridViewCommandColumn Caption="Whatever" ButtonType="Link">
   <CustomButtons>
      <dx:GridViewCommandColumnCustomButton Text="Download">
      </dx:GridViewCommandColumnCustomButton>
   </CustomButtons>
</dx:GridViewCommandColumn>

 
 

Do you want to only show a link for some records?

private void ReportGrid_HtmlCommandCellPrepared(object sender,
      ASPxGridViewTableCommandCellEventArgs e)
{
   if (e.CommandColumn.Caption == "Whatever")
   {
      if (e.KeyValue != null)
      {
         if (String.IsNullOrEmpty(TryToFindDownloadPath(e.KeyValue)))
         {
            e.Cell.Text = "";
         }
      }
   }
}

 
 

This method is referenced above:

private string TryToFindDownloadPath(object fileId)
{
   int matchMe = (int)fileId;
   foreach (Foo foo in _data.Where(foo => foo.FileId == matchMe)) {return foo.Path;}
   return null;
}

 
 

What happens when the link is clicked?

protected void Download_Callback(object sender,
      ASPxGridViewCustomButtonCallbackEventArgs e)
{
   var foo = (Foo)ReportGrid.GetRow(e.VisibleIndex);
   var id = foo.UniqueId;
   MakeTheFileDownloadHappen(id);
}

 
 

Obviously, this magic requires that two events be wired up to your grid.

ReportGrid.CustomButtonCallback += Download_Callback;
ReportGrid.HtmlCommandCellPrepared += ReportGrid_HtmlCommandCellPrepared;

 
 

In the above _data is a collection of Foo which is bound to ReportGrid which is an ASPxGridView. Get it?

Do you ever wonder when you started your day as you try to make sure you were at work working for X hours?

If you're like me, you probably hit your favorite browser as soon as you logged in. Look at the browser history, it will tell you when your day started.

When I try to make the browser cough out a .txt file as if said file were being downloaded, the copy inside gets the HTML of the current page appended after the real copy I want to include.

In C# your code for as much might look like so:

byte[] bytes = File.ReadAllBytes(pathToFlatFile);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=foo.txt";
HttpContext.Current.Response.AddHeader("Content-Length", bytes.Length.ToString());
HttpContext.Current.Response.ContentType = "text/plain";
HttpContext.Current.Response.OutputStream.Write(bytes, 0, bytes.Length);
HttpContext.Current.Response.Flush();

 
 

This suggests that the solution is to chase the lines above with:

HttpContext.Current.Response.End();

 
 

...but I put the line with the .End(); immediately before the line with the .Flush(); and that seemed to work too!

Sunday, September 6, 2015

more notes of the Tim Thomas CSS talk

https://github.com/TimGThomas/stateful-css-slides/ has all of Tim's slides which one may right arrow and left arrow back and forth through. They sit on top of a series of radio buttons which are hidden and dressing up the "slides" in much the same manner a checkbox is hidden to make copy on/off clickable here. There is an example in Tim's stuff of making a tabbed content area within a web page with the radio button trick. visibility:hidden is friendly to transitions where display:none is not. There is a loading keyword one may use when clicking a button and waiting for an AJAX request to happen to dress up the button with a spinner or something similar as if to say: "Hey, we're chewing on it." Wait, I guess there is no a "loading" keyword. Instead, I think Tim added a "loading" class to a button upon starting the act of loading to make the trick happen. I guess he then took it away again later, after loading. Uh, my chicken scratch notes can be hard to reinterpret as I type this stuff up. Codepen was suggested to be a pretty good place to go to for CSS examples. Beyond what Tim had to say, I had some pretty interesting conversations with some of the JavaScript peeps there before he started to talk. I vented my frustration of how I'd probably need to buy a Mac if I ever wanted to get serious about JavaScript as when Gulp and similar tools pull dependencies they try to place them in a folder structure I don't have. A guy there mentioned NPM for Windows, but honestly I think I've already been trying to use it and it hasn't solved my problem. As much as I like to play with aurelia I am incapable of setting it up on a Windows 8 laptop. I'm dead in the water before I can even begin because there is no way to hydrate the dependencies. Hisssss! XMPP is Extensible Messaging and Presence Protocol and is used in a lot of chat clients. Isomorphic means using the same language at the front end and the back end and this, yes, implies Node used in tandem with one of our modern JS frontend frameworks like Angular. Get it? JavaScript everywhere. "Universal JavaScript" is a new term emerging to replace isomorphic which isn't intuitive in/of meaning. I had to ask what it was. Elm is another corny language that complies to JavaScript. Maybe it's unfair for me to call it corny. The other things which compile to JavaScript that I've seen are corny. There was a conversation about whether it was wise to use one of many data stores with react.js and how the data in one store is eventually synced with another for consistency.

Saturday, September 5, 2015

I saw Tim Thomas speak on CSS at the JavaScript Austin meetup group meeting on Thursday.

This event was held at Evernote's office which I had not been to before. They have a nice space. Johnathan Hebert now works there so expect his group to meet there going forward. Everything in Tim's talk was new for me. There was no rehashing of the CSS stuff everyone has seen already. The first example was of sibling selection.

<html>
   <head>
      <title>Whatever</title>
      <style type="text/css" media="all">
         #two ~ p {
            color: blue;
         }
      </style>
   </head>
   <body>
      <div>
         <p id="one">one</p>
         <p id="two">two</p>
         <p id="three">three</p>
         <p id="four">four</p>
      </div>
      <p id="five">five</p>   
   </body>
</html>

 
 

The copy in the "three" and "four" paragraphs is going to be colored blue. The tilde ensures it. It finds a match for "two" and then finds all of the adjacent siblings (other paragraph tags in this case) downstream that have the same wrapping parental DOM element and applies its style there. The "five" is outside of the div wrapping the first four paragraph tags so it will not have its text turned blue. If a plus symbol were to be used in lieu of the tilde then the plus symbol would be the "next sibling selector" and only the "three" would get blue text. "Why should I care?" you ask. One of the interesting loopholes/exploits this sort of thing affords takes shape in allowing DOM elements to be on/off clickable like checkboxes or radio buttons. One of Tim's examples had a "Hello Austin" (note not "Hello World" ...comic commentary?) checkbox wherein the checkbox itself was hidden and one just clicked the "Hello Austin" copy to make the checkbox check and uncheck. How would you even know if the state was on or off if you couldn't see the hidden element? Well, the words "Hello Austin" would change color when checked! Alright, how does one pull that off? In Tim's example the copy was pulled out to a label that immediately followed the checkbox and was associated to it by way of having a for setting identical to the checkbox's id setting. This means that whenever the label itself is clicked, the checkbox behaves as though it were clicked directly. The checkbox is then hidden with the CSS you might expect and the specific state of being checked gets its own styling by way of the checked pseudoselector and it is this styling that uses the tilde to try to find a label immediately downstream in the DOM.

<html>
   <head>
      <title>Whatever</title>
      <style type="text/css" media="all">
         input[type=checkbox]:checked ~ label {
            color: blue;
         }
         input[type=checkbox] {
            display: none;
         }
      </style>
   </head>
   <body>
      <input id="enabler" type="checkbox">
      <label for="enabler">Hello Austin</label>   
   </body>
</html>

 
 

More to come...

Friday, September 4, 2015

Assignments of GroupIndex=0 at a DevExpress ASPxGridView...

...for default sorting of a column should probably be preceded by...

if (!IsPostBack)

 
 

...if the assignment happens on the C# side for otherwise the assignment may force a resorting upon a callback. Lame!

Thursday, September 3, 2015

Are one on one meetings formally a part of Agile?

A coworker told me this today, but I can't Google my way to an affirmation.

AutoExpandAllGroups not auto expanding all groups at a DevExpress ASPxGridView?

Per this, this...

<SettingsBehavior AutoExpandAllGroups="True"></SettingsBehavior>

 
 

...is not going to do its thing for data bound in a callback in lieu of a postback or a page load. The cure is to move the act to the C# side like so:

myGrid.ExpandAll();

How do I wrap the copy in the headers of a DevExpress ASPxGridView?

Per this, put the following inside the ASPxGridView tag:

<Styles Header-Wrap="True" />

Distinct counts will not play nicely with my giant foreach loop plans.

var foo = _data.Select(x => x.Bar).Distinct().Count();
var baz = _data.Select(x => x.Qux).Distinct().Count();

This idea won't fly. A loop to get a bunch of totals at once can't efficiently also find distincts, not if there is more than one distinct and the list to loop though cannot be sorted by the one relevant property upfront. If we want to refactor the two lines of C# above into our foreach loop we are in trouble. The only way to do so would entail pushing Bar and Qux values to other collections and looping through them in order to see if the next Bar or Qux exists therein already. It would be expensive. You could reduce overhead by, again, sorting the whole of the core collection by either Bar or Qux upfront so that only the values for Bar or Qux need to be tucked away into a goofy second collection, but even then this notion is still nasty.

Wednesday, September 2, 2015

when one int gets divided by another in C# and there should not be a clean integer result...

...there is nonetheless. Watch out for this! You won't have this problem if you divide a double or a decimal by an int, but int by int division is crazy. The following test passes even though forty-two divided by thirteen really should give an irrational number closer to pi than three.

[TestMethod]
public void BadTest()
{
   int fortyTwo = 42;
   int thirteen = 13;
   Assert.AreEqual(fortyTwo/thirteen,3);
}

DateTime endDate = DateTime.UtcNow.AddDays(1);

You want to run a report based on a date range, perhaps it being the last week or the last month, but the end is always the same, right now, yet it's hard to calculate when that is given a dirty hodgepodge of server time and UTC time that is the mix in your app. Well, if there are no dates in the future, you can always just set the end date in the future right? Regardless of whether the current server time or the current UTC time is later, you should be able to just take the current setting for either and then set it ahead a day to be ahead of both. (hack, hack, hack)

how to format a column in a DevExpress ASPxGridView for percentages or money

I started to write a blog posting like this...

Instead of trying to jam decimal precision into string formatting when bubbling up (presenting) the decimal at the user interface why not just round the decimal to the precision upstream of the string formatting? This will only suck if you explicitly have to show two decimal places for, for example, a price in lieu of just showing one or none. The reason I bring this up is that if one uses a DisplayFormatString setting at a DevExpress ASPxGridView to format a percentage, there should be a way to force the percentage formatting, but I can't figure it out.

 
 

But then the clouds parted...

If you Google this problem you will find a DevExpress thread on ASPxGridView that suggests you may just shove in the formatting but if you're like me you will struggle to make that happen. Here is the appropriate way, as best as I can tell, to format a number as a percentage: <PropertiesTextEdit DisplayFormatString="{0:P}" /> This assumes you are handing in .2 for twenty percent and not 20. And, yes, you may format for dollars and cents in the same manner by using C instead of P in the markup.

When to make a giant foreach loop in C#.

When calculating totals or counts as suggested in the last method here, you will be looping through the collection once for each total so if you have six column footers wherein you add up six prices across all line items (maybe total of subtotals, total of taxes, total of subtotals combined with tax fees which are real totals, and a variant of these three for when a discount code is used), well you've just looped through your collection six times instead of just once. You might be ahead to loop through once elsewhere in code, cast the findings to private fields, and then pluck the data points out again for the ASPxGridView footer assignments. My post "James and the Giant foreach" suggests this is out of fashion anymore, but I think unnecessary performance overhead is a bigger sin.

the difference between decimals and doubles in C#

The decimal has a capacity for being more precise. It's "better" while taking up more memory as an expense for being so. There is also a type called a float which is the same sort of thing yet crummier (less memory, less impressive) than either the decimal or the double. For more see:

Tuesday, September 1, 2015

Set the Caption setting at a DevExpress ASPxGridView to put a big loud message above the column headers inside the grid itself.

catch (Exception ex)
{
   ReportGrid.Caption = ex.Message;
}

 
 

Advertise an error even more so with an applicable CSS styling!

#ReportGrid caption {
   color: red;
}

Red Gate SQL Data Generator

...does what the name suggests! Launch it, pick a database, press the "Generate Data..." button at the upper left and then the "Generate Data" button inside of the dialog box which appears. Your schema will be filled with wacky gunk. Yay! Note that just because the data seems random you shouldn't mistake it for something generated with randomization. I've had two different copies of the same empty schema spun up in two separate databases and when I populated the two databases they both got the same stuff.

Uber Eats!

The Uber thing which allows you to have a driver chauffer you from place to place now can instead bring you food. I tried it today for the first time. Some coworkers and I got food from Koriente for our lunches. It was pretty good. I guess the drivers already have canned meals and they are just waiting to be told where to take them. You have to pick up the food at the street. The drivers do not come into the building to deliver. You just pay by way of the iPhone app I think. There is no cash exchange with the drivers. The drivers already have product and thus they get to you superfast in just a minute or two. Meh.