Tuesday, May 31, 2016

Visual Studio Live... Lives!

Following up on this, this, and this, a coworker who attended Visual Studio Live today mentioned something else about the experience he had not mentioned before which was that one might think of claims in the Identity paradigm like database permissions. i.e. does a user have the ability to edit database rows or add database rows. He said he heard another say that claims should sort of fall along these lines at the application level. This came after up after a different coworker mentioned that one could sort of query claims in the Identity paradigm as if asking "Do I have this claim?" and the Identity processes will crawl all claims looking for it.

Monday, May 30, 2016

Saturday, May 28, 2016

vicariously experiencing Visual Studio Live!

It's what you want and waited for. Here is the sequel to vicariously experiencing SXSW and the follow up to this teaser and this teaser too: a blog posting on things told to me secondhand about Visual Studio Live as it happened this year in Austin! Yay! There was an effective agile requirements talk on the third day. Should stakeholders do point estimates first as an exercise? It's important to keep in mind the distinction between requirements (what they need) vs. specifications (how to do something). Billy Hollis spoke on UX at a different session. He recommend the book "Universal Principles of Design" by William Lidwell and Kritina Holden. He suggested that the start bar on older Windows implementations got design right and hit on all eight of the points of good UI including 1 the ability to mark favorites, 2 retention/responsiveness around the recently used, and 6 other points my coworkers didn't articulate. Windows 8 in contrast was seen as a design failure. Something to consider is who are the people already using your product and what are the top three reasons they are using it for. Windows 8 targeted Apple users but not the existing Windows users, alienating them. The absence of a file hierarchy (think start menu) was infuriating. Billy's talk went into XAML and how to break down XAML into smaller components to use. He suggested adding components piece by piece instead of trying to plan everything at once. The concept of property injection dependency injection in unit testing was discussed. It was suggested that "new is glue" and that it might be best to lazy load dependencies that you need instead of newing them up. To clarify perhaps the lazy loading a bit it was also suggested that it gets painful to constantly change constructor signatures as dependencies grow and thus perhaps the service locator slant of inversion of control could be the solution. You'll be able to pick your compiler for TypeScript for transpilation down far enough to accommodate that really old version of IE... or not. Visual Studio 16 is coming! Visual Studio 16 may be run on Linux (such as Ubuntu) and OSX assuming you are just using .NET Core. A base .NET Core application is just a console app. You explicitly add in plugins to make it do more. You explicitly say "I want IIS" and "I want MVC" and "I want the old XML Web.config" and you add these one by one as plugins. Another coworker in the room suggested you HAVE to use Entity Framework with with .NET Core and not the old ADO (Active Data Objects) approach and what is more you end up reaching out to the Microsoft Framework by way of a web service to just fall back to the old stuff with regards to the data integration. Maybe the thing to do is to have an old school app exposing ASP.NET Web API endpoints and just talk into that from your Core app for your data needs. I dunno. TypeLITE gives you Intellisense for TypeScript. Google has realized that AngularJS isn't SEO friendly. Ha! Hilarious! They are trying to do something about that. In the meantime a dev at Visual Studio Live suggested that he still breaks apps up into views and then just runs an Angular app inside of each view to get around the problem for now. This begs the question: "Why even use Angular?" ...and I suppose the answer would be that while the use of Angular's views and their breakups are now emasculated there would still be the two-way databinding feature. (I suppose.) Scott Hanselman spoke and suggested that JavaScript is the new assembly language of the internet. In another talk it was recommended not to use the dynamic keyword. The discovery overhead for dynamic is apparently slow much as reflection is slow. The Html Agility Pack was recommended. You can turn on content security policy at browsers and only allow JavaScript from whitelisted sources. This will globally disallow inline JavaScript which "smells" injected another coworker theorized. @Html.AntiForgeryToken() may be used in an MVC app to prevent multiple posts and, yes, forgery. There was content to do with MSSQL 2016. The DIE (drop if exists) approach goes like so: DROP TABLE IF EXISTS dbo.Foo ...and simplifies iffy logic around a sanity check for if it is copacetic to drop. There is now the concept of column masking making, for example, columns of tokenized credit card numbers just appear as, I don't know, asterisks or whatever, instead of actual data when doing queries from code or visually in SSMS. The whether or not as to if you'll get masked data depends on the permissions you have in querying as a user. There is now an unmask permission. If you have the unmask permission you'll just get unmasked goodies. You don't have to explicitly unmask things in a select with SQL syntax or anything like that. Some column types, like blobs of XML, cannot be masked. Encryption keys have been a part of the database meaning that if your database is compromised so too is your data, but now encryption keys may be stored in external flat files. You will pass in the path to said file in a connection string now. You will now be able to select a date from two years ago and see what the data in a table looked like back then. There is some sort of data caching along such lines. There are now JSON data types. A trick I don't really understand as I type this up has to do with file streams and selecting files from a database wherein they are each a blob of data at the database. Supposedly, if you first do a select that will get nothing and follow it up with a second select that gets the blob it will allow your app itself to manage the memory for the download. That doesn't really make much sense now that I type it up.

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

