Saturday, February 28, 2015

logical or and and versus conditional or and and in C#

The logical ors and ands are the ones with only one pipe symbol or ampersand. This stackoverflow thread shows how they work in a "bitwise" manner like so:

  • 0101 & 0011 = 0001
  • 0101 | 0011 = 0111

Friday, February 27, 2015

PI in SAP

Stands for Process Integration and opens up a way to talk in and out of SAP in lieu of RFC endpoints.

I disabled IE Enhanced Security Configuration for Windows Server 2012 R2.

To do this go to "Server Manager" and click on "Local Server" at the upper left. You'll see the option in the list of options. This fixed a bug I was seeing (only in Internet Explorer) which I suspect was due to JavaScript being disallowed. Whatever.

Thursday, February 26, 2015

how to create a defect in Rally's new interface

In Rally, go to "Backlog" under PLAN at the top nav. The dropdown by "New" at the upper left should let you select options for User Story and Defect.

can't see a conversation photo in Skype when someone else changes it?

If you Google this problem you'll see a bunch of threads about how Skype just sucks, but, in reality, you may have a version less than that of the party who posted the picture.

Wednesday, February 25, 2015

the AspNetCompatibilityRequirements attribute and why you should care

This error...

The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the service type with RequirementsMode setting as 'Allowed' or 'Required'.

 
 

...comes from this bit of Web.config:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />

 
 

You will see it when you try to reach a .svc endpoint for a WCF web service in a browser. The trick to fix this is to decorate the class in your .svc.cs file with this attribute:

[AspNetCompatibilityRequirements(RequirementsMode =
      AspNetCompatibilityRequirementsMode.Allowed)]

Tuesday, February 24, 2015

of checking to see if a table already has a column in T-SQL and also of writing stuff to the console

IF EXISTS(SELECT * FROM sys.columns WHERE [name] = N'IsHairband' AND
      [object_id] = OBJECT_ID(N'Groups'))
   BEGIN
      PRINT 'Yes, there is a column.'
   END
ELSE
   BEGIN
      PRINT 'No, there is not a column.'
   END

make a column not null in T-SQL!

ALTER TABLE Users
ALTER Column IsAdmin bit NOT NULL

what is NTLM?

It's an authentication means at Microsoft/Windows stuff. The LM part stands for LAN Manager I think. The NT would stand for whatever the NT in Windows NT meant I guess. I dunno. Looks like NT stood for: "New Technology"

T-SQL update script to bolt on a new and not null column onto a table

IF EXISTS(SELECT * FROM sys.columns WHERE [name] = N'IsCorny'
      AND [object_id] = OBJECT_ID(N'Users'))
   BEGIN
      PRINT 'There is already a IsCorny flag.'
   END
ELSE
   BEGIN
      DECLARE @nullrecordcount int
      SELECT @nullrecordcount=COUNT(Id) FROM Users
      IF @nullrecordcount > 0
         ALTER Table Users
         Add IsCorny bit
      ELSE
         ALTER Table Users
         Add IsCorny bit NOT NULL
      ALTER TABLE Users
      ADD CONSTRAINT IsCorny_Constraint
      DEFAULT 0 FOR IsCorny
   END
GO
DECLARE @nullrecordcount int
SELECT @nullrecordcount=COUNT(Id) FROM Users WHERE IsCorny is null
IF @nullrecordcount > 0
   BEGIN
      UPDATE Users SET IsCorny=0 WHERE 1=1
      ALTER TABLE Users
      ALTER Column IsCorny bit NOT NULL
   END
ELSE
   BEGIN
      PRINT 'An attempt to make IsCorny not nullable will not be undertaken.'
   END

Monday, February 23, 2015

You say you want users of your WCF web service to play nicely with the custom means your application has for managing who is logged in, huh?

Well, these links have the solution for you:

 
 

You'll need a class that inherits from UserNamePasswordValidator like so in the project which holds the web service:

using System;
using System.IdentityModel.Selectors;
namespace WebApplication
{
   public class CustomyValidator : UserNamePasswordValidator
   {
      public override void Validate(string userName, string password)
      {
         if (null == userName || null == password)
         {
            throw new ArgumentNullException();
         }
         if (!(userName == "foo" && password == "bar"))
         {
            throw new Exception("Yikes!");
         }
      }
   }
}

 
 

Alright, this upfront sanity check will provide the chance to throw an exception and block access if the username and password look strange. This means that both the application holding the WCF web service and the application consuming it will need to hold references to System.IdentityModel at the applicable projects. The hardest part of getting all this to work for me was messaging Web.config into shape. This bit of Web.config...

<system.serviceModel>
   <behaviors>
      <serviceBehaviors>
         <behavior name="">
            <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
            <serviceDebug includeExceptionDetailInFaults="false" />
         </behavior>
      </serviceBehaviors>
   </behaviors>
   <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
         multipleSiteBindingsEnabled="true" />
</system.serviceModel>

 
 

...eventually got rewritten as:

<system.serviceModel>
   <services>
      <service name="WebApplication.CornyWebService"
            behaviorConfiguration="CornyBehavior">
         <host>
            <baseAddresses>
               <add baseAddress ="http://www.experiment.com/CornyWebService.svc" />
            </baseAddresses>
         </host>
         <endpoint address="username" binding="wsHttpBinding"
               bindingConfiguration="Binding"
               contract="WebApplication.ICornyWebService" />
      </service>
   </services>
   <bindings>
      <wsHttpBinding>
         <binding name="Binding">
            <security mode="Message">
               <message clientCredentialType="UserName" />
            </security>
         </binding>
      </wsHttpBinding>
   </bindings>
   <behaviors>
      <serviceBehaviors>
         <behavior name="CornyBehavior">
            <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
            <serviceDebug includeExceptionDetailInFaults ="true"/>
            <serviceCredentials>
               <userNameAuthentication userNamePasswordValidationMode="Custom"
                     customUserNamePasswordValidatorType="WebApplication
                     .CustomyValidator, WebApplication" />
               <serviceCertificate findValue="localhost" storeLocation="LocalMachine"
                     storeName="My" x509FindType="FindBySubjectName" />
            </serviceCredentials>
         </behavior>
      </serviceBehaviors>
   </behaviors>
</system.serviceModel>

 
 

At the other app which actually tried to authenticate against the web service I had code like so:

CornyWebServiceClient cornyWebServiceClient = new CornyWebServiceClient();
cornyWebServiceClient.ClientCredentials.UserName.UserName = "foo";
cornyWebServiceClient.ClientCredentials.UserName.Password = "bar";
cornyWebServiceClient.ClientCredentials.ServiceCertificate.Authentication
      .CertificateValidationMode = System.ServiceModel.Security
      .X509CertificateValidationMode.PeerOrChainTrust;
ViewBag.PassOrFail = cornyWebServiceClient.FishForValidation();

 
 

...which gave me this error:

The X.509 certificate CN=localhost is not in the trusted people store. The X.509 certificate CN=localhost chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

 
 

I got around this problem by using this setting instead for the CertificateValidationMode:

System.ServiceModel.Security.X509CertificateValidationMode.None;

Make things happen at a DevExpress grid when pressing the cancel button while inline editing!

You need the AfterPerformCallback event.

MyGrid.AfterPerformCallback += MyGrid_AfterPerformCallback;

 
 

You may use it like so:

private void MyGrid_AfterPerformCallback(object sender, ASPxGridViewAfterPerformCallbackEventArgs e)
{
   if (e.CallbackName.Equals("CANCELEDIT"))
   {
      MyGrid.DataSource = GetEverythingAnew();
      MyGrid.DataBind();
   }
}

 
 

In my case I found that when I surfaced an exception within attempting to save an inline record like this that when I then pressed the cancel button that the row I was editing did not return to the way it was before. Instead, I saw the botched record with messed up values that I didn't save and though I had saved it. I didn't save it though, there was some caching nastiness. This fixes that.

when IIS acts like it can't see a .svc endpoint for a WCF web service

...you will see an error like so:

The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.

 
 

...if you visit the .svc endpoint in a browser. This happened to me at Windows Server 2012 R2 in specific and I beat the problem by:

  1. click on the Server Manager icon at the taskbar, probably the leftmost icon at the taskbar after that pseudostart menu thing that Microsoft added back in to the Metro interface
  2. at the "Dashboard" click on "Add roles and features"
  3. click next through the "Add Roles and Features Wizard" until you are at "Features"
  4. under ".NET Framework 4.5 Features" you'll find "WCF Services" and under that you'll want to check the checkbox for "HTTP Activation"
  5. finish up

 
 

