Wednesday, April 30, 2014

Make an auto-incrementing number appear in the rows of an Excel column within an otherwise consistent entry.

Manually make the first two rows with the values "foo1" and "foo2" while substituting what you need for "foo" itself. Then select the two cells, release the mouse, and move the pointer over the lower right corner of your selection like this:

 
 

Next: Click and drag downwards.

 
 

Finally: Just let go!

If an object has a friend in C++...

...the friend may see the object's private methods and members.

Thread.Sleep(1000);

...is a one second pause in C#.

Did you know that when StructureMap maps a class to an interface that when the class gets instantiated that the constructor with the most parameters will get called?

What's that? You say you've never seen parameters passed in in the mappings and thus this doesn't make sense? I've never seen this either, but you may specify at the constructor in these scenarios other interfaces which are also hydrated (given dance partners in the form of classes) by StructureMap and StructureMap should "fill in the gaps" so to speak. When undertaking this sort of trickery, you will be golden provided you do not create a circular reference.

Bonus: There is a NuGet package, and it might be StructureMap.MVC4 (not sure), which allows for the interfaces to be handed in and hydrated at the constructor signatures of MVC controllers!

Tuesday, April 29, 2014

Override ToString() on a object in C# to make it easier to debug!

Consider this Person class.

using System;
namespace Testing.Models
{
   public class Person
   {
      public string Name { get; set; }
      public DateTime Birthdate { get; set; }
      public int ZipCode { get; set; }
      public bool IsEligibleForRetirement { get; set; }
   }
}

 
 

Now consider debugging a dictionary where the key values are of the Person type like so:

 
 

A lot of the drilldown "heartache" may be alleviated by temporarily shoving in a ToString override.

using System;
namespace Testing.Models
{
   public class Person
   {
      public string Name { get; set; }
      public DateTime Birthdate { get; set; }
      public int ZipCode { get; set; }
      public bool IsEligibleForRetirement { get; set; }
      
      public override string ToString()
      {
         return Name;
      }
   }
}

 
 

Debugging gets easier and easier to read.

If you revert something you should not have with TortoiseSVN...

...look for the item in your Recycle Bin in Windows 7.

Ctrl-K followed by Ctrl-D

...in Visual Studio 2013 will autoformat the indentions.

 
 

Addendum 6/20/2016: Ctrl-K-D seems to be legit for this too.

when to use underscores in C# as a naming convention

Just about everything in C# should be named in Pascal Case. (Example: MyDogHasFleas) There are three exceptions:

  1. Private variables that exist only within a loop or a method (almost all private variables) should be in Camel Case. (Example: myDogHasFleas)
  2. The exception to this exception is that private fields, that is controller or page wide variables that hold state from method to method, should be in Camel Case with a leading underscore. (Example: _myDogHasFleas)
  3. Strictly speaking one should never use underscores in names in any scenario other than the one above. One should never have underscores in the middle of name. That said, when I worked at AMD, I liked Joel Holder's convention of using snake case for the names of tests. This is a Ruby convention that he drug in. (Example: my_dog_has_fleas)

Ctrl-F5 will clear the cache in Google Chrome.

You may need to do it a few times. The favicon will be the hardest thing to jog into refreshing.

Tab to the next selected item with F3 in Visual Studio 2013.

In a .js file in Visual Studio 2013 select the name of an element or function or property as it appears everywhere by either clicking on one instance and pressing Ctrl-F3 or by pressing Ctrl-i and then typing the name of the item in the search box which appears. With the name selected everywhere it appears in the file, you may "tab" from one item to the next with the F3 key!

Lawson is yet another ERP!

I heard of it today.

DevExpress modals

<dx:ASPxPopupControl ID="ProgressBarPopup"
      ClientInstanceName="ProgressBarPopup" runat="server" AllowDragging="true"
      ShowOnPageLoad="false" Modal="true" ShowCloseButton="false"
      CloseAction="None" Width="310px" Height="350px"
      PopupHorizontalAlign="WindowCenter" PopupVerticalAlign="WindowCenter"
      HeaderText="Change Me" EditTitleKey="UpdatingWhatever" >
   <Windows>
      <dx:PopupWindow Name="ProgressBarPopupWindow" CloseAction="None">
         <ContentCollection>
            <dx:PopupControlContentControl ID="ProgressBarPopupWindowContent"
                  runat="server">
               <asp:Panel ID="ProgressBarPopupWindowContentPanel" runat="server">
                  <uc3:editformheader id="ProgressBarPopupHeader" runat="server"
                        resourcekey="Whatever.UpdatingWhatever" />
                  <div>Hello World...</div>
               </asp:Panel>
            </dx:PopupControlContentControl>
         </ContentCollection>
      </dx:PopupWindow>
   </Windows>
</dx:ASPxPopupControl>

 
 

uc3:editformheader above is a web user control which is going to slurp copy out of a resource and replace the header of the modal with it. This is in-house stuff of the company I work for and not something of DevExpress itself. In order to show the modal, one needs to call this code from the JavaScript side:

ProgressBarPopup.ShowWindow(ProgressBarPopup
      .GetWindowByName("ProgressBarPopupWindow"));

 
 

Close the modal like so:

ProgressBarPopup.HideWindow(ProgressBarPopup
      .GetWindowByName("ProgressBarPopupWindow"));

Monday, April 28, 2014

You may right-click on a breakpoint in Visual Studio 2013 and pick "Condition..." to stop at the breakpoint only when a condition is met.

This is helpful when looping through a collection while only desiring to debug into a select member of the collection.

Tribute to Marty Robbins (El Paso)

I got to participate in this unspeakable awesome movie! w00t!

Kermit Meister, once my fencing coach at Austin Community College, concocted this masterpiece in Adobe Premiere!

a C# extension method for serializing a reference type and then deserializing it anew to make a new pointer to a new spot on the heap

This will only work for classes that are decorated with the Serializable() attribute as described here.

public static T MakeNewPointerAndPlaceOnHeap<T>(this T specificObject)
{
   using (var memoryStream = new MemoryStream())
   {
      BinaryFormatter binaryFormatter = new BinaryFormatter();
      binaryFormatter.Serialize(memoryStream, specificObject);
      memoryStream.Position = 0;
      return (T)binaryFormatter.Deserialize(memoryStream);
   }
}

App_LocalResources

...is the name of the folder you should add to an ASP.NET project for keeping .resx resource files. This is a special folder like App_Code or App_Data.

Typing three forward slashes in Visual Studio 2013 above a method signature creates a comment block for the method.

It will look like so:

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

 
 

My superior mentioned that there is some manner of canned XML crawling for documentation that one may turn on in Visual Studio 2013 which will allow for comments of this shape to display helpful notes in IntelliSense when one is tentatively to type the method's name.