This error bubbles to the yellow and red screen of death from T-SQL when I attempt to hand in a date set with = DateTime.MinValue; in C# which equates to 1/1/0001 and the way to fix it is to instead hand in a date set with = new DateTime(1753,1,1); which is the beginning of the Gregorian calendar in Sweden and the point where it was here to stay.

buddytruk

It's the Uber of Moving? A coworker suggested this is a better go to for finding movers than craigslist.

GNU patch tool

...runs a .patch file to update a library when you just don't want to download the whole fat library. A coworker told me he uses it for Linux stuff.

You may compare timespans to TimeSpan.Zero in a greater than, less than, and/or is equals sense.

TimeSpan.Zero represents no length of time at all in C#!

You can't "reset" a claim as if setting a setting in the Identity paradigm.

Instead if the claims state needs to change you need to emulate logging in anew (or force the user to log in anew). Get the principal which will gather up all the claims which make up one's "identity" one more time. Think of how you can progressively build up the board in a game of Connect Four. You can build onto what is, but if anything needs to change you've gotta dump everything and start over.

If you let David Attenborough change his name at his account to Boaty McBoatface I guess he's just gonna carry on as David's ghost until you do a reset and you probably should reset right away.

Thursday, May 26, 2016

XKCD substitutions plugin

This will mess with your mind changing copy at your browser. The word successfully becomes suddenly and the like. It's a Google Chrome plugin.

How do I debug into the Visual Studio project I've been looping in as a NuGet package?

Go back to looping it in as a Visual Studio project in the short term!

  1. Add the project.
  2. Destroy references to the NuGet package.
  3. Add references to the new project to every project that used the NuGet package.
  4. Close Visual Studio 2015.
  5. Delete the packages folder.
  6. Doctor up each packages.config file in each project where you took out the NuGet reference so it's not sucked back in.
  7. Open back up Visual Studio 2015.
  8. Rebuild!

 
 

Beware the "works on my machine" excuse too if you just keep working like this. Sooner or later you'll want to go back to the NuGet package before you say "It works on my machine." out loud.

Crackle

...is another service like Netflix. You watch commericals with Crackle I hear.

rehydrate NuGet stuff

  1. close Visual Studio 2015
  2. delete the packages folder for the solution
  3. open back up Visual Studio 2015

Wednesday, May 25, 2016

Some NuGet packages are missing from this solution. Click to restore from your online package sources.

Just open the console for NuGet and you may see a yellow bar in Visual Studio 2015 for recovering what you lack. There will be a "Restore" button at the far right to click upon.

Change the color of Visual Studio 2015!

at... Tools > Options > Environment > General > "Color theme:" dropdown

There is a way to set up a Session state server to allow Session to work across numerous other servers which are web servers.

This IIS trick will allow you have a load balancer without Session being sabotaged in ASP.NET applications.

How did we sort and filter arrays in C# a dozen years ago before generics and LINQ/Lambda magic?

This came up in a conversation over Skype at work today. A coworker was working in some old ASP.NET 1.1 land-before-Cassini horribleness. I'm at home now and looking at my own old notes from back in the day. I wrote the unit test below which, yes, passes. I don't miss this at all. I haven't had to think about this in a long, long time.

using System;
using FluffyNothing.Core.Objects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FluffyNothing.Tests.Tests.Objects
{
   [TestClass]
   public class PersonTests
   {
      [TestMethod]
      public void Test()
      {
         
//arrange
         Person[] peeps = new Person[]
         {
            new Person(){ Name = "Moe" },
            new Person(){ Name = "Larry" },
            new Person(){ Name = "Curly" },
            new Person(){ Name = "Shemp" }
         };
         
         
//act
         Person[] truncatedPeeps = Array.FindAll(peeps, Filter);
         Array.Sort(truncatedPeeps, Compare);
         
         
//assert
         Assert.AreEqual(truncatedPeeps.Length, 3);
         Assert.AreEqual(truncatedPeeps[0].Name, "Larry");
         Assert.AreEqual(truncatedPeeps[1].Name, "Moe");
         Assert.AreEqual(truncatedPeeps[2].Name, "Shemp");
      }
      
      private bool Filter(Person person)
      {
         if (person.Name != "Curly")
         {
            return true;
         } else {
            return false;
         }
      }
      
      private int Compare(Person yin, Person yang)
      {
         int result = yin.Name.CompareTo(yang.Name);
         return result;
      }
   }
}