Here are some things I found along the way:

How to log off of Windows Server 2012 R2 without shutting it down.

In my situation, when I go to the gear at the charm bar there is not an option for just logging off. You can find this option with Ctrl-Alt-Delete however.

Sunday, February 22, 2015

The Query Store of Conor Cunningham

...is mostly already described here. I did get to see Mr. Cunningham himself speak to it all again at SQLSaturday. The new SQL tuning feature will record a history of all plans and let you just fall back to that one that used to work when things start choking on a new plan. The one thing I heard that was new that I had not heard before was that "The Optimizer" is one is one big algorithm which runs like a chess program. This behemoth tries to come up with the best plan for you the same way that Deep Blue tried to win at chess.

How does the CSS for those circular avatars at vine.co and ello.co behave?

.sidebar.user .icon {
   width: 94px;
   height: 94px;
   border-radius: 50%;
   margin-bottom: 15px;
   cursor: pointer;
   background-size: cover;
   background-color: transparent;
}

...seems to be slapped on my avatar at Vine:

As best as I can tell, the combinaton of the border-radius and the background-color settings allow for a square shape (94 by 94 pixels) to have its rounded off corners disapper while the background-size does the magic of making a background image resizable!

Saturday, February 21, 2015

I saw Lori Edwards speak on SQL Server Statistics at SQLSaturday.

Statistics are tied hand and hand with indexes as without indexes predicates don't care about statistics as you are returning the whole of a column. Trace flag 2371 was mentioned in a slide. Updating statistics comes with a performance hit, but you can turn on this flag to force it to happen more frequently whenever a significant number of rows are altered.

Friday, February 20, 2015

Business Application Programming Interface

BAPIs are APIs within SAP so to speak. They don't let you talk in from the outside, but they are interfaces between different bounded contexts inside on premise SAP mechanics.

Thursday, February 19, 2015

vCenter Server is a service for running the ESXi flavor of VMware VMs.

...ESXi being the more spiffy of the two VM varieties from VMware, and VM Workstation being the other, stripped down minimalistic alternative. One may talk into vCenter with PowerShell and do things like take snapshots of ESXi VMs and spin up new ESXi VMs based upon the snapshots.

What are severity and state in RAISERROR implementations and what do they mean back on the C# side?

Following up on this, they are the middlemost and last parameters seen here respectively.

RAISERROR ('Oh no!',11,0)

 
 

This suggests that the later number ("state" for error code reporting) can really be any integer you want it to be between zero and two hundred fifty-five, but that and this clarify that severity, the first number, runs from zero to twenty-five with each step representing an escalated severity with twenty-five being most severe and only settings from eighteen and downwards being specifiable without holding the sysadmin server role! Sixteen is suggested to be the default, and I found that if you use a setting below eleven that it will not even be caught as an exception in C#! I wanted to catch an error (from a RAISERROR) when updating a record with a sproc at the C# side and have it bubble up to a DevExpress control. I ended up writing a try/catch block which had a catch block for a SqlException before a regular catch block for an Exception. If an exception makes it through to the second catch block for Exception, I am logging the error but otherwise swallowing the exception, but if, upstream of that, the SqlException's catch block is entered I am turning around and outright throwing the error like so:

   }
   catch (SqlException exception)
   {
      throw exception;
   }
   catch (Exception exception)
   {
      mylogger.Log(exception);
      return false;
   }
   return true;
}

Debix and NetSpend are two Austin, Texas-based companies that I heard of this week.

Debix is a credit monitoring service. NetSpend allows you to have a debit card without a bank account. Basically you give cash upfront to fund a card in their system. You may then setup bill payments online without a back account. I guess this means there is a way to put new funds onto a NetSpend card.

Select a row count to a local variable in SQL!

SELECT @X=COUNT(Id) FROM Users WHERE Id not like @Id and Email = @Email

Tuesday, February 17, 2015

If you need to get something done make it a story and not an action item in your Agile process.

At work, we find the action items have a way of... lingering.

Kitty Hates Water

This iPhone game was introduced to me Friday and it is the most fun of any iPhone game I have yet played. There was a time in my youth when I was a vegan vegetarian, but I don't really believe in that stuff anymore or care much about animals. I've decided that I'll worry about animals the day people don't have any problems. However, if you are one of those spoiled white kids who sees no bigger evil near him than that rabbit that needs to be liberated from the science lab, you'll be pleased to know that an arrangement was set up with the advertisers who advertise within the game to give X amount of coin to the Society for the Prevention of Cruelty to Animals (SPCA) every time you log in. Alternatively, if you're like me, you'll just want to play the game because it's fun!

While, I'm speaking freely, the past four recessions in America have each been progressively worse. I know this because I remember being told in the last three: "This is the worst downturn since the Great Depression!" There is no reason to see a trend, but, what if? What if there is something right around the corner that is even worse than the housing crisis? Perhaps, I've strayed... What do you think is really important? Animals? Video games?

When inline editing a row at a DevExpress grid you may want a password column to use a password type input field.

Make that happen like so:

private void MyGrid_HtmlRowPrepared(object sender,
      ASPxGridViewTableRowEventArgs e)
{
   ASPxTextBox password = (ASPxTextBox) e.Row.Cells[2].Controls[0];
   password.Password = true;
}

 
 

Wire up the event like so:

MyGrid.HtmlRowPrepared += MyGrid_HtmlRowPrepared;

Sunday, February 15, 2015

last of the Murder They Wrote notes

Alright, what is here goes with what is here, here, and here. An edge case for using a table variable is for putting errors that happen midstream in a transaction into the table variable and then returning the table variable, declared before the transaction ever begins, allowing for what went wrong in a transaction to see the light of day instead of just being something lost forever as part of the rollback. You may use COLLATE following an ORDER BY like so: COLLATE Traditional_Spanish_ci_ai ...to specify a culture. Someone in the audience said that these tend to show up in third party applications and the Wayne Sheffield suggested that these moreover tend to create a performance hit. The better way to specify a culture is to set it globally at your server if you can help it. I got an earful about how the ORM convention of using GUIDs for record identifiers is really poor practice. They too come with a performance hit. bigint types ultimately have more of a range than uniqueidentifier (GUID) types too because parts of a GUID are not random but are instead reserved for an encoding of a representation of the latest moment in time or something similar. There are five variations of uniqueidentifier which vary based on what the extra, not random, bonus content is:

  1. TimeStamp + MAC Address
  2. Version 1 w/ DCE Security
  3. Name with MD5 hash
  4. Random / Pseudo-Random Number Generation
  5. Name with SHA-1 hash

NHibernate will attempt to update NULL columns at the database if the dance partner for the column at the map does not specify the nullable quality. When running with NOLOCK in, for example, SELECT * FROM Foo WITH(NOLOCK) you will read as READ UNCOMMITTED meaning you may read records halfway through a transaction that is midstream that is going to ultimately get rolled back, removing the records. PeopleSoft was written for Oracle which is better with cursors than set-based stuff and it plays to this strength. It thus runs with problems on MSSQL where the cursors versus set-based standing is reversed.

I attended once more the Agile Austin UX SIG.