things mentioned by my superior of debugging

  1. Start where the problem lies and work backwards in code from there. Also note that the issue may lie on the data side, in a stored procedure perhaps. It is best to rule that out quickly.
  2. Methods which take in reference types and doctor them should really be altered to advertise the alterations by making the variables out variables. Typically a method should not change the values handing in as parameters.

Ranz des Vaches

...is the name of that piece my mind sees as the quintessential music on hold melody.

Addendum 5/13/2014: This piece of music is not the same as the one that comes over the conference line at work after all.

Friday, April 25, 2014

Handing an instance of a class into a method signature is much like handing a value type into a method signature as a ref type variable.

If you use the instance variable procedurally after you hand it into the method, you will need to keep in mind that the instance may have changed (inside the method). A new copy on the heap with a new pointer is not created when the reference type is handed into a method signature. You are still using the same pointer referencing the same spot on the heap. Observe this in the following four items:

  1. using System;
    namespace ReferenceTypeExperiment.Stuff
    {
       public class MyState
       {
          public string MyString { get; set; }
          public bool MyBool { get; set; }
          public int MyInt { get; set; }
          public DateTime MyDateTime { get; set; }
       }
    }
     
  2. using System;
    namespace ReferenceTypeExperiment.Stuff
    {
       public class MyStateChanger : IMyStateChanger
       {
          public void MaybeChangeState(MyState myState)
          {
             myState.MyString = "Whatever";
             myState.MyBool = true;
             myState.MyInt = 13;
             myState.MyDateTime = new DateTime(1974, 8, 24);
          }
       }
    }
     
  3. namespace ReferenceTypeExperiment.Stuff
    {
       public interface IMyStateChanger
       {
          void MaybeChangeState(MyState myState);
       }
    }
     
  4. using System;
    namespace ReferenceTypeExperiment.Stuff
    {
       public class MyProcedure
       {
          public void Act()
          {
             MyState myState = new MyState();
             myState.MyString = "SomethingErOther";
             myState.MyBool = false;
             myState.MyInt = 42;
             myState.MyDateTime = new DateTime(2007, 2, 23);
             
             IMyStateChanger myStateChanger = new MyStateChanger();
             myStateChanger.MaybeChangeState(myState);
             
             var breakpoint = "stop here and look at myState";
          }
       }
    }
     

If you run the code in the Act method and hit a breakpoint at its last line, you may observe how myState has changed:

Also note that if you create another reference variable from an existing pointer like so...

MyState myOtherState = myState;

 
 

...that it will "have in it" exactly what the reference variable it was made from "has in it" as both variables don't really have contents but instead point to the same blob of storage on the heap. Once the two variables are tied together like this, it may be tricky to break them apart. This is one way to go about it:

using (var stream = new MemoryStream())
{
   var formatter = new BinaryFormatter();
   formatter.Serialize(stream, myOtherState);
   stream.Position = 0;
   myOtherState = (MyState)formatter.Deserialize(stream);
}

 
 

For this to work with the code I have above, the code above needs a stitch. The MyState class needs to be decorated with the Serializable attribute like so:

[Serializable()]

 
 

It now occurs to me that in this visitor pattern example I don't need to do this:

lucifer = siteOfThermonuclearExplosion.WelcomeVisitor(lucifer);
gregor = siteOfThermonuclearExplosion.WelcomeVisitor(gregor);
felix = siteOfThermonuclearExplosion.WelcomeVisitor(felix);
spot = siteOfThermonuclearExplosion.WelcomeVisitor(spot);

 
 

...as I all I really need is:

siteOfThermonuclearExplosion.WelcomeVisitor(lucifer);
siteOfThermonuclearExplosion.WelcomeVisitor(gregor);
siteOfThermonuclearExplosion.WelcomeVisitor(felix);
siteOfThermonuclearExplosion.WelcomeVisitor(spot);

 
 

...I could just change WelcomeVisitor to not hand back the same pointer handed in.

I caught lunch with a DBA...

...and he mentioned that new to MSSQL2008 following MSSQL2005 came:

  1. merges
  2. better XML support

 
 

...with MSSQL2012 following MSSQL2008 came AlwaysOn which has to do with mirroring to replicant databases (I think) and I believe that damaged portions of a database can be automatically repaired from a mirror.

Double-click the button (the one physical button) to see a list of apps running on an iOS7 device.

Swipe them upwards off the top of the screen to close them out.

Thursday, April 24, 2014

Wrapper!

At last night's Austin Homegrown API meetup, I saw Jeff Brateman of PayPal speak on PayPal's SDK (Software Development Kit) offerings for its API (Application Programming Interface). It has one for iOS, one for Android, and one for Windows. The iOS one for example allows one to make purchases via PayPal at an iOS app which is sort of exotic as there is little otherwise available in the way of ecommerce in apps listed at Apple's App Store. In each environment everything you could do with an SDK you could just do by interacting directly with the API as all a PayPal SDK does is give you a blob of Java or Objective-C or whatever to wrap API calls and make them less painful to use. That said, Jeff asserted that more developers were using the SDKs than were directly interfacing with the API. There are a couple of reasons for this.

  1. First is the DRY principal. Don't repeat yourself. SDKs wrapping APIs may minimize spaghetti.
  2. Many developers desire to work with an API without knowing the whole of the domain. Why can't it just be easy? Maybe it can be if you just talk into an SDK, let it talk to the API, let the API talk back to the SDK, and then get stuff back from what the SDK itself gleams from the outside.
  3. OAuth2 is used for authorization (are you who you say you are?) and authentication (are you supposed to be doing that?) and OAuth2 is a little bit painful to use outside of an SDK. If you write your own implementation against an OAuth2 API you will spend your first day just dealing with OAuth2. With OAuth2 you have a secret, or, if you do not have a secret, you are a "public client" and OAuth2 has approval and consent do-you-want-to-opt-in stuff baked into it. An SDK that uses OAuth2 makes it easy to fish for consent from a user without you having to figure out how to do it yourself.