Blu Ray 4K

Well, it's even better than Blu Ray! For times higher resolution! I caught lunch with coworkers who gabbed about the game Overwatch and this came up in conversation. I am hearing of it for the first time. Overwatch too.

Monday, May 23, 2016

unclosed parenthesis in media query expression

I was getting this compilation error in Visual Studio 2015 with regards to a .scss (Sass) file. I got around it by just removing a semicolon. This...

@media (min-height: 301px;) {
   .foo
   {
      overflow-y:scroll;
      overflow-x:hidden;
   }
}

 
 

...became this:

@media (min-height: 301px) {
   .foo
   {
      overflow-y:scroll;
      overflow-x:hidden;
   }
}

Type safety in TypeScript!

As promised, two coworkers gave me and braindump of their Visual Studio Live experience. I have a lot of notes and I'll probably type them up and give you a blog post on it all this weekend. In the short term, here is a teaser. This blob of JavaScript...

function Welcome(x) {
   return "Hello, " + x;
}

 
 

...may be written like so in TypeScript to ensure that a string is handed in for x which is what would make sense.

function Welcome(x: string) {
   return "Hello, " + x;
}

httpservletresponse is some sort of Java response packet.

This has some gunk on it.

The cookieHandler setting for identity may appear to sabotage your application!

I had this at the base of Web.config (well, Web.template.config which builds out Web.config).

   <system.identityModel.services>
      <federationConfiguration>
         <cookieHandler requireSsl="false" />
      </federationConfiguration>
   </system.identityModel.services>
</configuration>

 
 

I changed it like so and my application would not load whatsoever!

   <system.identityModel.services>
      <federationConfiguration>
         <cookieHandler requireSsl="false" path="/" />
      </federationConfiguration>
   </system.identityModel.services>
</configuration>

 
 

A coworker suggested that I just needed to clear cookies, but honestly, when removed the path setting, reran the app (got positive result), and then readded the path setting (got positive result again), that also fixed things too.

Manually force a NuGet reference to update at a project in Visual Studio 2015.

  1. Right-click on "References" and pick "Manage NuGet Packages..." from the menu that appears.
  2. Find the line item to update at the scrollable left content.
  3. If there is a newer version, an icon of a blue circle with a white arrow in it pointing upwards will be seen when you mouse over the line item at the right side of the line item.
  4. Click the icon.

I guess Cortana is the new Clippy.

I just woke in the middle of the night to find that that upgrade to Windows 10 which I thought was never gonna finish finished.

Saturday, May 21, 2016

Visual Studio Live!

The event was here in Austin! Two of my coworkers went to it this week. On Friday they were finally back at the office and on Monday they are to give us all a brain dump. In advance of that though, one of them just gushed to me off the cuff. He said that as of version two of .NET Core there will not be any support for web forms. This fits with something else I saw on Facebook in which it was suggested that there were a lot of breaking changes that came with the second version (in contrast/conflict to the first). The .NET Core stuff can run on Linux and Node and Macintoshes and the like. You don't need IIS. I can't remember if I've mentioned that yet on this blog or not. You can run Python and Ruby in Visual Studio now, or at least get Intellisense for it. It’s a legit editor for the two. .xproj replaces .csproj and it's now JSON instead of XML. There is a move towards configuration files being JSON instead of XML. The same thing happens to the solution files. There is Intellisense for TypeScript. One thing that has changed with C# 7.0 is that this...

if(i is Person)
{
   var per = i as Person;
   
more magic here
}

 
 

...may now be simplified like so:

if(i is Person as per)
{
   
more magic here
}

Friday, May 20, 2016

one time when you might actually want to use a code comment

When an enum in an application parallels a database table as suggested here, but not every value in the database table is used in the application because the application isn't the only application using that database, maybe the unused line items should just be commented out with a note. The two other bad alternatives are:

  • letting the numeric assignments to the line items to appear as if goofy encodings one would at a glance interpret as something ununderstood or understandable, you could just remove the unused line items
  • all line items stay leaving the false impression that all line items are used

Thursday, May 19, 2016

There doesn't need to be a rollback script for the script for creating the first version of your database.