The Friday the 13th event was the second meeting hosted by Nathan Bussiere and Alex Soufi at Bancvue, and, while we were trying to figure out what to do before, this time we had a game plan and adopted a Lean Coffee Kanban format and picked topics for the group to discuss. We really only had time for two. The first was: What KPIs should I be tracking? How often? How do I relate them to business value(s)? The gentleman posing the questions said that he had used NPS (Net Promoter Score) and SUS (system usability scale) and wondered what else there was in the wild. Jeff Neria suggested that the key performance indicators to track might vary based upon one's business model. In a subscription based model you might measure churn (eventual drop off) and if you are just selling one off products online you might measure a different kind of drop off rate, persons losing interest or getting frustrated/disenchanted on their way through the workflow which should close a sale ideally. It may be hard to relate churn back to any one thing that you did if you are releasing every six months. Jeff suggested it smart to figure out what one metric you really want to track, (what is the one thing you really want to change and improve?) and then try to figure out how other metrics tie into the bigger metric. If reducing the number of clicks to do things in an app ultimately boosts an end goal metric like sales conversions, then as much might be an example of a supporting metric. If not, then it’s a distraction. The man who asked the original questions suggested that surveys were helpful while seeming to want to find another solution as if suspecting that they were not the answer to everything. Alex spoke of a desire to optimize the screen and make the process easier for users trying to get from here to there. He offered an example of an interface that forced a user to complete two dropdowns for country and language. This interface was simplified to only have one dropdown for country. How many clicks does it take to complete a task? Is clickiness a problem? Actual system performance and perceived system performance are two separate metrics worth worrying about. Alex also spoke of trying to minimize the JavaScript in interactive design in the name of these concerns and furthermore suggested that one shouldn't try to collect name/phone/email from users at forms if one is never going to contact that person or do anything with the information. A concept from a different talk I once saw Tim Ash give on optimizing forms for conversion: Keep forms that users must fight through simple so that the fight is as little of a fight as possible in the name of minimizing frustration and thus drop off. Only ask them about the information you really need and don't have a bunch of noise on the screen causing other distractions or making it unobvious as to what to do. Alex suggested that "fail, fail fast, and fail often" was a great mantra. Be ready to abandon ship. In the real world there is often not time and budget to undertake what is right and do surveys and gauge markets so a creative team just ends up throwing something together and in these situations in particular they need to course correct quickly. Having shorter sprints will help with this. The second topic of discussion was "How do I engage developers more in collaboration?" and Jeff Smith, one of the original board members of Agile Austin, suggested that holding lunches where there would be free food was a good idea. The woman posing this question said she just heard crickets when trying to get developers interested. This in particular seemed to be a problem on teams that had just switched to Agile where there is a newness factor. One of the developers in the room flatly asked "What's in it for me?" in retort. Alex suggested that developers often feel the pain of trying to implement a design handed down to them only to realize that it was not implementable and that these painful memories would serve as good incentive to give feedback to developers. Jeff felt that developers aren't so much coldly indifferent to UX as they just have more than they can do in a day at any one day. Dev leads are all the better to try to coax into a meeting because the underlings of the dev leads will follow their leaders into such meeting, but these individuals, dev leads, are all the more likely to be spread thin with other meetings. If you don't want to be involved in the UX process as a developer then there is something really wrong, but Jeff felt that inattention often stemmed not from apathy or irritation but from overextension. Alex suggested that there are two types of developers, the ones to whom you just give stuff and they just do and the ones who come back and fight you. Alex reiterated a need to set a rule wherein individuals had a certain window of time to complain and would lose their abilities to challenge afterwards. This should incentivize developers to be involved. Jeff suggested doing creating exercises on Fridays to get others involved. He often draws with a team lead and a QA lead. He felt the garbage in, beauty out UX principle applies to everyone and that developers who think that they don't have a "design sense" just need to be encouraged to blossom. He said that: "It's a myth that there is a creative department." Everyone can be creative.

Friday, February 13, 2015

Selenium tests apparently don't handle download-a-file scenarios too well.

A coworker mentioned that he uses AutoIt in these situations (in tandem with Selenium) to compensate.

I attended an Austin Technology Council talk called Payments Made Easy on Wednesday night which was about trends in the payment space.

In the photo here, from left to right are, the moderator, a Deborah Thoren-Peden, and panelists Braden More, Robert Alvarez, Doug Yeager, and Dan O'Malley. The moderator said that she had once been a Chief Privacy Officer, a fiduciary (in the interest of another, not yourself) role, when such a role was new, but that such a role is no longer a new thing. She sighted a statistic that suggested that cybersecurity in America was shy two hundred thousand needed employees as well.

Braden More of Wells Fargo coordinates marketing to the industry for his company. He said that technology takes away the payment workflow as it stops being an independent thing and instead it just becomes a part of a bigger process which in turn allows engagement based on loyalty and rewards. One of the biggest challenges Braden saw to venture capitalist funded players in the payments space is that there is a need to be able to tell a story and sell a dream. As long as people believe, the checks will keep flowing, but once you hit a door and you stop growing how will you maintain your investors' enthusiasm? Braden suspected that one could create a dating service based just on the data in a bank's records. Your purchase habits tell us where you live and what you like after all, and you could be matched to like-minded persons nearby. There is so very much potential for data mining from banking records that is presently going untapped. In the future, how will it be used? Should it be secured? Apple has been adamant that they will not look at the data collected from Apple Pay, but other entities in similar circumstances make no such guarantees and have very different philosophies. Braden offered that there are already some OTT (over the top) players trying to capitalize on banking data. He suggested that he was rather appalled by Kabbage which asks you for your credentials to log into your Wells Fargo portal on your behalf, scrapes your banking history, and then uses the data to help it in making decisions about giving you a loan! Marketers have had a history of thinking in terms of segments. A segment of eighteen to thirty-six year olds might be an example. In our modern era however segments are one person in size and not a sweeping swath. You have enough information to talk to one person in the moment temporally. The "value pack" text spamming of sales opportunities to anyone marginally a fit is not good practice. The brands you really buy from should be sending you alerts, but not everyone. Alerts need to be relationship-based, and in such a manner may be rewarding and energizing without providing overkill. Neiman Marcus and Starbucks do this well and also allow for in-app payments. With regards to security, make strategic alliances with other players to keep yourself strong. If someone hacks Bank of America it would be ideal for Bank of America to share what it knows of the hacker with other banks so that the villain cannot hop bank to bank causing problems. Albeit, there are regulatory agencies that somewhat prevent the blacklisting of sinister individuals in these circumstances. HCE (host card emulation) risk mitigation has a lot to do with making hackers want to just give up and go somewhere else. Whatever one might say to badmouth HCE security, it is superior to walking around with a plastic card with a bunch of numbers embossed on the side of it. Tokenization is fundamental. (Create fictitious card numbers with a "link back" to the real data point.) Security is a multi-faceted Rubik cube. Many people want to expand the closed-loop environment and have more control in that space. Braden wonders how bill payment might tie into the open-loop space.

Robert Alvarez of Bigcommerce suggested that the number one pain point to setting up an online store (Bigcommerce provides online stores) is not the branding or color themes or the workflow processes but the payment part. Bigcommerce has gotten its time to onboard a new customer down to thirty minutes which is crucial to a healthy revenue stream. Bigcommerce is a SaaS company through four rounds of funding and growing at a rate of eighty percent per year. Research and design is vital if you’re a SaaS company as are metrics and analytics. The onboarding process for your service as a SaaS company needs to be simple. Not every merchant cares about customization, the supply chain, and ERPs, but the bigger of Bigcommerce's merchants do. Bigcommerce has one technical team in Sydney, Australia and another in a San Francisco office. If you are selling online it has to be complete secure and a lot of fraud protection has to be built in. Robert said that Bigcommerce offers an AppStore, for accessing partners for loyalty programs, to its merchants. Bigger players want this. Metrics from point of sales providers that a merchant integrates with are given to the merchant at Bigcommerce's portal. When asked about the challenge of clientele desiring to have an ecommerce solution in house in lieu of in a SaaS shape, Robert suggested that this was a challenge less and less all the time and that he saw an ever-increasing trend towards SaaS solutions. Bigcommerce handles clientele which themselves handle up to one hundred million dollars in volume. Demandware, Inc., a competitor, gets the even bigger fish, but a majority of the fish in the pond (the overall space) are suited to Bigcommerce and Demandware comes with a hefty upfront cost. Bigcommerce helps industry move away from big box retail to small businesses by empowering companies to build a brand. If you sell your stuff on Amazon and eBay you are building their brands and not your own. Fugoo, which sells speakers, grew its brand to such a point that it could get a distribution deal with Apple and now Fugoo speakers may be purchased at an Apple store.

Doug Yeager of SimpleTap said that SimpleTap uses NFC (near field communication, i.e. radio communication with comparable devices) cards to make payments from smartphones at point of sale systems in the Android space. SimpleTap is the Android Pay shadow of Apple Pay. A big Softcard (formerly Isis Mobile Wallet and based on NFC technology) patch for HCE (host card emulation, i.e. a software alone representation of a smart card) was embraced by Google and put into Android to empower this. SimpleTap has just gotten its second round of venture capital funding. When asked about what is most challenging for mobile payments, Doug suggested that as EMV (Europay, MasterCard, Visa) terminals have been deployed, there has often been head trash on the part of merchants to see the devices as only for open loop payment cards (American Express, Visa, MasterCard and Discover) and not for closed-loop, store card options (Home Depot cards for example) which would give a break on an interchange rate. This head trash is not representative of the reality however. Doug said that at SImpleTap they measure their success on the fact that no one knows them. He felt SimpleTap should feel seamless and should not be a part of a regular shopping process that anyone has to think about. PayPal got big into BLE (Bluetooth Low Energy) AKA Bluetooth Smart, but it and EMV (Europay, MasterCard, Visa) Dip, where one dips a phone for up to eight seconds to mirror the act of swiping a card, seemed deprecated/archaic to Doug. One had to call in to activate an EMV chip card too. Boo! No one will want to deal with one hundred different wallets and we will need a standard platform. Doug sees in-app purchases growing as a trend.