card.io was brought up as a technology which PayPal bought. It allows you to take a photo of a credit card with a smartphone and have that act work in lieu of swiping a card in another scenario. The numbers in the photo are interpreted and the card is processed, all without adding new technology onto the devices we all already have. Another interesting aside: What keeps a credit card processor in business will boil down to its ability to prevent fraud and abuse while also not shutting out legitimate transactions. This is not trivial and doing it well is so tough that it is tough for one to establish oneself in this space. A story was told of how PayPal once blanket blocked transactions in a stream of transactions if all of the transactions appeared to come from the same IP address. In the name of blocking sinister traffic, they would act (after a few transactions made it through and they "saw the pattern") to just turn off access. Makes sense right? This backfired when, at a convention, many different parties legitimately tried to hit the API from the same wireless network at the convention's locale. I think this all happened for a presentation that gave a demo of the API. Embarrassing! To better deal with this sort of thing one has to consider geopositioning and triangulation. That has to come into the mix to make judgment calls on the legitimacy of traffic flooding in from a single IP address. This stuff isn't easy. PayPal does it well. They've learned and grown from tough mistakes (well, at least one), but don't think that any company can do what they do. Anyways, let me get back on topic. Tips for a good API-wrapping SDK included:

  1. Try to make something future proof which means try to make something that can be given new features and functionality without it feeling like add-ons were obviously unplanned and originally oversights. Ideally, new features should be downwards compatible.
  2. Small footprints are preferred. A forty megabyte SDK? Not so much. That could be bigger than the rest of one's application in some cases. Some users will want to keep it thin and you should empower them to do so.
  3. Minimize external dependencies as much as possible. People just want to use SDKs and not stress. Instead of worrying about how to light a candle, whether it will blow out, and if it will start a fire, wouldn't you rather just be handed a flashlight?

Addendum 4/26/2014: authorization is "are you supposed to be doing that?" and authentication is "are you who you say you are?" not the other way around.

The "Track" link at the top of Rally shows you what is in the latest sprint.

"Track" also opens a menu full of reports. Just double-clicking track defaults to opening the most recently selected report or perhaps the first of the reports if you've never made a selection.

DotNetNuke templates

...contain how .ascx controls are laid out for certain logins and also things like skins to be used. When adding a new DotNetNuke "page" one must update the templates so that data for the template makes its way into the DotNetNuke database.

ClientIDMode="Static" ...is the magic for making HTML side ids mirror ASP.NET side ids.

<asp:HiddenField runat="server" ID="Whatever" ClientIDMode="Static" />

...in this case the id tag that appears in HTML will have "Whatever" in it.

BMC Footprints

Is some fashion of asset management tool perhaps like IBM's Maximo??? I dunno.

Communication Tools

Wednesday, April 23, 2014

WS-Security

"is an extension to SOAP to apply security to Web services" per Wikipedia.

"Find Security Bugs" is something akin to HP Fortify I think.

It is free but also is only for Java. I think like Fortify, it will crawl a code base and tell you what is bad.

NSubstitute mocking