You just drop the database to "rollback." Duh.

The target principal name is incorrect. Cannot generate SSPI context.

This error at a yellow and red screen of death in ASP.NET apps has to do with Kerberos authentication. In my case specifically this reared its head when a single sign on implementation was moved from being a project one joined into a solution to a concern hydrated by NuGet and when I tried to loop in the single sign on stuff the old way the problem appeared. Doing things the right way fixed the problem, and I got out from under this without really understanding what was falling down. The problem happened a second time after I reset IIS and I ended up just restarting the server holding my database to fix the problem a second time.

Scan server settings in an attack that sends a bad XML packet!

It's a thing. Even if the bad packet is just rejected the sender can somehow fish out environment settings and learn about what they are trying to break into. Some links supplied by my superior today were:

Throwback Thursday: Windows XP Unattended Installs

I am a Microsoft Certified Professional! This means very little. It means that I managed to pass one exam: Exam 70-270: Installing, Configuring, and Administering Microsoft Windows XP Professional ...remember a dozen years back when everyone was so obsessed with certs? I ended up with one myself a few years later. Now I'm an MCP. Anyways, the silly test I took was on Windows XP and the big feature to study up on was unattended installs! This was a way to just kick off the install without having to next-next-next through a wizard while waiting minutes on end between panes of the wizard while stuff was shoved to your PC! You could just walk away and come back to it being done! I never actually did it myself and I can't remember anything about it now. I thought this retro forgettable stuff might tickle you.

Wednesday, May 18, 2016

Half of the mechanics of Foursquare have been spun off into a new app called Swarm.

This explains what's what. The geolocation stuff for checking in at locale X gets moved into the new app.

troll versus trolling

In a tech sense, troll is a somewhat subjective and ambiguous term for someone who stirs up trouble online by saying something inflammatory or doing some cyberbullying or the like. Trolling, in a tech sense, may mean the act of being a troll, but it could also mean going to look for something and hoarding information. Trolling could be scrounging/crawling for what you want. A recruiter might go trolling through all of the people associated to a company's LinkedIn profile at LinkedIn to mine those folks as contacts, but that doesn't necessarily mean the recruiter herself is a troll. Get it?

Yammer

It's some sort of private social network that you'd use inhouse to chat with coworkers instead of public facing Skype or that ilk of things. The benefit of this sort of approach is that when someone is fired, they are really gone.

Tuesday, May 17, 2016

Sprocs are interpreted at runtime not compiled when you run an alter.

This sucks because you could be joining to that table you just deleted and it won't throw an error upon your alter. You're going to find out the hard way. You'll get an error if you just outright use bad T-SQL, but there is no sanity checking to see if the things you reach out to are there for you.

legacy code

In the loosest sense this is old, bad code that no one wants to touch out of fear of breaking it. I guess "bad" might be a harsh description. It works right? I guess it's bad in that you can't change it. Two more finite descriptions that could tell you when an app goes from healthy to legacy that I've heard are:

  • This guy suggested that Michael C. Feathers' book "Working Effectively with Legacy Code" has the standard! Any code not under test is legacy code.
  • This guy suggested that code becomes legacy code when it is easier to just build what you need around an application in lieu of trying to change the application.

What do the .min.js.map files do in the Web Essentials way of doing things?

They associate whatever.js to the whatever.min.js file that gets made from it, the later being the minified version of the former. An association tells where to spit out the minified file to and also allows for debugging inside of a minified file to defer back to the beautified version so that it's easier to set breakpoints, read code, and tell what is going on. Why can't the two just be associated by naming convention? It seems like that would work most of time and the map is really only needed if you want the minified file to have a different name or live in a different folder. I wonder if there is just a way to turn the maps off for ninety-nine percent of the use cases where that doesn't apply. I duuno. What overhead, eh?

Monday, May 16, 2016

Microsoft will pay you to use Bing instead of Google!

A coworker pointed out today that if you do enough searches on Bing you'll get gift card money to spend at Amazon or wherever!

"Get Me" and "Fasten" are the new Uber and Lyft in Austin?

Well, not yet.

 
 

Addendum 5/18/2016: Shuan Hickson tweeted to me: @jaeschke And these guys start this weekend: http://ridefare.com/

Sunday, May 15, 2016

Set a datetime in HTML5 with separate controls for date and time.

<div>
   <div>date of event:</div>
   <div>
      <input type="date" id="Date" />
      <input type="time" id="Time" />
   </div>
</div>

Friday, May 13, 2016