Dan O'Malley of Mozido said that Mozido is a six-year-old startup in the mobile marketing space that he has been with for about a year. He used to run MoneyGram.com which is sort of a Western Union –style wire-someone-some-money company that dealt with the interesting technical rules of cross-border payments between different nations. He asked the audience: "Anyone not carrying your mobile phone tonight?" ...and nobody put their hand up at that prompt. He followed with: "If you left home without it you likely went back to get it!" What is something that you may do from anywhere in the world? Remittance payments were suggested as an example. A worker in a foreign land may have incentive to send funds back to loved ones in his/her home nation and especially so if the worker does not have banking set up in the new land. As much is an example of a remittance. Mozido has created something like the M-Pesa, the mobile-phone driven money transfer system of Kenya (pesa means money in Swahili), in Jamaica and Sri Lanka in the name of remittance. Mozido does the myDQ Dairy Queen Wallet and they are in the process of acquiring Corfire which manages the wallet for Dunkin Donuts. The two wallets together create a wallet footprint larger than that of the Starbucks wallet. These closed environments allow for company specific payments. Mozido is also becoming a bedfellow of SimpleTap as Dan feels that most of the world's populace is holding an Android phone and not an Apple phone. Everyone in the payment space has "table stakes" (the most one can bet in a game) in security. Dan suggested that none of the guys on the stage could afford a security problem. He suggested focusing on your company's approach to managing security more so than any specific trees in the forest that is security challenges, and later in the talk a member of the crowd expressed disappointment that two things, understanding how your data is governed and social engineering (your employees are your weakest link), were not specifically called out. These concerns arose in the light of the Home Depot, Target, and T.J.Maxx hacks of late and Dan acknowledged that these were important concerns while trying to refocus, again, on managing a bigger, diversified picture (not unlike the picture of Mozido's business model which has its fingers in many varied pies). He said it was important to have many eyes and ears and that it was thus wise to hire outside contractors and consultants with security skills to inject fresh blood. Dan felt marketing to others still needs to boil down to just one thing. Example: Let me sell you one thing. If I could take you down to that level, would you take the next step with me? etc. I need small data, little data on the target audience for this. The volume/prevalence of Opt In and Opt Out safeguards will exhaust users at some point and elate them and make them feel confident in other situations and the tensioning on this dial is very important. Privacy laws are obviously different in different parts of America and in different parts of the world, and this has to be taken into account too making the knob trickier yet to adjust. Dan mentioned a contemporary who had declared that "Privacy is dead." PayEase is a player in the Chinese mobile market. The United States has the biggest remittance market in the world. Many payments leave the US. There is a trend towards organizations building mobile wallets. When will we be able to forego our driver's licenses and use our phones instead? Stripe allows code/applications to accept payments online through an API and Braintree is a rival founded by PayPal.

Thursday, February 12, 2015

IS versus = and IS NOT versus <>

It's hard to tell which is best in SQL sometimes. If you want to check to see if a sproc exists before deleting it as in the reverse of this scenario it is best to use IS NOT, but clearly I get away with not using IS NOT here which I could not do when I attempted the other way (less than followed by greater than) in the first situation. Whatever.

Splunk

...gathers "operational intelligence" and ties into log4net nicely apparently.

See if two types match with reflection in C#!