[TestMethod]
public void underwater_basket_weaving_behaves_as_expected()
{
   var service = Substitute.For<IBasketWeaver>();
   service.WeaveUnderwater(NSubstitute.Arg.Any<int>())
         .Returns(new List<Basket>(){new Basket()});

 
 

I specify NSubstitute before Arg in a set of tests which also have Rhino Mocks mocking sprinkled in to differentiate the Arg of NSubstitute from the Arg.Is(13) syntax of Rhino Mocks.

\n will put a line break in the body of a jConfirm dialog box but not the header!

That makes me cranky.

I could read the line item in an ASP.NET resource (.resx) if it was named "Whatever.Text" but not if it was merely named "Whatever" standalone.

This works:

string myPath = "~/MyFolder/SomethingErOther.ascx.resx";
MyHiddenField.Value = Localization.GetString("Whatever.Text", myPath);

 
 

This doesn't:

string myPath = "~/MyFolder/SomethingErOther.ascx.resx";
MyHiddenField.Value = Localization.GetString("Whatever", myPath);

 
 

Both of the above assume that Whatever or Whatever.Text corresponds to a key in the .resx. I don't understand the .Text convention yet. I am trying to pull copy from an .resx into an asp:HiddenField control in the name of allowing the .resx data to then be slurped into JavaScript.

Tuesday, April 22, 2014

ESAPI is The OWASP Enterprise Security API

As a tool it may be used to make sure redirects are safe. A piece of advice from OWASP is that if you are to use redirects that pass a parameter for where to redirect to that a parameter should find a dance partner in a lookup table and should not be interpreted literally. The parameter should be a key and the dance partner the thing to power the redirect.

manage certificates at "Console 1 - [Console Root]"

  • type "mmc" at the start menu in Windows Server 2008 R2 to launch "Console 1 - [Console Root]"
  • go to: File > Add/Remove Snap-in...
  • add the "Certificates" snap-in
  • back at Console 1 you should see a Certificates subsection beneath "Console Root"

phishing means "to fish"

This is the act of trolling for a security hole as a hacker.

an UPDATE with a JOIN in SQL!

UPDATE dbo.foo SET columnINSIDEfoo=13
FROM dbo.foo f
JOIN dbo.bar b ON b.barID = f.barID
WHERE b.columnINSIDEbar=42

forget my Init on a control manhandling way of getting back to JavaScript from a callback

This and this are flawed as it turns out. The mere presence of this...

<ClientSideEvents EndCallback="Whatever_EndCallback"></ClientSideEvents>

 
 

...will allow one to fall into this when a callback completes:

function Whatever_EndCallback(s, e) {
   alert('whatever');
}

return; in a JavaScript case/switch statement is not the same as break;

You'll be done with the function you are in after the return; and code after the case/switch statement in the same function will not run.

Workday

I heard of Workday today. I heard it is an ERP of IBM with a SalesForceesque SaaS (Software as a Service) model. Should SalesForceesque get a double e?

nest an enum inside of a class in C#

namespace Whatever
{
   public class MyClass
   {
      public enum MyEnum
      {
         Foo=1,
         Bar=2,
         Baz=3,
         Qux=4
      }
   }
}

 
 

Use the enum like so:

if(MyVariable == MyClass.MyEnum.Foo)
{

Monday, April 21, 2014

Alice and Bob

...are names typically given to party A and party B in computer science textbook examples. Read more about Alice and Bob here.

While passing variables, I'm trying to find a way to reach back into JavaScript from a DevExpress Callback.

Let's revisit this:

<asp:Panel runat="server" ID="InnerPanel"></asp:Panel>

 
 

We may hand a magic string of "magicstring" into JavaScript like so:

var input = new ASPxImage();
input.ClientInstanceName = "somethingrandom" + DateTime.Now;
input.ClientSideEvents.Init = "function(s,e){{InitTransactionInput(s, 'mymagicstring');}}";
InnerPanel.Controls.Add(input);

 
 

We may then doctor up "magicstring" to be "magicstringsomethingmore" in JavaScript and then turn around and hand "magicstringsomethingmore" back into our callback on the C# side.

function InitTransactionInput(s, e) {
   alert('whatever');
   InnerPanel.PerformCallback(e + 'somethingmore');
}

 
 

Some if/then logic would need to exist in the callback's code to "catch" our new value and do something other than just run the code previously ran so that we do not end up in an endless loop.

enums in JavaScript!

Make them like so:

var obj = Object.freeze({ "foo": 0, "bar": 1, "baz": 2, "qux": 3 });

 
 

Use them like so:

var whatever = obj.foo;

 
 

Object.freeze() locks the shape of an object so that new stuff may not be bolted onto it.

Wow! Look what I found!

Photos I took at a Headspring all hands meeting in 2009 in Spicewood, Texas!

faces from left to right: Eric Anderson, Kevin Hurwitz, Jimmy Bogard, Matt Hinze, Rafael Torres, and Mahendra Mavani (Eric Hexter has his back to us at the the left.)

 
 

from left to right: Kevin Hurwitz, Rafael Torres, Mahendra Mavani, and Dustin Wells

 
 

faces from left to right: Jimmy Bogard, Jeffrey Palermo, Matt Hinze, Eric Hexter, and Nick Becker (Blake Caraway has his back to us.)

 
 

from left to right: Eric Anderson, Matt Hinze, the guy who told us we could enter the butterfly garden at Krause Springs for free but not the swimming area, and Dustin Wells

 
 

faces from left to right: Eric Hexter, Dustin Wells, and Blake Caraway

 
 

This was nearly five years ago. It seems like a lifetime ago.

Friday, April 18, 2014

I saw a talk on optimizing SQL at the Austin .NET User Group on Monday night.

Big News: MSSQL Server 2014 is here!

  1. clustered indexes: There can be only one of these per database table as it keeps the physical ordering of rows. (Sorting by Guids is ineffective and useless. It is best to put the primary key elsewhere.)
  2. nonclustered indexes: This is also a list of keys like a clustered index providing a quick way to get to a record (much quicker than just crawling the whole of the table) but as the database table itself is not ordered by a nonclustered index the ordering must be kept elsewhere in a supporting file.
  3. columnstore indexes: See this. (these were not really explained in the talk)

These are the three kinds of indexes, and thus the interview question: "What may you do at the server to make queries faster?" ...could be answered with "add an index" ...but beware. As you add indexes you increase the amount of File I/O hijinks and this may ultimately lead to a performance hit instead of a performance boon. Whenever a table is updated, so too must the flat files holding the nonclustered indexes for the table. So, how do you put your finger on the sweet spot, the happy medium between indexing nothing and indexing everything? The answer is to use the Tuning Advisor. It will run every possible combination of indexes and let you know both which is the best and how much of a performance gain (a percentage) you will get over what you had to start out with. One should use the SQL Server Profiler first in advance of the Tuning Advisor. Pick "New Trace..." from the file menu here. When prepping the trace in the steps to come use the "Tuning" template. You may pick "Database Engine Tuning Advisor..." from the "Tools" menu to get at the desired analysis. I could not tell from the talk if one strictly needs to save the trace out to a table at "Column Filters..." first before running the Tuning Advisor. Perhaps so. Queries break down into:

  1. table scans: have to crawl everything in a table to find what they are looking for without the help of an index
  2. index scans: also touch every row in a table but also utilize indexes making them speedier than table scans
  3. index seeks: find what they need from an index exclusively and only delve into the table or tables in question at the rows which match what the query is fishing for

The speaker was Anil Desai. He suggested that if one has an ORM implementation yet needs to do a complicated query that one might have the query materialize in a view and then just work against the view with the ORM as one might a table. I found this a fascinating contrast to Ryan Vice's suggestion (as denoted here) that one might just sidestep using an ORM when the queries get crazy in CQS.

Thursday, April 17, 2014

What are fuzzers?

In fuzz testing one pushes random data to an application to attempt to get it to break. Fuzzers are tools which assist with this.

XSS variations

Three are three kinds of Cross-Site Scripting (XSS) attacks.

  1. Stored: an injected script is permanently kept at the server, perhaps in a database cell
  2. Reflected: are reflected to a target's victim off of an application ...could be an attack that causes a sinister error message to surface or an attack that forces a sinister email to be sent
  3. DOM-based XSS: entails handing in HTML script tags which will ultimately bubble back up to HTML and do something terrible

TLS is the new SSL?

This suggests that Transport Layer Security "is the successor to the Secure Sockets Layer (SSL)."

rainbow tables

Wikipedia tells us that a "rainbow table is a precomputed table for reversing cryptographic hash functions" and that means it will end up with a list of possible matches for an encrypted password or passwords.

backlog grooming

...in the Agile process is the art of prepping stories for a sprint long before the sprint has started in the name of not trying to figure out what the team will work on day-to-day while the sprint runs its course.

the better "are you sure?" dialog

jConfirm is a jQuery plugin for dressed-up confirm stuff. There is also a jAlert. jConfirm implementations look like this:

jConfirm("Are you sure you want to do this?", "Caution", function (result) {
   if (result) {
      doWhatever();
   }
});

 
 

The first magic string is the copy in the body of the message while the second is for a header above.

I'm trying to find a way to reach back into JavaScript from a DevExpress Callback.

One ghetto hack to have a regular panel within the ASPxCallbackPanel like so:

<asp:Panel runat="server" ID="InnerPanel"></asp:Panel>

 
 

...and then add into it (from within the Callback) a control that will fire off a JavaScript event on creation like so:

var input = new ASPxImage();
input.ClientInstanceName = "somethingrandom" + DateTime.Now;
input.ClientSideEvents.Init = "InitTransactionInput";
InnerPanel.Controls.Add(input);

 
 

This would set off...

function InitTransactionInput(s, e) {
   alert('whatever');
}

MVCC stands for multiversion concurrency control.

It makes sure reads don't interrupt writes and writes don't interrupt reads.

pgpool

This suggests: "pgpool-II is a middleware that works between PostgreSQL servers and a PostgreSQL database client. It is licensed under BSD license." PostgreSQL is a heavy hitter in open source SQL. Perhaps it is "the new mySQL" so to speak.

hybris

SAP AG bought hybris and it provides a commerce tie-in into SAP.

three levels of credit card processing

It's not this simple, but this is what I know so far...

  • Level 1: you hand in your credit card number, expiration date, and the cvv (Card Verification Value) on the back of the card
  • Level 2: verification goes against a zip code as well
  • Level 3: in your statements you will see a breakdown of the purchase listing line items in lieu of just a total amount

Wednesday, April 16, 2014

Open a layered .png in Adobe Fireworks and save it as a .psd to get the layers over to Adobe Photoshop.

Fireworks is no longer being kept up. It might be time to bail. An in-house standardization around layered .png files probably needs a second look.

A DevExpress theme will have its own folder, at least in ASP.NET web forms.

Inside of the folder there will be a file with a .skin extension for each control in the DevExpress suite. ASPxGridView.skin is an example of such a file's name. The skins may be used to dress up the controls.

DevExpress sliders are ASPxTrackBar controls.

<dx:ASPxTrackBar Id="Diameter" ClientInstanceName="Diameter" Direction="Normal"
      runat="server" MinValue="100" MaxValue="100000" Width="300"
      PositionStart="30310" />

 
 

The above and the below are markup for the ASPxTrackBar controls I first tried to use here and then gave up on.

<dx:ASPxTrackBar Id="Distance" ClientInstanceName="Distance" Direction="Normal"
      runat="server" MinValue="0.1" MaxValue="40.0" Width="300" Type="Decimal"
      Step="0.1" PositionStart="2.2" />

Adobe Captivate 7

...is a tool for creating demonstrations of your apps. It is not a part of Adobe's Creative Cloud suite. #sadtrombone

How to talk to things outside of a DevExpress callback panel from within a callback panel.

I started something here and refined it here and then came up with the web form markup seen here. The markup below is a blob from that same markup with the items in white being new additions in one last revision:

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
   
<script type="text/javascript">
      function OnEndCallback(s, e) {
         if (s.cp_Arg) {
            var titleText = document.getElementById('TitleText');
            titleText.innerHTML = s.cp_Arg;
            titleText.style.color = "#FF0000";
            delete (s.cp_Arg);
         }
      }
      function UpdateTitleText() {
         var titleText = document.getElementById('TitleText');
         titleText.innerHTML = "These settings are up to date!";
         titleText.style.color = "#00FF00";
      }
   </script>

   <dx:ASPxCallbackPanel ID="SolorSystemCallBackPanel"
         OnCallback="SolarSystemCallBackPanel_Callback"
         ClientInstanceName="SolorSystemCallBackPanel" HideContentOnCallback="false"
         ShowLoadingPanel="true" EnableViewState="true" runat="server" Width="700px">
      <PanelCollection>
         <dx:PanelContent ID="SolorSystemContent" runat="server">
            <dx:ASPxGridView ID="SolarSystem" ClientInstanceName="SolarSystem"
                  runat="server" Width="100%" KeyFieldName="Name"
                  AutoGenerateColumns="False">
               
<ClientSideEvents EndCallback="OnEndCallback" />
               <SettingsBehavior AutoExpandAllGroups="True" />
               <SettingsPager PageSize="15">
               </SettingsPager>

 
 

You can probably see how the OnEndCallback stuff changes the copy inside of a div. Perhaps you can also imagine how the same trick might populate the value of a hidden field so that, when a form (the token form in a ASP.NET web form) is later posted, the value makes its way back to the server from the client. Anyways, my effect looks like this:

 
 

These two methods changed in the code behind. This is how I pass "This may no longer be current." and I have been told that any variables used must start with "cp_" or they won't work.

private void SolarSystem_RowInserting(object sender, ASPxDataInsertingEventArgs e)
{
   UseRevampedPlanets(RevampPlanets(new OrderedDictionary(), e.NewValues));
   e.Cancel = true;
   ((ASPxGridView)sender).JSProperties["cp_Arg"] = "This may no longer be current.";
}
 
private void SolarSystem_RowUpdating(object sender, ASPxDataUpdatingEventArgs e)
{
   UseRevampedPlanets(RevampPlanets(e.OldValues, e.NewValues));
   e.Cancel = true;
   ((ASPxGridView)sender).JSProperties["cp_Arg"] = "This may no longer be current.";
}

 
 

Finally, and less interestingly, I decorated both of the ASPxListBox's in Default.aspx's markup with an OnClick event like so:

<dxe:ASPxListBox ID="Distance" runat="server" ClientInstanceName="DistanceClient"
      Height="635" OnClick="UpdateTitleText()">

Tuesday, April 15, 2014

Talking into a DevExpress ASPxCallbackPanel from the outside!

Behold: I have taken the ASPxGridView I first showed off here and have since refined here and here made it better yet. I brought in the Measurements class I mention here and have made Default.aspx look like so:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master"
      AutoEventWireup="true" CodeBehind="Default.aspx.cs"
      Inherits="DummyDevExpressApplication._Default" %>
<%@ Register Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web.ASPxEditors"
      TagPrefix="dx" %>
<%@ Register TagPrefix="dx" Namespace="DevExpress.Web.ASPxGridView"
      Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" %>
<%@ Register TagPrefix="dx" Namespace="DevExpress.Web.ASPxTabControl"
      Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" %>
<%@ Register TagPrefix="dx" Namespace="DevExpress.Web.ASPxClasses"
      Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" %>
<%@ Register TagPrefix="dx" Namespace="DevExpress.Web.ASPxPanel"
      Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" %>
<%@ Register TagPrefix="dx" Namespace="DevExpress.Web.ASPxCallbackPanel"
      Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" %>
<%@ Register TagPrefix="dxe" Namespace="DevExpress.Web.ASPxEditors"
      Assembly="DevExpress.Web.v13.1, Version=13.1.9.0, Culture=neutral,
      PublicKeyToken=b88d1754d700e49a" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
   <dx:ASPxCallbackPanel ID="SolorSystemCallBackPanel"
         OnCallback="SolarSystemCallBackPanel_Callback"
         ClientInstanceName="SolorSystemCallBackPanel" HideContentOnCallback="false"
         ShowLoadingPanel="true" EnableViewState="true" runat="server" Width="700px">
      <PanelCollection>
         <dx:PanelContent ID="SolorSystemContent" runat="server">
            <dx:ASPxGridView ID="SolarSystem" ClientInstanceName="SolarSystem"
                  runat="server" Width="100%" KeyFieldName="Name"
                  AutoGenerateColumns="False">
               <SettingsBehavior AutoExpandAllGroups="True" />
               <SettingsPager PageSize="15">
               </SettingsPager>
               <Settings ShowFilterRow="True" ShowGroupPanel="True" />
               <Styles AlternatingRow-Enabled="True">
                  <AlternatingRow Enabled="True">
                  </AlternatingRow>
               </Styles>
               <Columns>
                  <dx:GridViewCommandColumn VisibleIndex="0" ButtonType="Link"
                        Caption="Edit">
                     <EditButton Visible="True">
                     </EditButton>
                     <DeleteButton Visible="True">
                     </DeleteButton>
                     <HeaderCaptionTemplate>
                        <dx:ASPxHyperLink ID="btnNew" runat="server" Text="New">
                           <ClientSideEvents Click="function (s, e) {
                                 SolarSystem.AddNewRow();}" />
                        </dx:ASPxHyperLink>
                     </HeaderCaptionTemplate>
                  </dx:GridViewCommandColumn>
                  <dx:GridViewDataTextColumn FieldName="Name" VisibleIndex="1">
                  </dx:GridViewDataTextColumn>
                  <dx:GridViewDataTextColumn
                        FieldName="ClosestAstronomicalUnitDistanceFromSun"
                        VisibleIndex="2">
                  </dx:GridViewDataTextColumn>
                  <dx:GridViewDataComboBoxColumn FieldName="PlanetType"
                        VisibleIndex="3">
                     <PropertiesComboBox DataSourceID="PlanetTypeSource"
                           ValueField="key" TextField="value" ValueType="System.String"
                           DropDownStyle="DropDown" />
                  </dx:GridViewDataComboBoxColumn>
                  <dx:GridViewDataTextColumn FieldName="MilesInDiameter"
                        VisibleIndex="4">
                  </dx:GridViewDataTextColumn>
                  <dx:GridViewDataColumn FieldName="DiscoveryDate" VisibleIndex="5">
                  </dx:GridViewDataColumn>
               </Columns>
               <SettingsPopup>
                  <EditForm Width="500" />
               </SettingsPopup>
               <SettingsPager Mode="ShowPager" PageSize="10" />
               <Settings ShowTitlePanel="true" />
               <SettingsText Title="Our Solar System" />
               <Templates>
                  <EditForm>
                     <div style="padding: 4px 4px 3px 4px">
                        <dx:ASPxPageControl runat="server" ID="PageControl" Width="100%">
                           <TabPages>
                              <dx:TabPage Text="Planet" Visible="true">
                                 <ContentCollection>
                                    <dx:ContentControl runat="server">
                                       <dx:ASPxGridViewTemplateReplacement ID="Editors"
                                             ReplacementType="EditFormEditors" runat="server">
                                       </dx:ASPxGridViewTemplateReplacement>
                                    </dx:ContentControl>
                                 </ContentCollection>
                              </dx:TabPage>
                           </TabPages>
                        </dx:ASPxPageControl>
                     </div>
                     <div style="text-align: right; padding: 2px 2px 2px 2px">
                        <dx:ASPxGridViewTemplateReplacement ID="UpdateButton"
                              ReplacementType="EditFormUpdateButton" runat="server">
                        </dx:ASPxGridViewTemplateReplacement>
                        <dx:ASPxGridViewTemplateReplacement ID="CancelButton"
                              ReplacementType="EditFormCancelButton" runat="server">
                        </dx:ASPxGridViewTemplateReplacement>
                     </div>
                  </EditForm>
               </Templates>
            </dx:ASPxGridView>
            <asp:ObjectDataSource ID="PlanetTypeSource" runat="server"
                  SelectMethod="SelectPlanetTypes"
                  TypeName="DummyDevExpressApplication.Utilities.CommonSource">
            </asp:ObjectDataSource>
         </dx:PanelContent>
       </PanelCollection>
   </dx:ASPxCallbackPanel>
   <table style="background-color:#FFFFCC; width: 700px;">
      <tr>
         <td align="center"><h3 id="TitleText">Automatically assign planet type?</h3></td>
         <td width="100"></td>
      </tr>
      <tr>
         <td align="right" valign="top">a gas giant is bigger than this many miles in
               diameter:</td>
         <td height="100">
            <dxe:ASPxListBox ID="Diameter" runat="server"
                  ClientInstanceName="DiameterClient" Height="635">
               <Items>
                  <dxe:ListEditItem Text="90000" Value="90000" />
                  <dxe:ListEditItem Text="84100" Value="84100" />
                  <dxe:ListEditItem Text="78400" Value="78400" />
                  <dxe:ListEditItem Text="72900" Value="72900" />
                  <dxe:ListEditItem Text="67600" Value="67600" />
                  <dxe:ListEditItem Text="62500" Value="62500" />
                  <dxe:ListEditItem Text="57600" Value="57600" />
                  <dxe:ListEditItem Text="52900" Value="52900" />
                  <dxe:ListEditItem Text="48400" Value="48400" />
                  <dxe:ListEditItem Text="44100" Value="44100" />
                  <dxe:ListEditItem Text="40000" Value="40000" />
                  <dxe:ListEditItem Text="36100" Value="36100" />
                  <dxe:ListEditItem Text="32400" Value="32400" />
                  <dxe:ListEditItem Text="28900" Value="28900" />
                  <dxe:ListEditItem Text="25600" Value="25600" />
                  <dxe:ListEditItem Text="22500" Value="22500" />
                  <dxe:ListEditItem Text="19600" Value="19600" />
                  <dxe:ListEditItem Text="16900" Value="16900" />
                  <dxe:ListEditItem Text="14400" Value="14400" />
                  <dxe:ListEditItem Text="12100" Value="12100" />
                  <dxe:ListEditItem Text="10000" Value="10000" Selected="True" />
                  <dxe:ListEditItem Text="8100" Value="8100" />
                  <dxe:ListEditItem Text="6400" Value="6400" />
                  <dxe:ListEditItem Text="4900" Value="4900" />
                  <dxe:ListEditItem Text="3600" Value="3600" />
                  <dxe:ListEditItem Text="2500" Value="2500" />
                  <dxe:ListEditItem Text="1600" Value="1600" />
                  <dxe:ListEditItem Text="900" Value="900" />
                  <dxe:ListEditItem Text="400" Value="400" />
                  <dxe:ListEditItem Text="100" Value="100" />
               </Items>
               <ClientSideEvents SelectedIndexChanged="function(s, e) {
                  var item = { Diameter: DiameterClient.GetSelectedItem().value, Distance:
                        DistanceClient.GetSelectedItem().value };
                  SolorSystemCallBackPanel.PerformCallback(JSON.stringify(item));
               }" />
            </dxe:ASPxListBox>
         </td>
      </tr>
      <tr>
         <td align="right" valign="top">...and inner planets are within this many AU of the
               sun:</td>
         <td height="100">
            <dxe:ASPxListBox ID="Distance" runat="server"
                  ClientInstanceName="DistanceClient" Height="635">
               <Items>
                  <dxe:ListEditItem Text="38.7" Value="38.7" />
                  <dxe:ListEditItem Text="36.163" Value="36.163" />
                  <dxe:ListEditItem Text="33.712" Value="33.712" />
                  <dxe:ListEditItem Text="31.347" Value="31.347" />
                  <dxe:ListEditItem Text="29.068" Value="29.068" />
                  <dxe:ListEditItem Text="26.875" Value="26.875" />
                  <dxe:ListEditItem Text="24.768" Value="24.768" />
                  <dxe:ListEditItem Text="22.747" Value="22.747" />
                  <dxe:ListEditItem Text="20.812" Value="20.812" />
                  <dxe:ListEditItem Text="18.963" Value="18.963" />
                  <dxe:ListEditItem Text="17.2" Value="17.2" />
                  <dxe:ListEditItem Text="15.523" Value="15.523" />
                  <dxe:ListEditItem Text="13.932" Value="13.932" />
                  <dxe:ListEditItem Text="12.427" Value="12.427" />
                  <dxe:ListEditItem Text="11.008" Value="11.008" />
                  <dxe:ListEditItem Text="10.965" Value="10.965" />
                  <dxe:ListEditItem Text="8.428" Value="8.428" />
                  <dxe:ListEditItem Text="7.267" Value="7.267" />
                  <dxe:ListEditItem Text="6.192" Value="6.192" />
                  <dxe:ListEditItem Text="5.203" Value="5.203" />
                  <dxe:ListEditItem Text="4.3" Value="4.3" />
                  <dxe:ListEditItem Text="3.483" Value="3.483" />
                  <dxe:ListEditItem Text="2.752" Value="2.752" />
                  <dxe:ListEditItem Text="2.107" Value="2.107" Selected="True" />
                  <dxe:ListEditItem Text="1.548" Value="1.548" />
                  <dxe:ListEditItem Text="1.075" Value="1.075" />
                  <dxe:ListEditItem Text="0.688" Value="0.688" />
                  <dxe:ListEditItem Text="0.387" Value="0.387" />
                  <dxe:ListEditItem Text="0.172" Value="0.172" />
                  <dxe:ListEditItem Text="0.043" Value="0.043" />
               </Items>
               <ClientSideEvents SelectedIndexChanged="function(s, e) {
                  var item = { Diameter: DiameterClient.GetSelectedItem().value, Distance:
                        DistanceClient.GetSelectedItem().value };
                  SolorSystemCallBackPanel.PerformCallback(JSON.stringify(item));
               }" />
            </dxe:ASPxListBox>
         </td>
      </tr>
   </table>
   <style type="text/css" media="all">
      #MainContent_Diameter {
         position: absolute;
         -moz-transform: rotate(90deg);
         -ms-transform: rotate(90deg);
         -o-transform: rotate(90deg);
         -webkit-transform: rotate(90deg);
         transform: rotate(90deg);
         margin-left: -260px;
         margin-top: -310px;
      }
      #MainContent_Distance {
         position: absolute;
         -moz-transform: rotate(90deg);
         -ms-transform: rotate(90deg);
         -o-transform: rotate(90deg);
         -webkit-transform: rotate(90deg);
         transform: rotate(90deg);
         margin-left: -260px;
         margin-top: -310px;
      }
   </style>