How do I select all of my sprocs in SSMS 12 for a mass delete?

  • Select the "Stored Procedures" folder under the "Programmability" folder in SSMS's Object Explorer.
  • Press F7 to open the list of sprocs in an "Object Explorer Details" pane.
  • Herein you may use the old click-and-then-click-a-second-time-while-holding-Shift trick to select everything.
  • Click the "Delete" or "Del" key.

Thursday, May 12, 2016

another reason to use a getsetter

They sure seemed overused, don't they? How often do we overpower/override them with polymorphic tricks? However, I noticed today that an interface in C# may have a getsetter when in cannot merely have a field.

Wednesday, May 11, 2016

To manually assign a permission to a sproc in SSMS 12...

  1. right-click on the stored procedure in the Object Explorer and pick "Properties" from the menu which appears
  2. pick "Permissions" from the menu at the upper right
  3. then click the "Search..." button to bring up the "Select Users or Roles" dialog box
  4. use the "Browse..." button to get what you want and then close out the dialog box with: "OK"
  5. click the "Grant" checkbox for "Execute" for your line item and then click "OK"

LimeWire

This was a tool like KaZaA! for stealing stuff.

Tuesday, May 10, 2016

When you insert an interface as a middleman in an inheritance chain wherein a class otherwise just inherits from an interface in C#...

The middleman interface will not have to hydrate the requirements for the parent interface, not in order to merely compile without error. Instead the class will have to hydrate the requirements for both interfaces.

The Analyzers under References at a Visual Studio 2015 project...

...allow you to make intellisense errors and warnings to appear as you type. Roll your own hintset with this.

Why can't I stop at a breakpoint inside of Application_Start within Global.asax.cs with the debugger?

Well, you can! Rebuild the entire Visual Studio 2015 solution and try it anew! Restarting IIS is NOT enough.

Monday, May 9, 2016

Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context.

This suggests putting this...

void Application_OnError()
{
   var ex = Context.Error;
   if (ex is SecurityTokenException)
   {
      Context.ClearError();
      if (FederatedAuthentication.SessionAuthenticationModule != null)
      {
         FederatedAuthentication.SessionAuthenticationModule.SignOut();
      }
      Response.Redirect("~/");
   }
}

 
 

...in Global.asax.cs will solve this identity/claims problem and it worked for me.

I'm trying to bring in identity into my app from a coworkers changes and now the app doesn't even show up in IIS!

I think the problem is going to be of Web.config. I think I'm going to have to doctor up Web.config to be consistent with what my coworker has, bringing in identityModel stuff.

Cannot pass 'whatever' as a ref or out argument because it is a 'using variable'

Is there is no way to defer out the guts of a using statement? Are we are back to making a procedural mess? No, just hand in the "using variable" are regular variables. Remember reference variables kinda behave as if the ref keyword where there anyways, you know?

This is the last day Uber and Lyft will be in Austin.

They wanted a proposition to pass into law to allow them to continue to do background screenings for their drivers for their ride-hailing apps their way, but it is not to be. I don't know if Chariot for Women is in Austin yet or will continue if it's here. I don't know what other knockoff services will fill the void. I guess we are back to taxicabs for the moment.

Sunday, May 8, 2016

Visual Studio Community

Get is at visualstudio.com. It's Visual Studio Professional for free (assuming you are not using it as a major business presence) but not Enterprise (Ultimate) though. The link I give here also has Visual Studio Code which is Microsoft's Notepad++.

Saturday, May 7, 2016

Don't try to code first with the Code First Entity Framework paradigm.

The disenchantment I express here is really do to with attempting to code first and then have C# objects build out my database. The Code First paradigm is really just a badly named move closer towards an NHibernate way of doing things away from that .edmx thing. If I don't despise NHibernate for not letting me just model in C# then I guess I shouldn't despise Entity Framework for the same "shortcoming" either. Just write SQL to make your tables and then interface with the database you've built out with your SQL from Entity Framework. This will take some getting used to as you learn what Entity Framework wants C# getsetters to map to in the SQL space. A DateTime is to dance with a not null datetime while a nullable DateTime will dance with a datatime column where you can have nulls. A string in C# seems to correspond to a nulls-are-just-fine nvarchar of max length. I don't know how to change that yet. If you want to make a primary key restraint to tie one table to another and have it represented in C#, I have no idea how to make that happen either. Whatever. fun fun!

Yesterday I realized that most events, summoned from one locale in code, may just be written as closures.