private string DecideIfToLogException(Exception ex)
{
   foreach (Type type in _loggerHelper.GetWhiteListedExceptionTypes())
   {
      if (type.IsAssignableFrom(ex.GetType()))
      {
         return "";

 
 

Technically, I think this will check to see if the second type may be cast to the first honestly so this is not a strict equality comparison.

You're not supposed to put two spaces after the period at the end of a sentence when you type anymore.

My boss was bringing this up in our stand up today. This changed twenty years ago.

Wednesday, February 11, 2015

Is there a way to REALLY get rid of StructureMap's ObjectFactory at web forms ASP.NET applications?

To follow up on this, there is apparently a way to wiggle away from ObjectFactory alltogether without using the magic binding at MVC Controller signatures. This has details. I'm going to have a story at work to figure this stuff out and there will be another blog posting when I know more. Wait... This is now being portrayed to me by my higherups as a better way to go. The second article seems to suggest creating a private static readonly IContainer Container and newing it up with = new Container(new ScanningRegistry());

Addendum 2/14/2015: Alright. Now I've done it. ScanningRegistry() is a home spun class of Christos Matskas here. It will have the ususal stuff that you would have otherwise put in Global.ascx.cs leading in with the this keyword like so: this.For<IWhatever>().Use...

Tuesday, February 10, 2015

reference one repository into another in Subversion

  1. In TortoiseSVN's Repo-browser, right-click on a folder to bring references into and and pick "Show properties"
  2. "New..." button at far-right of "Properties" pane
  3. "Other" should allow you to make a new Property here, but if you pick an existing Property and pick "New..." at the dialog which appears a third dialog box yet will appear
  4. put an SVN path in the URL property and in "Local path" put the name of you pseduofolder to be
  5. start OKing out of the dialogs to save your alteration
  6. do an Update (pull down the files from the external source)
  7. do a commit (commit the programmatic change of referencing the external stuff)
  8. refresh the folder holding reference within the Repo-browser

Sophos

...is yet another antivirus tool.

yet even more Murder They Wrote notes

Following up on this and this, the red X in an execution plan means that you have a problem in your plan and a heap is a table without a clustered index wherein there is no general sort order and where a rid (row identifier) may be used in the absence of a clustered index. DBAs are encouraged to open up execution plans to developers as developers need the plans to tune. What is more, DBAs should probably just open up permissions enough for developers to just screw up dev environments. Just worry about keeping UAT (user acceptance testing) and prod clean and pristine. "Great Performance Tuning" by Grant Fritchey was recommended. I don't see that exact book here so maybe it is "SQL Server Query Performance Tuning" instead. Inline functions are pulled into query plans allowing SQL server to make optimizations. In inline table functions one may also have parallelization. In general you will want to try to avoid using functions as these sabotage SARGability. If something is SARGable (search-argument-able) it is searchable by a WHERE cause. WHERE, ORDER BY, GROUP BY, and HAVING all open the door to SARGability, but you may sabotage SARGability by wrapping the left side of the predicate in a scalar function and forcing a scan instead of a seek. For example, if you wrap a DateTime type column in a function that just returns the year at the left of predicate and then set that equal to 1999 (at the right) in the name of trying to find the year 1999, you will sabotage the index on the column (assuming there is one) and will have to increment rbar through every record to find matches for 1999. Speaking of assume, the photo here is of Wayne Sheffield reexplaining Benny Hill's old explanation of the word. I can't really exactly recall how this came up in our conversation. Scalar functions by their very nature return a single value and prevent parallelization. What is parameter sniffing? When you have several different parameters at a sproc, depending upon the amount of data being returned, one of two different execution plans may be returned. Parameter sniffing happens every time you execute SQL. SQL will try to compile the faster plan, but, this may not always be the fastest plan. 97% of all data results may fall into the center of the bell curve where the calculated plan works, but there may be outlier scenarios forcing a square peg into a round hole. What to do for the outliers? Putting RECOMPILE in strategic places within the sproc is one solution. Another is to use local parameters instead of globals. Global parameters are the usual inbound parameters at a sproc while to make locals, you take the globals and immediately turn around and assign them to new variables just inside of the stored procedure's code for mechanics. Then do everything with the locals instead of the globals in the name of fighting bad parameter sniffing scenarios. Conor Cunningham a product engineer at Microsoft has created, to fight this problem, "The Query Store" which is to come out in the next version of SQL Server. What is a plan guide? Every time you execute a query it creates a plan guide and every time you rerun the query it will use the plan guide. Conor's thing will allow you to force the use of particular plan guides to tell queries to work in ways that is not SQL's first choice. A query hint will allow you to optimize a query for a particular circumstance in which the inbound parameters are specific x, y, and z values. ADD EVENT sqlserver.query_pre_exection_showplan is going to show you an estimated plan and ADD EVENT sqlserver.query_post_exection_showplan is going to show you an actual plan.

Monday, February 9, 2015

page size in a DevExpress grid getting lost when one starts inline editing?

In my scenario, this happened because I was doing this...

MyGrid.SettingsPager.PageSize = 5;

 
 

...inside of the Page_Load event! I had to do this to make the page size a default other than ten, but whenever I went into line item editing of a row as a user the page size would just fall back to five regardless of what it had been. The fix was to put the line above inside of:

if (!Page.IsPostBack) {

HR FitBit is a device you wear on your wrist which monitors your pulse and the like when you walk.

I learned of it for the first time today.

A sproc I wrote today for taking the first four unique entries out of the password history for a user.

CREATE PROCEDURE [dbo].[CheckPasswordList]
@Username VARCHAR (50)
AS
DECLARE @Gold varchar(50)
DECLARE @Silver varchar(50)
DECLARE @Bronze varchar(50)
SET @Gold = null
SET @Silver = null
SET @Bronze = null
DECLARE @Placeholder varchar(50)
DECLARE @Table TABLE
(
   Password varchar(50)
)
DECLARE hydrator CURSOR FOR
   SELECT Password FROM PasswordHistory
   WHERE Username = @Username
   ORDER BY DateAdded DESC
OPEN hydrator
FETCH NEXT FROM hydrator into @Placeholder
   WHILE @@FETCH_STATUS = 0
      BEGIN
         IF @Gold is null
            BEGIN
               SET @Gold = @Placeholder
               INSERT INTO @Table (Password)
               VALUES (@Placeholder)
            END
         ELSE
            BEGIN
               IF @Silver is null
                  BEGIN
                     If @Placeholder <> @Gold
                        BEGIN
                           SET @Silver = @Placeholder
                           INSERT INTO @Table (Password)
                           VALUES (@Placeholder)
                        END
                  END
               ELSE
                  BEGIN
                     IF @Bronze is null
                        BEGIN
                           If @Placeholder <> @Gold
                              BEGIN
                                 If @Placeholder <> @Silver
                                    BEGIN
                                       SET @Bronze = @Placeholder
                                       INSERT INTO @Table (Password)
                                       VALUES (@Placeholder)
                                    END
                              END
                        END
                     ELSE
                        BEGIN
                           If @Placeholder <> @Gold
                              BEGIN
                                 If @Placeholder <> @Silver
                                    BEGIN
                                       If @Placeholder <> @Bronze
                                          BEGIN
                                             INSERT INTO @Table (Password)
                                             VALUES (@Placeholder)
                                             BREAK
                                          END
                                    END
                              END
                        END
                  END
            END
         FETCH NEXT FROM hydrator into @Placeholder
      END
CLOSE hydrator
DEALLOCATE hydrator
SELECT * FROM @Table
RETURN

Sunday, February 8, 2015

more Murder They Wrote notes

Murder They Wrote was a day long training I attended in advance of SQLSaturday which tied into SQLSaturday. One way to guard against SQL injection is to use parameterized stored procedures. Sqlninja is a tool one may download to help with authoring SQL injection attacks. mySQL and Oracle are more prone to SQL injection than MSSQL which is probably the safest database option there is. If you need to dynamically build up a query string you will not be able to protect yourself with parameterized stored procedures. Instead use the sp_executesql sproc to run built up query string as it will allow for parameters to be placed inside of what is built up. Example: Password=@password Bind parameters in SSRS reports to stored procedures which take in parameterized inputs. The CURSOR stuff is really slow. It does rbar (row by agonizing row) scanning, and as bad as they are WHILE loops tend to be worse. This suggestion messed with my mind a little bit and the speakers seemed to say some conflicting things with regards to whether a CURSOR could exist without a WHILE loop or not. It was suggested that GO 5 in contrast to a mere GO will run the lines before it five times over and that as much is an example of a CURSOR without a WHILE loop. DBCC CHECKDB was given as an example of a CURSOR which didn't suck and a set-based approach (specify what to do but not how to do it) to CURSOR stuff was encouraged. There is a plan cache stored for each query, and a plan hash (execution plan) has to be unique for each, but all cursors use the same plan! ORM (Object Relational Mapping) tools like Entity Framework, NHibernate, Ruby on Rails, LLBL Gen Pro, and SQL Alchemy may write some really nasty SQL beneath the hood. Deadlocks can happen often in ORMs. A recipe for slowness characteristic of ORMs is to have these three things all in the mix together in the SQL created:

  • nested views
  • recursive views
  • functions (especially those which are not inline table functions and are thus particularly slow... varieties of functions being:
          1. scalar
          2. table:
                1. inline
                2. multi-statement

Scalar functions return a simple type while table functions return a table. Multi-statement table functions must have the table to be returned declared at the outset and there will be a begin/end block around the around that which is returned. Inline table functions are all other functions not of this shape which hand back a table.) A nested view is a view which does a SELECT on top of another view or views instead of reaching directly into tables and Entity Framework has bad habit of making these in its SQL. This sort of mess will create a sucky plan in the optimizer and you should never nest views if you can avoid doing so. If view one queries view two which queries view three which actually queries tables as seen in Jason Brimhall's whiteboarding here then view one and view two are nested views. If true madness ensues and view three also reaches backwards against the progression to view one as much (view three that is) would be an example of a recursive view. You shouldn't do a SELECT * in lieu of calling out to just the columns you need in a table for tables that are huge and have numerous columns, and at the same time it is not recommended to have just the ninety of one hundred columns that you "need" specified either as this will make a bytes heavy outgoing request when you send the SQL itself across the network. Ask for just what you need and get back just what you need. The part of a where clause which goes seeking against the table id should go as far to the left as possible in a WHERE clause. Hit that first. sp_refreshview will refresh a view to make sure that columns weren't dropped in editing a referenced (or indirectly referenced) table. If you call out to columns numerically instead of by name in a view the view may get jacked up when columns are dropped from the table.

Saturday, February 7, 2015

A coworker told me that amazon.com games its prices to the profile it has built up on you a little bit.

I wonder how they work that in with the default pricing you see before you log in. I dunno.

fiverr

Fiverr is a place to offer your skills online like Mechanical Turk.

Murder They Wrote

In the day before SQLSaturday my work sent me to a lead-in event that was a SQL training called "Murder They Wrote" hosted by a Jason Brimhall and a Wayne Sheffield. This day long training was fantastic and honestly much better than SQLSaturday itself. I suspect I could have skipped SQLSaturday if not for the session I found there on PowerShell. Anyways, I will try to start putting my Murder They Wrote notes to my blog. I was have to break this up into a few posts as there is a lot to cover. SQL is set-based and declarative and in SQL's situation this means that you as a user tell SQL what to do and it tries to find the best way to do it. If you try to tell SQL what to do every step of the way it will oblige you and you will have performance problems. If you're running as sysadmin and an attacker successfully attacks through a SQL injection attack, the hacker can do anything he/she wishes to your database. If the same account is also an administrator at the machine at hand the attacker may highjack the machine and perhaps move outside that boundary even to wreak havoc at the greater LAN beyond. The speakers told a story of a company that was hacked through SQL injection attacks wherein the attacker(s) got usernames/emails/passwords for accounts. The company in question wasn't Yahoo, but Yahoo was also hacked and it was another example of a scenario in which the party keeping plain-text passwords was exposed for its sloppiness. If usernames/emails/passwords may be "recovered" in an attack, the attacker may then go fishing at gmail and PayPal and the like with the same credentials as people have a habit of using the same password everywhere. A common SQL injection attack is to push in as in input value Whatever' OR 1=1;- which is going to expose too much when injected inside of SELECT Username, Password FROM dbo.Users WHERE Username='Minnie' AND Password='????'; Imagine Whatever' OR 1=1;- in place of the four question marks and I think you'll see the problem. You'll get back all of the Minnies when you should only see one. If you see an application blow up when you enter a last name with a hyphen like O'Mally in a form field that is a good sign that the form may be used for SQL injection attacks. There are two varieties of SQL injection attacks:

  1. immediate
  2. delayed

The many Minnies example, a stereotypical SQL injection attack, is an example of an immediate attack. In a delayed attack, in contrast, one just does an insert, perhaps shoving in the 1=1 hack, and a dirty record sits within the database waiting to be used. If values out of the database are ever used in conditional SQL then problems will occur. There is no way to deal with a delayed SQL injection attack other than to never, never, never use queried data in predicates (where clauses).

Friday, February 6, 2015

You may need to make sure the KeyValue in DevExpress implementations is not null when attempting to loop through records.

I had to add the null check here...

public static void HideDeleteButton(ref ASPxGridViewTableCommandCellEventArgs e,
      string key)
{
   if (e.CommandColumn.Caption == "Delete")
   {
      if (e.KeyValue != null)
      {
         if (e.KeyValue.ToString() == key)
         {
            e.Cell.Controls.Clear();
         }
      }
   }
}

 
 

...or else when I filtered away all of the rows in a DevExpress grid I would see this error surface:

Object reference not set to an instance of an object

In web forms, don't try to set Session immediately before a Response.Redirect.

Session will be sabotaged. See: this

throw; by itself in C# does not reset the stack trace.

And yet, if you throw a specific exception you will reset the stack trace.

That second Boolean parameter for Response.Redirect...

...is optional and will define whether or not the thread at hand will be aborted upon redirecting. The default value is true meaning that, yes, the old thread gets the axe.

If you have an underscore in a domain, Internet Explorer will not use cookies at that that site!

This has more on this interesting "feature" which came up in IE 5.5 to fix a pitfall back then. Underscores are technically not appropriate characters for DNS stuff.

Thursday, February 5, 2015

MyGrid.SettingsBehavior.ConfirmDelete = true;

...in C# will make the Delete buttons in a DevExpress grid prompt you with "Are you sure?" alerts before deleting a record.

format a date at a DevExpress grid column

<dx:GridViewDataDateColumn FieldName="LastLogin" VisibleIndex="8"
      ReadOnly="True">
   <PropertiesDateEdit EditFormatString="d/M/yyyy h:mm:ss tt"
         DisplayFormatString="d/M/yyyy h:mm:ss tt" EditFormat="DateTime">
      <TimeSectionProperties>
         <TimeEditProperties EditFormatString="d/M/yyyy hh:mm:ss tt" />
      </TimeSectionProperties>
   </PropertiesDateEdit>
</dx:GridViewDataDateColumn>

Readonly local variable cannot be used as an assignment target

This error rears its head when you try to edit the gunk inside of a foreach loop in C#, especially so if you try to replace the variable for the child at hand in a loop step. If you need to hand each child out to a method elsewhere to reshape it and expect to return an object of the same type as the object that needs editing you, again, may not just overpower the old with the new. You have to either incrementally create a new list as you loop through the old list, or, in the case of just doctoring up one match, you can do something like this:

int counter = 0;
int positionOfInterest = 0;
User alteredUser = null;
foreach (User user in _users)
{
   if (user.Username == e.Keys[0].ToString())
   {
      alteredUser = UserUpdater.Update(user, GroupId, e.OldValues, e.NewValues,
            MyRepository);
      positionOfInterest = counter;
   }
   counter++;
}
if (alteredUser != null)
{
   MyRepository.UpdateUser(alteredUser);
   _users[positionOfInterest] = alteredUser;
}

Wednesday, February 4, 2015

vicious!

At lunch a coworker mentioned SIPVicious at lunch today. Named for Sid Vicious, this malware or virus or whatever tries to find a phone attached to a SIP (Session Initiation Protocol) port at your PC and it will then make your phone ring again and again. It made me think of the Bugbear virus of 2003 which would try to find printers at your LAN and would then start printing its source code out, one line per sheet of paper, in the name of seeing how many sheets of paper it could ruin.

use images for buttons in a DevExpress grid

I refactored this:

<dx:GridViewCommandColumn Caption="Edit" ButtonType="Image" VisibleIndex="11">
   <EditButton Visible="True" />
   <UpdateButton Visible="True" />
   <CancelButton Visible="True" />
</dx:GridViewCommandColumn>

 
 

...to this:

<dx:GridViewCommandColumn Caption="Edit" ButtonType="Image" VisibleIndex="11">
   <EditButton Visible="True">
      <Image Url="/Images/foo.png" />
   </EditButton>
   <UpdateButton Visible="True">
      <Image Url="/Images/bar.png" />
   </UpdateButton>
   <CancelButton Visible="True">
      <Image Url="/Images/baz.png" />
   </CancelButton>
</dx:GridViewCommandColumn>

do something for each HTML element decorated with a certain class

<script type="text/javascript">
   var loop = function() {
      $(".dxgvTitlePanel").map(function () {
         var contents = this.innerHTML;
         if (contents) {
            this.innerHTML = "";
            alert(contents);
         }
      });
   };
   var interval = setInterval(loop, 100);
</script>

hide something without making it invisible

.outofsightoutofmind {
   position: absolute;
   margin-left: -9999px;
}

alternating row colors at a DevExpress grid

The last two assignments use the System.Drawing namespace while the first needs DevExpress.Utils:

MyGrid.Styles.AlternatingRow.Enabled = DefaultBoolean.True;
MyGrid.Styles.AlternatingRow.BackColor = ColorTranslator.FromHtml("#C6C4d7");
MyGrid.Styles.Row.BackColor = Color.White;

Why can't I see the control for changing pagination at a DevExpress grid?

I assume that this worked when I wrote it, but at some point I lost the ability to see my control for changing pagination. I fixed it like so:

<SettingsPager Position="TopAndBottom">
   <PageSizeItemSettings Visible="true" ShowAllItem="true" />
   <PageSizeItemSettings Items="5, 10, 20, 50, 100" />
</SettingsPager>

 
 

I eventually took out ShowAllItem="true" as it put an option for "All" in the control which I did not want. On the C# side I had to explictly make the 5 the default as otherwise 10 would be the default. I did that like this:

MyGrid.SettingsPager.PageSize = 5;

 
 

As I type this up, I bet I had...

MyGrid.SettingsPager.Visible = true;

 
 

...in my C# at some point and I accidentally zapped it. That is probably why my pagination sizing control disappeared, you know?

to push data points to a DetailRow in a DevExpress 13.1.9 grid...

Replace the "coming soon..." here with a Literal control like so:

<asp:Literal ID="Details" runat="server"></asp:Literal>

 
 

In C# you will need to wire up a .HtmlRowCreated event like so:

MyGrid.HtmlRowCreated += MyGrid_HtmlRowCreated;

 
 

...and pimp it out like this:

private void MyGrid_HtmlRowCreated(object sender,
      ASPxGridViewTableRowEventArgs e)
{
   if (e.RowType == GridViewRowType.Detail)
   {
      Literal literal = OrganizationManagementGrid
            .FindDetailRowTemplateControl(e.VisibleIndex, "Details") as Literal;
      Group group = (Group)OrganizationManagementGrid.GetRow(e.VisibleIndex);
      literal.Text = group.Notes;
   }
}

 
 

In this example, MyGrid is populated with a list of Group objects to begin with and we are casting each of the rows back to a Group object to get the Notes getsetter off of each Group so that we may put in in our Literal.

Tuesday, February 3, 2015

RAISERROR

...in SQL should throw up an error. If a C# implementation is attempting to catch error in a try/catch it should be able to, or if it lets it just bubble up to a DevExpress 13.1.9 grid using the sproc DevExpress will catch the error and display it as a validation error. I haven't tried this yet. This is just what I heard today.

an example of hiding the delete button in DevExpress 13.1.9 grids

Use this event...

MyGrid.HtmlCommandCellPrepared += MyGrid_HtmlCommandCellPrepared;

 
 

...like so:

private void MyGrid_HtmlCommandCellPrepared(object sender,
      ASPxGridViewTableCommandCellEventArgs e)
{
   if (e.CommandColumn.Caption == "Delete")
   {
      if(e.KeyValue.ToString() == ((User)Session["User"]).Username)
      {
         e.Cell.Controls.Clear();
      }
   }
}

when SettingsText.Title seems to do nothing in DevExpress 13.1.9 grid implementations...

This problem messed with my mind. I had this going on in a dx:ASPxGridView...

   </Columns>
   <Templates>
      <TitlePanel>
         Hello There!
      </TitlePanel>
      <DetailRow>
         <div>coming soon...</div>
      </DetailRow>
   </Templates>
   <SettingsDetail IsDetailGrid="True" ShowDetailRow="True" AllowOnlyOneMasterRowExpanded="false" />
</dx:ASPxGridView>

 
 

The markup allowed me to make each row have a +/- control for expandable and collapsible content with "coming soon..." inside of it which shows in a row that appears below the row of data at hand, but what about the TitlePanel? I figured out that I could make it visible (from C#) like so:

MyGrid.SettingsText.Title;

And yet, I could not replace "Hello There!" from the C# side, try as I may, with this syntax even though everything I read online told me that this was the way to go.

MyGrid.SettingsText.Title = "foo";

 
 

The fix was to remove the TitlePanel tag outright from the markup and only have the C# stuff!

making custom buttons do things at a DevExpress grid

How to make custom buttons in a DevExpress 13.1.9 Grid View do things in JavaScript:

<ClientSideEvents CustomButtonClick="function(s, e) {
   if(e.buttonID == 'whatever'){
      alert('whatever: ' + e.visibleIndex);
   }
}" />
<Columns>
   <dx:GridViewCommandColumn Caption="Whatever" ButtonType="Image"
         VisibleIndex="1">
      <CustomButtons>
         <dx:GridViewCommandColumnCustomButton ID="whatever" Text="Whatever">
         </dx:GridViewCommandColumnCustomButton>
      </CustomButtons>
   </dx:GridViewCommandColumn>
</Columns>

 
 

s.keys[e.visibleIndex] could be substituted for e.visibleIndex to fish out the key for a row if a KeyFieldName setting was set. It's not the scenario above. Do things on the C# side with a CustomButtonCallback event like so:

private void MyGrid_CustomButtonCallback(object sender,
      ASPxGridViewCustomButtonCallbackEventArgs e)
{
   if (e.ButtonID == "View")
   {
      ASPxWebControl.RedirectOnCallback("Whatever.aspx");
   }
}

 
 

You cannot do a Response.Redirect within a callback, but .RedirectOnCallback is the DevExpress workaround.

getsetters on a DevExpress 13.1.9 ASPxImag

...include, of course Height and Width, but there is also ToolTip which will take a string to be displayed when one mouses over the image. If you leave this unset, there will be no effect.

Monday, February 2, 2015

AlwaysOn

...seems to be for configuring and managing Availability Groups.

padding: 3px 6px 4px;

...only the top, right, and bottom values are displayed here, and yet the left value will still be 6px. The middle value will serve for both the left and right values when three values are given like this in CSS.

disabling fields you don't want to edit in inline editing within DevExpress 13.1.9 grids in an aesthetic way

If you decorate a dx:GridViewDataColumn with ReadOnly="true" at the .aspx or .ascx markup the form field one sees when inline editing with still be a form field of a type="text" shape with readonly slapped upon it. These uneditable fields do not read as uneditable to the eye. Wouldn't it be best to have a label instead of a disabled input? Yes. First use this event:

MyGrid.HtmlRowPrepared += MyGrid_HtmlRowPrepared;

 
 

...and then give the event some code to swap out the readonly input fields:

private void MyGrid_HtmlRowPrepared(object sender,
      ASPxGridViewTableRowEventArgs e)
{
   if(e.RowType.Equals(GridViewRowType.InlineEdit))
   {
      ASPxTextBox usernameControl = (ASPxTextBox)e.Row.Cells[0].Controls[0];
      ASPxDateEdit lastLoginControl = (ASPxDateEdit)e.Row.Cells[7].Controls[0];
      usernameControl.Visible = false;
      lastLoginControl.Visible = false;
      ASPxLabel userNameLabel = new ASPxLabel();
      userNameLabel.Value = usernameControl.Value;
      userNameLabel.CssClass = "whatever";
      e.Row.Cells[0].Controls.Add(userNameLabel);
      ASPxLabel lastLoginLabel = new ASPxLabel();
      lastLoginLabel.Value = String.Format("{0:M/d/yyyy}", lastLoginControl.Value);
      lastLoginLabel.CssClass = "whatever";
      e.Row.Cells[7].Controls.Add(lastLoginLabel);
   }
}

 
 

...dropping the username which is also the KeyFieldName came with some consequence. Stuff like this at the RowUpdating...

foreach (User user in _users.Where(user => user.Username ==
      e.OldValues[0].ToString())) {

 
 

...had to be reshaped like so:

foreach (User user in _users.Where(user => user.Username == e.Keys[0].ToString())) {

If you turn on the ASP.NET State Service...

...and you use "StateServer" instead of "InProc" here, you may use the service to keep Session in an alternate AppPool and hence when you rebuilt the application while testing you will not be forced to log in anew. In order for this to work, everything which goes into session must be serialized.

Replace checkboxes for Boolean values with images in nonedit mode at a DevExpress 13.1.9 grid.

Use the .HtmlDataCellPrepared event like so:

private void MyGrid_HtmlDataCellPrepared(object sender,
      ASPxGridViewTableDataCellEventArgs e)
{
   if (e.DataColumn.FieldName == "Admin")
   {
      e.Cell.Controls.Clear();
      if ((bool)e.CellValue)
      {
         var activeImage = new ASPxImage()
         {
            ImageUrl = "/whatever.png"
         };
         e.Cell.Controls.Add(activeImage);
      } else {
         var activeImage = new ASPxImage()
         {
            ImageUrl = "/somethingelse.png"
         };
         e.Cell.Controls.Add(activeImage);
      }
   }
}

Sunday, February 1, 2015

the first and best talk I saw at this year's SQLSaturday was by a Jennifer McCown and called: Introduction to PowerShell cmdlets for DBAs

I'm not a DBA, but this was a really good introduction to PowerShell in general. I scribbled down just about everything the speaker offered. I'll slowly go through it now. As I type this up, I'm testing everything. I'm often guilty of phoning in blog postings, but I'm not doing that here. Things worth saying are:

  • First of all, please run PowerShell as an administrator. That will save you a lot of heartache as you attempt what follows.
  • A lot of old school DOS commands are honored in PowerShell. For example, when I open PowerShell the prompt says PS C:\WINDOWS\system32> and when I type cd.. it changes to PS C:\WINDOWS>
  • All of the supported DOS conventions are aliases for real PowerShell commands. You may see what an alias is by, typing, in the case of cd for example, get-alias cd which will write the name of the real command to the console. Set-Location is the name of the real command in this case and when I type set-location .. it changes the command prompt to PS C:\> which I could have also got to with set-location C:\ ...please note that there does not seem to be case sensitivity in using the PowerShell commands as the command is Set-Location and I'm getting away with set-location and also set-location WINDOWS takes me back into the WINDOWS directory and sets the command prompt to PS C:\WINDOWS>
  • Other DOS commands include move and just now I was, from the C root, able to move Tom.txt from C:\Tom.txt to C:\foo\Tom.txt with move Tom.txt foo ...the command cls will clear out the history of noise in the shell and something like echo "Hello" will write Hello to the console... move corresponds to Move-Item while cls corresponds to Clear-Host and echo to Write-Output so I may move Tom.txt back to where it was by navigating into the foo folder and typing move-item Tom.txt C:/ ...note that the commands, properly called cmdlets, typically take a verb-noun shape. write-host hi there also puts copy to the console, in this case: hi there
  • get-childitem and dir do the same thing (show a list of what is in the directory at hand) but there is no support for dir /W which would have, in DOS, broken up the list into a few columns running side by side (I think). I was able to emulate the /W trick by using get-childitem | format-wide which made two columns of things in the C root when I ran the command after having navigated into the C root. I typed get-help format-wide to learn more about format-wide and saw [-Column <Int32>] in a SYNTAX subsection which led me to type get-childitem | format-wide –column 3 to have three columns instead of just two. This begs the question, what do the pipe symbol and the hyphen do? The hyphen denotes a parameter switch used as a setting for the command before it, so in this example –column is a setting for format-wide. I had at first thought that format-wide's functionality might be a setting for get-childitem, but this is not so. In order to emulate the dir /W behavior one must hand the get-childitem command to the format-wide command. The pipe symbol provides for this. When you "pipe" one thing to another, you hand that which is on the left of the pipe to that which is on the right of the pipe as an inbound value.
  • "hi there" | out-file "C:\temp\THUNDERDOME.txt" was and example of creating a text file with "hi there" inside of it at C:\temp\THUNDERDOME.txt. I took the photo I provide here at SQLSaturday and in it Jennifer points out how complicated it is to do the same thing in C#. out-file -inputobject "thunderdome" -filepath "C:\temp\Whatever.txt" is a comparable act which will put thunderdome as a string into a new file at C:\temp\Whatever.txt
  • get-psdrive will give you a list of all hierarchies that PowerShell may navigate about. The C drive is a FileSystem for example and HKLM and HKCU are registries. I think Jennifer said that HKLM is Active Directory. One may filter the list to see just the registries with get-psdrive –psprovider registry
  • If the command prompt is PS C:\> then typing set-location HKLM:\ would take one into the Active Directory stuff and out of the file tree at C setting the command prompt to PS HKLM:\> ...I had to Google for how to do this and I found the answer here.
  • After going into active directory, I typed get-childitem and saw a partial list of what there was to see along with an error in the midst of the list telling me... get-childitem : Requested registry access is not allowed. ...Next, set-location SOFTWARE took me into SOFTWARE and from here get-childitem returns a list of installed programs without the error I saw before. I'm not sure how to manipulate the user accounts yet and that wasn't really a big focus in Jennifer's talk. This has some ideas but it seems to be doing it from the C root.
  • Clicking the up arrow at the command prompt will "retype" old commands for you, one at a time, circling backwards in history progressively. F8 seems to do the same thing.
  • sqlps is a tool that Jennifer described as flavor of PowerShell with SQL installed. import-module sqlps –disablenamechecking was how Jennifer recommended installing it but I got an error reading: import-module : File C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\sqlps\Sqlps.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170. ...when I tried. I got around this by running, from the C root, powershell.exe –executionpolicy bypass and then turning back around and running import-module sqlps –disablenamechecking again, but this, which touches on execution policies, illuminates that this policy change comes with a little bit of living dangerously. The prompt I now see is PS SQLSERVER:\>
  • get-help *SQL* is going to get a list of all commands which have sql in the name. The asterisks are wildcards.
  • A list of what is at the root of SQLSERVER looked like this for me...
    1. SQL
    2. SQLPolicy
    3. SQLRegistration
    4. DataCollection
    5. XEvent
    6. Utility
    7. DAC
    8. SSIS
    9. SQLAS
    ...and in going into SQL I could see a MachineName list with my one machine in it, and going into that I could see a Instance Name list with my one instance in it, and going into that I could see...
    1. Audits
    2. AvailabilityGroups
    3. BackupDevices
    4. Credentials
    5. CryptographicProviders
    6. Databases
    7. Endpoints
    8. JobServer
    9. Languages
    10. LinkedServers
    11. Logins
    12. Mail
    13. ResourceGovernor
    14. Roles
    15. ServerAuditSpecifications
    16. SystemDataTypes
    17. SystemMessages
    18. Triggers
    19. UserDefinedMessages
    ...and going into Databases I could see a list of databases. When I went into a database I could see...
    1. ApplicationRoles
    2. Assemblies
    3. AsymmetricKeys
    4. Certificates
    5. DatabaseAuditSpecifications
    6. Defaults
    7. ExtendedProperties
    8. ExtendedStoredProcedures
    9. Federations
    10. FileGroups
    11. FullTextCatalogs
    12. FullTextStopLists
    13. LogFiles
    14. PartitionFunctions
    15. PartitionSchemes
    16. PlanGuides
    17. Roles
    18. Rules
    19. Schemas
    20. SearchPropertyLists
    21. Sequences
    22. ServiceBroker
    23. StoredProcedures
    24. SymmetricKeys
    25. Synonyms
    26. Tables
    27. Triggers
    28. UserDefinedAggregates
    29. UserDefinedDataTypes
    30. UserDefinedFunctions
    31. UserDefinedTableTypes
    32. UserDefinedTypes
    33. Users
    34. Views
    35. XmlSchemaCollections
    ...and inside of Tables I found a list of tables.
  • $txt = "hello" followed by write-host $txt will put hello to the console and at this point just $txt by itself will also put hello to the console. $txt is an example of a variable. The dollar sign denotes a variable. $num = 1 followed by write-host $num will put 1 to the console and if we follow this up with $num = $num + 1 and then write-host $num this will put 2 to the console. Combining variables, $txt = $txt + $num followed by write-host $txt will put hello2 to the console.
  • $txt.Equals('hello') puts False to the console at this point while $txt.Equals('hello2') will put out True and $txt.Length will give us: 6
  • Equals is an example of a Method for a string variable while Length is an example of a Property. To see all of the methods or properties for a type do something like so: $txt | gm or $txt | get-member (gm is an alias for get-member)
  • get-service will give a list of all of the services running on your box, and get-service | format-wide might be the better thing to do so that none of the names get truncated, AdobeFlashPlayerUpdateSvc, for example, was just represented as AdobeFlashPlaye... in the list made by the first, simpler syntax. get-service *sql* will give a list of the services which have SQL in their names and get-service *sql* | select-object Name, Status, DisplayName, ServicesDependedOn | format-table –autosize will give us some of the stats on those services, and more so than just select-service *sql* which will not tell us about the ServicesDependedOn, but let's focus on AdobeFlashPlayerUpdateSvc as that seems like a really harmless service to mess with. get-service AdobeFlashPlayerUpdateSvc | select-object Status tells me that the service is stopped. (get-service AdobeFlashPlayerUpdateSvc).Start() should turn it on, but when I run get-service AdobeFlashPlayerUpdateSvc | select-object Status right after it tells me that it's still stopped. SQLWriter is running and I can successfully stop it and start with (get-service SQLWriter).Stop() and (get-service SQLWriter).Start() so why can't I start AdobeFlashPlayerUpdateSvc? get-service AdobeFlashPlayerUpdateSvc | select-object ServicesDependedOn just returns {} which I'm guessing is an empty list, so there isn't a dependency that's just off. Alright, when I just go into my services and try to start it outside of PowerShell a dialog box tells me: The Adobe Flash Player Update Service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.
  • get-service AdobeFlashPlayerUpdateSvc | select-object * is going to give us a list of all of the obvious stats for AdobeFlashPlayerUpdateSvc but the Startup Type is not one of them and to get that the command is get-wmiobject –class Win32_Service –property StartMode –filter "Name='AdobeFlashPlayerUpdateSvc'" ...alter the state with set-service AdobeFlashPlayerUpdateSvc –startupType disabled and set-service AdobeFlashPlayerUpdateSvc –startupType automatic and set-service AdobeFlashPlayerUpdateSvc –startupType manual
  • Alright, let's write a script! First, we must allow permissions for that with powershell.exe –executionpolicy unrestricted (which I ran from the root of C) and then we should create a script. I created a text file at C:\foo\whatever.txt, renamed it to C:\foo\whatever.ps1, and put this into it...
    $state = ""
    $state = $state + (get-service SQLWriter | select-object Status)
    IF($state -eq "@{Status=Running}")
    {
       echo "stopping..."
       (get-service SQLWriter).Stop()
    }
    ELSE
    {
       echo "starting..."
       (get-service SQLWriter).Start()
    }
    get-service SQLWriter | select-object Status

    ...which I may use to toggle the SQLWriter service on and off by navigating into the foo folder and typing ./whatever.txt
  • get-childitem "C:\somefolder\" *.html is going to give you a list of just the .html files in the somefolder folder.
  • Let's rewrite whatever.ps1 to loop through a collection and write stuff from it to the console:
    $state = "whatever yo"
    1, 2, "Heya", $state | foreach-object {
       write-host $_ -ForegroundColor YELLOW;
       write-host $_ -ForegroundColor RED;
    }
  • I tried to figure out how to open a series of files in notepad combining the stuff in the last two bullet points like so...
    get-childitem "C:\somefolder\" *.html | % {
       notepad $_FullName
    }

    ...but when I do I just get an empty file for each thing I attempt to open. Whatever. Note that % is an alias for foreach-object.
  • If I go back to sqlps and navigate back to the tables I can run a query with invoke-sqlcmd "SELECT * FROM Whatever" and this may be done from outside of the database like so invoke-sqlcmd "SELECT * FROM Whatever" -database MyDatabase
  • write-output "That's all!"
  • clear-host

 
 

Addendum 4/11/2016: I realized today that I have whatever.txt above in a spot where I should have whatever.ps1. Also I learned of start-process explorer ftp://user:pass@example.com -Windowstyle maximized and also of start-sleep -m 3000 today!