</asp:Content>

 
 

I have nested my grid inside of a callback panel and I am to talk into it from the outside from two ASPxListBox controls which I have rotated ninty degrees just to be silly and to make them seem more like sliders. (ASPxTrackBar would not behave correctly so I substituted these controls.) These controls will effect the records in the grid without reposting the page.

 
 

I saw Joe Celko once suggest that data could be categorized by pieces of ranges in a talk he gave...

 
 

Building on this, I force the PlanetType of each Planet to be set by my "sliders" based upon their inputs. Planets close enough to the sun will be Inner planets. All others are either Dwarf or Gas planets depending upon how big they are. My code behind is:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.Web.Script.Serialization;
using System.Web.UI;
using DevExpress.Web.ASPxClasses;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxGridView.Rendering;
using DevExpress.Web.ASPxTabControl;
using DevExpress.Web.Data;
using DummyDevExpressApplication.Models;
using DummyDevExpressApplication.Utilities;
using System.Linq;
namespace DummyDevExpressApplication
{
   public partial class _Default : Page
   {
      private List<Planet> planets;
      
      protected void Page_Load(object sender, EventArgs e)
      {
         List<Planet> nullCheck = Session["planets"] as List<Planet>;
         if (nullCheck == null)
         {
            planets = PlanetFactory.GetPlanets();
            Session["planets"] = planets;
         }
         planets = Session["planets"] as List<Planet>;
         SetSolarSystem();
      }
      