Consider these two methods from here:

  1. public ActionResult Export()
    {
       var gridViewSettings = new GridViewSettings();
       gridViewSettings.Name = "whatever";
       gridViewSettings.KeyFieldName = "CustomerID";
       gridViewSettings.Columns.Add("ContactName");
       gridViewSettings.Columns.Add("CompanyName");
       gridViewSettings.Columns.Add("ContactTitle");
       gridViewSettings.Columns.Add("City");
       gridViewSettings.Columns.Add("Phone");
       var printable = GridViewExtension.CreatePrintableObject(gridViewSettings,
             NorthwindDataProvider.GetCustomers());
       
       PrintingSystem ps = new PrintingSystem();
       
       using (this.headerImage = Image.FromFile(Server.MapPath("~\\Content\\pic.png")))
       {
          Link header = new Link();
          header.CreateDetailArea += new
                CreateAreaEventHandler(header_CreateDetailArea);
          
          PrintableComponentLink link1 = new PrintableComponentLink(ps);
          link1.Component = printable;
          
          CompositeLink compositeLink = new CompositeLink(ps);
          compositeLink.Links.AddRange(new object[] { header, link1 });
          
          compositeLink.CreateDocument();
          using (MemoryStream stream = new MemoryStream())
          {
             compositeLink.PrintingSystem.ExportToXls(stream);
             WriteToResponse("filename", true, "xls", stream);
          }
          ps.Dispose();
       }
       return PartialView("View");
    }
  2. void header_CreateDetailArea(object sender, CreateAreaEventArgs e)
    {
       e.Graph.BorderWidth = 0;

       Rectangle r = new Rectangle(0, 0, headerImage.Width, headerImage.Height);
       e.Graph.DrawImage(headerImage, r);

       r = new Rectangle(0, headerImage.Height, 400, 50);
       e.Graph.DrawString("Additional Header information here....", r);
    }

 
 

They may be hammered into one method like so:

public ActionResult Export()
{
   var gridViewSettings = new GridViewSettings();
   gridViewSettings.Name = "whatever";
   gridViewSettings.KeyFieldName = "CustomerID";
   gridViewSettings.Columns.Add("ContactName");
   gridViewSettings.Columns.Add("CompanyName");
   gridViewSettings.Columns.Add("ContactTitle");
   gridViewSettings.Columns.Add("City");
   gridViewSettings.Columns.Add("Phone");
   var printable = GridViewExtension.CreatePrintableObject(gridViewSettings,
         NorthwindDataProvider.GetCustomers());
   
   PrintingSystem ps = new PrintingSystem();
   
   using (this.headerImage = Image.FromFile(Server.MapPath("~\\Content\\pic.png")))
   {
      Link header = new Link();
      header.CreateDetailArea += new
            CreateAreaEventHandler(
(object sender, CreateAreaEventArgs e) => {
               e.Graph.BorderWidth = 0;
            
               Rectangle r = new Rectangle(0, 0, headerImage.Width, headerImage.Height);
               e.Graph.DrawImage(headerImage, r);
            
               r = new Rectangle(0, headerImage.Height, 400, 50);
               e.Graph.DrawString("Additional Header information here....", r);
            }
);
      
      PrintableComponentLink link1 = new PrintableComponentLink(ps);
      link1.Component = printable;
      
      CompositeLink compositeLink = new CompositeLink(ps);
      compositeLink.Links.AddRange(new object[] { header, link1 });
      
      compositeLink.CreateDocument();
      using (MemoryStream stream = new MemoryStream())
      {
         compositeLink.PrintingSystem.ExportToXls(stream);
         WriteToResponse("filename", true, "xls", stream);
      }
      ps.Dispose();
   }
   return PartialView("View");
}

 
 

A followup refactoring after this might be to get rid of headerImage as a class wide variable and just have it isolated to the Export method. That seems cleaner to me.

Friday, May 6, 2016

How can I jam a header onto an Excel sheet I poop out from DevExpress grid data in an MVC app?

This way of doing things needs love if we are going to have a header. In fact, the approach radically changes. I have had an example working, but it yet needs spruce up. The code I offer below is really dirty code but I've been sitting on this for a few days I and I wanted to share it instead of maybe getting to it later. Most of it is stolen from elsewhere, but I don't recall where.

using System.Drawing;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using DevExpress.Web.Mvc;
using DevExpress.XtraPrinting;
using DevExpress.XtraPrintingLinks;
using Modernity.Models;
namespace Modernity.Controllers
{
   public class ExportingController : Controller
   {
      private System.Drawing.Image headerImage;
      