      private void SetSolarSystem()
      {
         SolarSystem.Settings.ShowGroupPanel = false;
         SolarSystem.HtmlDataCellPrepared += SolarSystem_HtmlDataCellPrepared;
         SolarSystem.HtmlEditFormCreated += SolarSystem_HtmlEditFormCreated;
         SolarSystem.RowDeleting += SolarSystem_RowDeleting;
         SolarSystem.RowInserting += SolarSystem_RowInserting;
         SolarSystem.RowUpdating += SolarSystem_RowUpdating;
         SolarSystem.RowValidating += SolarSystem_RowValidating;
         SolarSystem.SettingsEditing.Mode = GridViewEditingMode.PopupEditForm;
         SolarSystem.DataSource = Session["planets"];
         SolarSystem.DataBind();
      }
      
      private void SolarSystem_HtmlDataCellPrepared(object sender,
            ASPxGridViewTableDataCellEventArgs e)
      {
         if (e.DataColumn.FieldName == "DiscoveryDate" && e.CellValue == null)
         {
            e.Cell.Text = "prehistory";
            e.Cell.ForeColor = Color.Firebrick;
            e.Cell.Font.Size = 8;
         }
      }
      
      private void SolarSystem_HtmlEditFormCreated(object sender,
            ASPxGridViewEditFormEventArgs e)
      {
         ASPxPageControl outerWrapper =
               (ASPxPageControl)SolarSystem.FindEditFormTemplateControl("PageControl");
         GridViewEditFormTable innerWrapper =
               (GridViewEditFormTable)outerWrapper.ActiveTabPage.FindControl("DXEFT");
         LiteralControl literal =
               (LiteralControl)innerWrapper.Rows[0].Cells[2].Controls[0].Controls[0];
         literal.Text = "AU Distance";
         ASPxTextBox firstTextBox =
               (ASPxTextBox)outerWrapper.ActiveTabPage.FindControl("DXEditor1");
         outerWrapper.ActiveTabPage.Text = firstTextBox.Text;
      }
      