      public ActionResult Export()
      {
         var gridViewSettings = new GridViewSettings();
         gridViewSettings.Name = "whatever";
         gridViewSettings.KeyFieldName = "CustomerID";
         gridViewSettings.Columns.Add("ContactName");
         gridViewSettings.Columns.Add("CompanyName");
         gridViewSettings.Columns.Add("ContactTitle");
         gridViewSettings.Columns.Add("City");
         gridViewSettings.Columns.Add("Phone");
         var printable = GridViewExtension.CreatePrintableObject(gridViewSettings,
               NorthwindDataProvider.GetCustomers());
         
         PrintingSystem ps = new PrintingSystem();
         
         using (this.headerImage = Image.FromFile(Server.MapPath("~\\Content\\pic.png")))
         {
            Link header = new Link();
            header.CreateDetailArea += new
                  CreateAreaEventHandler(header_CreateDetailArea);
            
            PrintableComponentLink link1 = new PrintableComponentLink(ps);
            link1.Component = printable;
            
            CompositeLink compositeLink = new CompositeLink(ps);
            compositeLink.Links.AddRange(new object[] { header, link1 });
            
            compositeLink.CreateDocument();
            using (MemoryStream stream = new MemoryStream())
            {
               compositeLink.PrintingSystem.ExportToXls(stream);
               WriteToResponse("filename", true, "xls", stream);
            }
            ps.Dispose();
         }
         return PartialView("View");
      }
      
      void WriteToResponse(string fileName, bool saveAsFile, string fileFormat,
            MemoryStream stream)
      {
         string disposition = saveAsFile ? "attachment" : "inline";
         Response.Clear();
         Response.Buffer = false;
         Response.AppendHeader("Content-Type", string.Format("application/{0}",
               fileFormat));
         Response.AppendHeader("Content-Transfer-Encoding", "binary");
         Response.AppendHeader("Content-Disposition", string.Format("{0}; filename={1}.
               {2}", disposition, fileName, fileFormat));
         Response.BinaryWrite(stream.GetBuffer());
         Response.End();
      }
      
      void header_CreateDetailArea(object sender, CreateAreaEventArgs e)
      {
         e.Graph.BorderWidth = 0;
      
         Rectangle r = new Rectangle(0, 0, headerImage.Width, headerImage.Height);
         e.Graph.DrawImage(headerImage, r);
      
         r = new Rectangle(0, headerImage.Height, 400, 50);
         e.Graph.DrawString("Additional Header information here....", r);
      }
   }
}

When your load balancer is stripping the s off of https in what it presents to you...

You can't just get dependable URLs from an app for "itself" (links back to itself in emails sent and the like) like so:

Request.Url.ToString().ToLower().Split('?')[0].Replace("/yourimmediatething.aspx","");

 
 

The base URL is going to need to be a setting somewhere in the Web.config or the database or something. Don't try to just replace http:// universal with https:// as you'll find this makes it impossible to test in dev. It's time to stop being clever and start hacking.

Thursday, May 5, 2016

When doing an INSERT in T-SQL you cannot insert specifying numeric positions of columns instead of column names.

Apparently there is a way to do an insert specifying nothing at all assuming you are to use every column in order. Just leave out the first set of parenthesis. This suggests an example might be:

INSERT INTO INVOICE VALUES( 1,1,'KEYBOARD',1,15,5,75);

Wednesday, May 4, 2016

Make Excel sheets exported from DevExpress MVC grids hide and rearrange columns based upon how the user hides and rearranges columns at the grid itself.

more settings here... columns are defined, etc. in black copy at the link's blog posting is a place where one fills in columns at a grid. These now need to be hydrated like so:

settings.KeyFieldName = "CustomerID";
foreach (string column in GridViewPartialViewColumns.Get())
{
   settings.Columns.Add(column);
}
settings.ClientLayout = (sender, e) =>
{
   if (e.LayoutMode == ClientLayoutMode.Saving)
   {
      ReportExporter.BackingStore = (MVCxGridView)sender;
   }
};

 
 

We need to pull the master list of columns in default order from a second place. Let's do something like so:

using System.Collections.Generic;
namespace MoreModernModernity.Views.Home
{
   public static class GridViewPartialViewColumns
   {
      public static List<string> Get()
      {
         return new List<string>()
         {
            "ContactName",
            "CompanyName",
            "ContactTitle",
            "City",
            "Phone"
         };
      }
   }
}

 
 

The ReportExporter class I offer here need to be significantly overhauled.

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using DevExpress.Web.Mvc;
using DevExpress.XtraPrinting;
using Modernity.Views.Home;
namespace Modernity.Models
{
   public static class ReportExporter
   {
      public static MVCxGridView BackingStore { get; set; }
      