      private void SolarSystem_RowDeleting(object sender, ASPxDataDeletingEventArgs e)
      {
         UseRevampedPlanets(RevampPlanets(e.Values, new OrderedDictionary()));
         e.Cancel = true;
      }
      
      private void SolarSystem_RowInserting(object sender,
            ASPxDataInsertingEventArgs e)
      {
         UseRevampedPlanets(RevampPlanets(new OrderedDictionary(), e.NewValues));
         e.Cancel = true;
      }
      
      private void SolarSystem_RowUpdating(object sender,
            ASPxDataUpdatingEventArgs e)
      {
         UseRevampedPlanets(RevampPlanets(e.OldValues, e.NewValues));
         e.Cancel = true;
      }
      
      private void SolarSystem_RowValidating(object sender,
            ASPxDataValidationEventArgs e)
      {
         List<Planet> revamp = RevampPlanets(e.OldValues, e.NewValues);
         if (IsNamingCollision(revamp)) e.RowError = "You may not have a duplicate name.";
      }
      
      private bool IsNamingCollision(List<Planet> revamp)
      {
         return revamp.Select(x => revamp.Count(y => x.Name == y.Name))
               .Any(z => z > 1);
      }
      
      private Planet GiveNewPlanet(OrderedDictionary newValues)
      {
         return new Planet()
         {
            Name = newValues[0] as string,
            ClosestAstronomicalUnitDistanceFromSun = Convert.ToDecimal(newValues[1]),
            PlanetType = (PlanetType)Convert.ToInt32(newValues[2]),
            MilesInDiameter = Convert.ToInt32(newValues[3]),
            DiscoveryDate = newValues[4] as DateTime?
         };
      }
      
      private List<Planet> RevampPlanets(OrderedDictionary oldValues,
            OrderedDictionary newValues)
      {
         List<Planet> revamp = new List<Planet>();
         if (oldValues.Count == 0) revamp.Add(GiveNewPlanet(newValues));
         foreach (Planet planet in planets)
         {
            if (oldValues.Count != 0 && planet.Name == oldValues[0] as string)
            {
               if (newValues.Count != 0) revamp.Add(GiveNewPlanet(newValues));
            } else {
               revamp.Add(planet);
            }
         }
         return revamp;
      }
      
      private void UseRevampedPlanets(List<Planet> revamp)
      {
         if (!IsNamingCollision(revamp)) planets = revamp;
         Session["planets"] = planets;
         SolarSystem.DataSource = Session["planets"];
         SolarSystem.DataBind();
         SolarSystem.CancelEdit();
      }
      
      protected void SolarSystemCallBackPanel_Callback(object sender,
            CallbackEventArgsBase e)
      {
         string json = e.Parameter;
         JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
         Measurements measurements =
               javaScriptSerializer.Deserialize<Measurements>(json);
         UpdateEverything(measurements);
      }
      
      public void UpdateEverything(Measurements measurements)
      {
         foreach (Planet planet in planets)
         {
            if (planet.ClosestAstronomicalUnitDistanceFromSun <= measurements.Distance)
            {
               planet.PlanetType = PlanetType.Inner;
            } else {
               if (planet.MilesInDiameter > measurements.Diameter)
               {
                  planet.PlanetType = PlanetType.Gas;
               } else {
                  planet.PlanetType = PlanetType.Dwarf;
               }
            }
         }
         Session["planets"] = planets;
         SolarSystem.DataSource = Session["planets"];
         SolarSystem.DataBind();
      }
   }
}

 
 

Both of my "sliders" have events at the ASP.NET markup which pass JSON into SolarSystemCallBackPanel_Callback at the code behind. Bonus: SolarSystem.Settings.ShowGroupPanel = false; ...gets rid of the "Drag a column header here to group by that column" thing. A lot of this silliness could really be better yet. The up/down arrow keys don't really work in my "sliders" as well as the clicks do. Just see this as what it is. I'm learning.

rivals to DevExpress

Telerik and Infragistics play in the same space (spiffy .NET controls).

JavaScriptSerializer is new as of the ASP.NET 4.5 Framework and is a great way to deserialize stringified JSON to a type!

protected void SolarSystemCallBackPanel_Callback(object sender,
      CallbackEventArgsBase e)
{
   string json = e.Parameter;
   JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
   Measurements measurements = javaScriptSerializer.Deserialize<Measurements>(json);
   UpdateEverything(measurements);
}

 
 

In this example, my type that I deserialize to is:

using System;
namespace DummyDevExpressApplication.Models
{
   public class Measurements
   {
      public Int32 Diameter { get; set; }
      public decimal Distance { get; set; }
   }
}

 
 

The stringified JSON I give as an example here would end up putting 13 in the Diameter property and 3.14 in the Distance property.

JSON.stringify(whatever);

...is a way in JavaScript to cast JSON back to a string. Observe:

var item = { Diameter: '13', Distance: '3.14' };
SolorSystemCallBackPanel.PerformCallback(JSON.stringify(item));

 
 

The string that would get made in this case would have this in it:

"{\"Diameter\":\"13\",\"Distance\":\"3.14\"}"

Monday, April 14, 2014

deadlock

A deadlock is concurrency quirk which usally happens during a race condition wherein the locking of a record never gets undone and the record stays unreachable.

All and Any with Lambda expressions

This simple Where Lambda will return an IEnumerable of the type it queries against, so bar must be a collection of MyType.

IEnumerable<MyType> foo = bar.Where(b => b.Status != (int)MyEnum.Whatever);

 
 

Bolting on All makes the Lambda return a true or false value.

Boolean foo = bar.Where(b => b.Status != (int)MyEnum.Whatever)
      .All(b => b.Whatever != null);

 
 

Bolting on Any does so too. The difference is that All makes sure that every record matches while Any looks for at least one match in the name of returning true.

Boolean foo = bar.Where(b => b.Status != (int)MyEnum.Whatever)
      .Any(b => b.Whatever != null);

an example of a test using Rhino Mocks

using Whatever;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StructureMap;
namespace DALTests.Controllers
{
   [TestClass]
   public class ThingamabobTests
   {
      [TestInitialize()]
      public void Setup()
      {
         ObjectFactory.Initialize(x => x.AddRegistry(new MyRegistry()));
      }
      
      [TestMethod]
      public void Test()
      {
         
//Arrange
         var fooProvider = ObjectFactory.GetInstance<FooProvider>();
         var barProvider = ObjectFactory.GetInstance<BarProvider>();
         var bazProvider = ObjectFactory.GetInstance<BazProvider>();
         
         fooProvider.Expect(x => x.fooState).Return(null);
         barProvider.Expect(x => x.barStuff()).Return(new List<Qux>());
         
         
//Act
         var thingamabob = new Thingamabob(fooProvider, barProvider, bazProvider);
         thingamabob.Act();
         
         
//Assert
         fooProvider.VerifyAllExpectations();
         barProvider.VerifyAllExpectations();
      }
   }
}

 
 

There is also a way to sanity check the number of times a method is called with syntax such as:

  • barProvider.Expect(x => x.barStuff()).Repeat.Never();
  • barProvider.Expect(x => x.barStuff()).Repeat.Once();
  • barProvider.Expect(x => x.barStuff()).Repeat.Twice();
  • barProvider.Expect(x => x.barStuff()).Repeat.Times(13);