      private static GridViewSettings PrepareSettings()
      {
         int counter = 0;
         Dictionary<int, Tuple<int, bool>> instructions = new Dictionary<int, Tuple<int,
               bool>>();
         while (counter < BackingStore.Columns.Count)
         {         
            instructions.Add(BackingStore.Columns[counter].VisibleIndex,new
                  Tuple<int,bool>(counter,BackingStore.Columns[counter].Visible));
            counter++;
         }
         var settings = new GridViewSettings();
         settings.Name = "grid";
         settings.KeyFieldName = BackingStore.KeyFieldName;
         foreach (string column in Rearrange(GridViewPartialViewColumns.Get(),
               instructions))
         {
            settings.Columns.Add(column);
         }
         return settings;
      }
      
      private static List<string> Rearrange(List<string> defaultColumns, Dictionary<int,
            Tuple<int, bool>> instructions)
      {
         List<string> newColumns = new List<string>();
         int counter = 0;
         foreach (string defaultColumn in defaultColumns)
         {
            if (instructions[counter].Item2)
            {
               newColumns.Add(defaultColumns[instructions[counter].Item1]);
            }
            counter++;
         }
         return newColumns;
      }
      
      public static ActionResult MakeExcelSheet(Object data)
      {
         GridViewSettings settings = PrepareSettings();
         ActionResult actionResult = GridViewExtension.ExportToXls(settings, data,
               new XlsExportOptionsEx { ExportType =
               DevExpress.Export.ExportType.WYSIWYG });
         return actionResult;
      }
   }
}

 
 

This could be more elegant. BackingStore could be a dictionary of MVCxGridView types that one could look up by magic string names such as "Home" which would allow thus to scale beyond one implemenation. I guess it needs love in other places too if that is to work. GridViewPartialViewColumns needs some sort of inheritance implementation, etc.

Tuesday, May 3, 2016

I saw some flakiness in which a DevExpress namespace could show up and the appropriate .dll was in the bin folder yet the project wasn't referenincg the .dll!

It happened with DevExpress.XtraPrinting.v15.2.dll and I had to manually add the .dll as a reference to get the code to understand the PrintingSystem type even though the namespace was looped in OK. Messed up! You can't just type in some nonsense in a using declaration and expect C# to compile, you have to use a namespace that really is a namespace, but how does C# know of a namespace outside of the references? Is it crawling the bin folder and using what it finds to halfway work in a misleading way? WTF? Maybe a different DevExpress .dll depends on DevExpress.XtraPrinting.v15.2.dll which was why it was in the bin folder to begin with (as I didn't put it there) and... You know what, I bet a namespace is split across two .dlls and I had the ineffective half to start with. Maybe that is what is going on. Nasty.

Monday, May 2, 2016

How do I allow users to export GridViews to Excel sheets in DevExpress' MVC paradigm?

The example here is pretty convoluted and even includes a few methods which are not used, but it basically suggests that you'd have a button in your view like so:

@using (Html.BeginForm("Index", "Exporting"))
{
   <input type="submit" value="Export" />
}

 
 

Assuming NorthwindDataProvider.GetCustomers() is what hydrates our grid lets go ahead and use that to also hydrate our Excel sheet. The Excel sheet does not need to read directly from the GridView. This is going to hit an action like so:

using System;
using System.Web.Mvc;
using Modernity.Models;
namespace Modernity.Controllers
{
   public class ExportingController : Controller
   {
      public ActionResult Index()
      {
         Object data = NorthwindDataProvider.GetCustomers();
         return ReportExporter.MakeExcelSheet(data);
      }
   }
}

 
 

My helper class for returning the ActionResult is below. GridViewSettings is a DevExpress thing found in the DevExpress.Web.Mvc namespace.

using System;
using System.Web.Mvc;
using DevExpress.Web.Mvc;
using DevExpress.XtraPrinting;
namespace Modernity.Models
{
   public static class ReportExporter
   {
      public static ActionResult MakeExcelSheet(Object data)
      {
         GridViewSettings gridViewSettings = new GridViewSettings();
         gridViewSettings.Name = "report";
         ActionResult actionResult = GridViewExtension.ExportToXls(gridViewSettings,
               data, new XlsExportOptionsEx {ExportType =
               DevExpress.Export.ExportType.WYSIWYG});
         return actionResult;
      }
   }
}

 
 

One may make an Adobe Acrobat PDF instead of an Excel sheet by making the second the last line of code immediately above look like so:

ActionResult actionResult = GridViewExtension.ExportToPdf(gridViewSettings, data);