I spite of what I thought here, it has been pointed out to me that jQuery does lose more than half of its file size when minified. It is so big that it has that much copy in private variable names and line returns or other whitespace. Unbelievable! Alright, if you're using a giant 3rd party library or rolling your own, then, yes, you should minify. Another way to really help is to bundle many minified files into one for one trip over the wire in delivery. There is a way in ASP.NET MVC apps to keep not minified files at the server and to minify and send upon client request. This allows for debugging against the easy-to-read stuff and the performance gain of minification to really come in the trip over the wire on the fly.
Thursday, March 31, 2016
CollabNet
These guys have a bunch of products which together do too much just like TFS! It's source control, no it's continous integration, no it's bug tracking...
Addendum 3/20/2019: continuous not continous
How do I prevent an ASPxUploadControl from breaking when I upload something too big.
You can upload the image in chunks and if the chunks exceed a limit then you can proactively freak out ahead of things getting really bad.
<dx:ASPxUploadControl id="Foo" runat="server" ClientIDMode="Static"
ClientInstanceName="Bar" OnFileUploadComplete="Foo_FileUploadComplete"
UploadMode="Advanced">
<ValidationSettings MaxFileSize="1048576" MaxFileSizeErrorText="Fail!"/>
<AdvancedModeSettings PacketSize="131072"></AdvancedModeSettings>
</dx:ASPxUploadControl>
This magic happens in an async-under-the-hood manner and not on a post of a form. Start an upload like so from JavaScript:
Bar.Upload();
At the code behind we need...
protected void Foo_FileUploadComplete(object send, FileUploadCompleteEventArgs e)
{
byte[] bytes = new byte[e.UploadedFile.FileContent.Length];
using (Stream fileStream = e.UploadedFile.FileContent)
{
fileStream.Read(bytes, 0, (int) fileStream.Length);
}
DoWhatever(bytes);
}
Wednesday, March 30, 2016
copy/paste into a VMware VM that doesn't want to allow it
...by using the "Paste" option under the "Edit" menu at the top nav of VMware.
MaxFileSize="1048576" MaxFileSizeErrorText="Fail!"
These settings inside a ValidationSetting tag inside a dx:ASPxUploadControl tag will restrict the size of an upload to 1MB (1024 bytes x 1024), but they do not handle a scenario in which the limit is so exceeded that the control cannot make sense of just how big the image is. It feels like DevExpress does an upload and then decides if the upload is too big, and that, of course, only works for the modestly big. Dan Aykroyd not John Candy.
Tuesday, March 29, 2016
Debugging Stopwatch
I found this in my old notes today. I don't know what it's all about.
using (var stopWatch = new DebugTrace("Whatever"))
{
foreach (var foo in Foos)
{
//do something here
}
throw (new Exception(stopWatch.Message));
}
Addendum 8/23/2018: There is such a thing as a Stopwatch in C#. This touches on them some. This is something like a Timer but different. You measure how long an application took to do its thing with a Stopwatch. The example here is probably all you need.
Let's hack! How may I keep a serialized bytes array as a string to later make an image in an MVC application?
I've had the need to do this twice now and so here is a blog posting. Let's make a class you will later throw away like so:
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace Airport.Core.Utilities
{
public static class Stringification
{
public static string ForFile(string path)
{
byte[] bytes = File.ReadAllBytes(path);
using (var memoryString = new MemoryStream())
{
using (var xmlTextWriter = new XmlTextWriter(memoryString, Encoding.UTF8))
{
var xmlSerializer = new XmlSerializer(bytes.GetType());
xmlSerializer.Serialize(xmlTextWriter, bytes);
using (var xmlTextWriterMemoryStream = (MemoryStream)
xmlTextWriter.BaseStream)
{
UTF8Encoding utf8Encoding = new UTF8Encoding();
return utf8Encoding.
GetString(xmlTextWriterMemoryStream.ToArray()).Substring(1);
}
}
}
}
}
}
Most of the magic above comes from this and you will ultimately make the string an image like this. Just keep the string in a static helper class somewhere. Anyhow, to see what your dummy throwaway class makes, I would just pull it up into a view and then copy and paste the XML out the what the view renders. Some applicable razor markup is:
@Stringification.ForFile("C:\\foo\\bar.jpg")
After you get the copy you may want to replace the double quotes with single quotes. There are not many of them and this act will be harmless. This act will make it a little more painless to just keep the string inside double quotes in C#.
Relocate a subversion repository with TortoiseSVN.
Right-click on the root of the directory and pick "Relocate..." under "TortoiseSVN" there will be a dropdown list for where to relocate to and you may either pick something or type in your own entry. Why do you want to relocate? This act is what you do when you abandon one hosting of subversion for another with the directories set up the same, i.e. we are migrating the hosting. You will likely need to first, before this step, open a repo-browser to the new hosting and log in and click upon: "Accept the certificate permanently"
Monday, March 28, 2016
.Find versus .Where in a Lambda in C#
IEnumerable<Foo> match = Foos.Where(item => item.Description == "Yuck");
...may be rewritten as...
Foo match = Foos.Find(item => item.Description == "Yuck");
...and doing so will make a spinning machine that stops spinning upon finding the first match.
Sunday, March 27, 2016
Catch errors for a particular web from standalone with the Page_Error event!
This goes in the code behind and will happen before the yellow and red, ketchup and mustard screen of death:
void Page_Error(object sender, EventArgs e)
{
//whatever
Saturday, March 26, 2016
There is a night and day difference between Whatever.callBack() and Whatever.PerformCallback() in DevExpress' web forms paradigm.
Assuming Whatever is an ASPxCallbackPanel, the later above is legit while the former will give you errors like this:
Length cannot be less than zero.
Parameter name: length
Friday, March 25, 2016
checksum
Wikipedia suggests: "A checksum or hash sum is a small-size datum from a block of digital data for the purpose of detecting errors which may have been introduced during its transmission or storage. It is usually applied to an installation file after it is received from the download server. By themselves checksums are often used to verify data integrity, but should not be relied upon to also verify data authenticity."
Thursday, March 24, 2016
Put "this" in the watch window in Visual Studio 2015.
It should give a list of what is in scope in global variables and the like.
Wednesday, March 23, 2016
How do I refactor an ObjectDataSource to hand in a variable to a method in lieu of just calling a method without any parameters at the signature?
There probably is a way but I can't tell you what it is, I just hacked around the problem. I deleted this from my web form...
<asp:ObjectDataSource ID="MySource" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="DoSomething"
TypeName="Whatever.MyClassElsewhere"></asp:ObjectDataSource>
...and put this in my code behind.
List<Stuff> stuff = MyClassElsewhere.DoSomething(13);
var gridViewDataComboBoxColumn =
(GridViewDataComboBoxColumn)MyGrid.Columns["Meh"];
gridViewDataComboBoxColumn.PropertiesComboBox.DataSource = stuff;
What I am trying to do is hydrate the selectable values at a GridViewDataComboBoxColumn which is a column header in an ASPxGridView (MyGrid in my example above) so I will need to doctor up the following markup to remove the DataSourceID parameter.
<dx:GridViewDataComboBoxColumn FieldName="Meh" Caption="Yawn">
<PropertiesComboBox DataSourceID="MySource" ValueField="StuffyValue"
TextField="StuffyName" ValueType="System.String"
DropDownStyle="DropDown" />
</dx:GridViewDataComboBoxColumn>
Addendum 3/27/2016: It has been pointed out to me over Twitter that this has this example:
<asp:objectdatasource
id="ObjectDataSource1"
runat="server"
selectmethod="GetEmployee"
typename="Samples.AspNet.CS.EmployeeLogic">
<selectparameters>
<asp:querystringparameter name="EmployeeID" querystringfield="empid"
defaultvalue="-1" />
</selectparameters>
</asp:objectdatasource>
Tuesday, March 22, 2016
null-coalescing and caching playing nicely together
I thought I was gonna have a nosebleed when I first saw this thing. The second half of the one line of code that really matters below is an assignment, so how is the null-coalescing operator picking out the second half of the assignment (the second half of the second half that is) as worthwhile?
public List<Foo> GoGetIt()
{
return _cacheThing.Bar ?? (_cacheThing.Bar = _dataThing.Bar().ToList());
}
Well, if you think about it, this would return the thing getting assigned on the spot.
public List<Foo> GoGetIt()
{
return _cacheThing.Bar = _dataThing.Bar().ToList();
}
_dataThing.Bar().ToList() gets assigned to _cacheThing.Bar and then _cacheThing.Bar gets returned, all on one line of code. You may make an assignment and return the thing you just assigned to all at once. If you're like me you probably don't see this so much in code, so it looks strange. So, that makes the null-coalescing magic a little easier to understand, huh? The magic itself doesn't really have anything to do with the null-coalescing operator. Also, you would need to managing the caching elsewhere like so:
public List<Foo> Bar
{
get
{
return (List<Foo>)HttpContext.Current.Cache["Qux"];
}
set
{
Cache("Qux", value);
}
}
Monday, March 21, 2016
Skype commands...
They start with a slash. They do different things. You just type in a command where you would otherwise chat. /showmembers for example shows all members in the current group chat session in a list.
Saturday, March 19, 2016
the ASPxUploadProgressHttpHandler for a ASPxFileManager is throwing errors suggesting it cannot find files which end in .aspx which don't even exist
This needs to be triggered by something in the Application_Start method of Global.asax.cs:
routes.Ignore("{*ashx}", new { ashx = @".*\.ashx(/.*)?" });
Addendum 3/22/2016: You may also need to exclude .js and .css files in the same manner. That said, I now suspect that this problem I'm fighting is particular to the home-rolled routing of the app in front of me.
Friday, March 18, 2016
web form error page in MVC!
This blog posting suggests you have to spec a web forms page for a custom error page in MVC app by putting something like so in the system.web stuff at Web.config!
<customErrors mode="On" defaultRedirect="404.aspx"/>
This will suffice for uncaught exceptions thrown in .NET itself. I tested it and it worked for me. There is some dirtiness in which the web form will return a 200 OK header, but I think you may fight your way out of this wet paper bag like so:
<% Response.StatusCode = 404; %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="404.aspx.cs"
Inherits="Airport.Mvc._404" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>Whoa! Oh no!</div>
</form>
</body>
</html>
The blog posting also suggests putting something like this in the system.webServer stuff at Web.config to catch errors thrown in IIS (as opposed to .NET exceptions).
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="404.aspx" responseMode="File"/>
</httpErrors>
...but when I try this I see the error page interpreted as if a .txt file splashing what you see in the middle of this blog posting, angle brackets and all, up to the user to see. Maybe this is because I am running Visual Studio locally and getting the extra variable of using Cassini or IIS Express or whatever it is. I dunno.
Waze
...is an app (a mobile app) for suggesting ways to drive home, to dodge traffic and speed traps and the like.
serve up an image with @Url.Action
In an ASP.NET MVC application, your action could look like:
public ActionResult Image()
{
byte[] bytes;
using (StringReader stringReader = new StringReader(Images.Plane()))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(byte[]));
bytes = (byte[])xmlSerializer.Deserialize(stringReader);
return File(bytes, "image/jpg");
}
}
And, in your view you would have:
<img src="@Url.Action("Image", "Home")"/>
Thursday, March 17, 2016
secure enclave
the OutputCache attribute
Per this: Output caching lets you store the output of an action method in memory on the Web server.
Throttling
ATT's old plans for the iPhone gave unlimited data and they had to throttle down how fast you got the data to accommodate as much which was otherwise impossible to support. The joke is on you!
capacitors and resistors
Electricity spools up in a capacitor and is then let out at a consistent rate. It does not necessarily flow in at a consistent rate though. A resistor acts as a dampening widget to keep power coming in at too heavy a rate from advancing and burning something up downstream of the resistor. A consistent or at least a no-greater-than-X amount of electricity should also thus emerge from a resistor. I guess when a breaker in tripped a power surge has made it beyond the safeguards and caused havoc.
What is Paymetric exactly?
It's payments integration with the ERPs and PCI compliance and...
Addendum 6/9/2017: Vantiv does payment processing and they bought Paymetric.
Addendum 6/18/2019: Vantiv has become Worldpay.
Turn on/off power saving mode in Windows 7.
- go to the Control Panel
- search for "Power Options"
- go to "Change power-saving settings" by that icon which at first glance looks like a teapot but is really an electical cord wrapping a battery
- click the appropriate "Change plan settings" link here
Wednesday, March 16, 2016
The singleton pattern came up in conversation at Monday night's ADNUG.
It and it's static state stuff could be used for ISessionFactory for NHibernate I suppose. The example of allowing only one user to access a particular thing (one user has the key at any one point in time) was an example in conversation.
foolproof
Challenge: How can I compare two form fields at ASP.NET MVC DataAnnotations and have that make its way into jquery.validate.unobtrusive.min.js client-side validations as a sanity check? Like so?
using System;
using System.ComponentModel.DataAnnotations;
namespace Airport.Core.Objects
{
public class Flight
{
public int FlightId { get; set; }
public float Duration { get; set; }
public DateTime DepartureTime { get; set; }
[Required]
public int DepartureCity { get; set; }
[Required]
[Compare("DepartureCity", ErrorMessage = "No one flies to the same city.
Com'on.")]
public int DestinationCity { get; set; }
}
}
Well, that would work dandy if I wanted DepartureCity and DestinationCity to be the same as I might for the two fields for double-entry of a password, but it this case I want just the opposite. I want to be sure that DepartureCity and DestinationCity are different. Could I do this instead?
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Airport.Core.Objects
{
public class Flight : IValidatableObject
{
public int FlightId { get; set; }
public float Duration { get; set; }
public DateTime DepartureTime { get; set; }
[Required]
public int DepartureCity { get; set; }
[Required]
public int DestinationCity { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (DepartureCity == DestinationCity)
{
yield return new ValidationResult("No one flies to the same city. Com'on.", new[]
{ "DestinationCity" });
}
}
}
}
The yield keyword before return above suggests that the enumeration in scope will be incremented in addition to the return doing its thing. I don't use the yield keyword enough to feel comfortable (well, confident) with it. Meh. Anyhow, this is also not what I want because it only happens server-side and not client-side and that sucks. The fix is the get the foolproof NuGet package like so:
install-package foolproof "Airport.Core"
This installed version 0.9.5851.39131 of FoolproofValidation. I'm realizing that the package manager console is really just a PowerShell console and install-package is a PowerShell command. If something distinguishes the NuGet console from a PowerShell window in another light, I don't know what it is. Clearly there are going to be some directory settings (defaults) that are not out-of-the-box, but beyond just settings is anything different? I dunno. Anyways, in trying to get back on topic, I noticed that the NuGet package made a "Client Scripts" folder full of .js files, but as I did not install the package at my UI project I manually moved the .js files to my "Scripts" folder in the MVC project. I put this...
<script src="~/Scripts/mvcfoolproof.unobtrusive.min.js" type="text/javascript">
</script>
...just below this...
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript">
</script>
...at my view and I changed my model again like so:
using System;
using System.ComponentModel.DataAnnotations;
using Foolproof;
namespace Airport.Core.Objects
{
public class Flight
{
public int FlightId { get; set; }
public float Duration { get; set; }
public DateTime DepartureTime { get; set; }
[Required]
public int DepartureCity { get; set; }
[Required]
[NotEqualTo("DepartureCity", ErrorMessage="No one flies to the same city.
Com'on.")]
public int DestinationCity { get; set; }
}
}
This is what I wanted. http://foolproof.codeplex.com/ has some examples (well, notes) on other comparisions you may do with foolproof. You may do greater-than/less-than comparisons to compare dates and the like. Yay! In all three validations above the error message will appear by the DestinationCity field and not the DepartureCity field and if you look close you can probably figure out why.
How may I have events at a DevExpress MVC GridView like I used to at the ASPxGridView grids in the web forms way of doing things?
In this example we use HtmlDataCellPrepared to string format a DateTime type. Note that I do not have the explictly cast e.CellValue to DateTime.
@Html.DevExpress().GridView(
settings =>
{
settings.Name = "GridView";
settings.HtmlDataCellPrepared = (sender, e) =>
{
if (e.DataColumn.FieldName == "Day")
{
e.Cell.Text = String.Format("{0:MM/dd/yyyy}", e.CellValue);
}
};
settings.Width = Unit.Percentage(100);
settings.SettingsPager.PageSize = 32;
settings.Settings.VerticalScrollBarMode = ScrollBarMode.Visible;
settings.Settings.VerticalScrollableHeight = 350;
settings.ControlStyle.Paddings.Padding = Unit.Pixel(0);
settings.ControlStyle.Border.BorderWidth = Unit.Pixel(0);
settings.ControlStyle.BorderBottom.BorderWidth = Unit.Pixel(1);
settings.Columns.Add("FlightId");
settings.Columns[0].Caption = "Flight";
settings.Columns.Add("Day");
settings.Columns.Add("DepartureCityName");
settings.Columns[2].Caption = "Leaving";
settings.Columns.Add("DepartureTimeAndTimeZone");
settings.Columns[3].Caption = "Leaving";
settings.Columns.Add("DestinationCityName");
settings.Columns[4].Caption = "Arriving";
settings.Columns.Add("DestinationTimeAndTimeZone");
settings.Columns[5].Caption = "Arriving";
}).Bind(Model).GetHtml()
Tuesday, March 15, 2016
I saw Barrett Simms of Clear Launch speak on unit testing at the Austin. NET User Group last night.
This was a pretty straightforward talk on the stuff you might expect. Barrett set up sister test projects for testable projects in a Visual Studio solution and used MOQ for mocking, and so on. He used Unity for dependency injection instead of StructureMap, but it too offers the trick of autohydrating interfaces at the constructor signature of MVC controllers and this ultramodern tricky was referred to as the "Unit of Work" pattern. So what did I learn that was new for me?
- If you make a change and that breaks something which previously worked that is a regression.
- The Boy Scout mantra of "Leave it as you found it." (honestly, I think it's really: "Leave the campground cleaner than you found it.") applies to writing tests. They should be nullipotent and running them zero times or one hundred times should cause the same number of effects (zero) on the code base and beyond. If you are putting things to a database in an integration test you should also be cleaning it back away as part of your teardown process, etc. You should not be wrecking things with your tests.
- If you are making a change in a huge app with no unit tests, just worry about getting your change under test. You don't have to refactor the whole app into something testable. Just do the right thing for what you introduce.
- Simian is a tool that finds duplicate code in your code base so that you may consolidate it. One great way to get your code coverage statistic up is to reduce the duplicate code. Slapping the [ExcludeFromCodeCoverage] attribute on things is even better! (I'm kidding.) NCover is the code coverage tool Barrett uses. dotCover is an open source version of the third version of NCover per Mr. Simms even though it's also clearly a JetBrains not-free product. Maybe I'm missing something. JetBrains ReSharper also has some code coverage capabilities baked into it with all the other magic.
- Don’t write tests around T4 (Text Template Transformation Toolkit) template stuff unless it's your own T4 stuff.
- BaseAspNetAngularUnity is an open source GitHub project that Barrett made for getting starting doing things his way. It has a better nude MVC app (his opinion) than the out-of-the-box one that comes out of Visual Studio by default. His thing has MOQ in test projects and AngularJS and Unity already cozy together.
- It's almost impossible to get code coverage up to 100%. Chill out.
- At the end of the talk Barrett asked the audience what qualities make for "good code" and a list which started with functional grew into: functional, readable, fast, maintainable, extensible, and testable, but unfortunately it started out as just functional alone and he heavily cautioned against using that alone as the gold standard. A 1973 Ford Pinto which takes you from A to B is not a quality car even though it's functional.
A coworker mentioned today that anything for which you may have a foreach in C# is either an IEnumerable or a subtype of IEnumerable.
An array of string or a List of string may be assigned to a variable defined as an IEnumerable of string. A Dictionary of string, string may be assigned to a similar IEnumerable variable of KeyValuePair(s) which are specifically of a string, string shape. A different coworker illuminated that skeletons are taboo in China and thus cleaned out of the Chinese versions of a lot of games, but that's less interesting. Well, not less interesting, but less important, vital.
How do I convert to a float in C#?
flight.Duration = float.Parse(Convert.ToString(dataRow["Duration"]));
Addendum 3/16/2016: It has been suggested to me that Convert.ToSingle() is the better way to go.
an example of using an indexer at a class in C#s
using System;
using System.Collections.Generic;
using System.Linq;
namespace ComfyCozyAreWe.Core.Objects
{
public class Sleigh
{
private string _lead;
private Dictionary<string, string> _lackeys;
public Sleigh(string lead, Dictionary<string, string> lackeys)
{
if (String.IsNullOrWhiteSpace(lead) || lackeys == null || lackeys.Count == 0 ||
lackeys.Keys.Any(x => String.IsNullOrWhiteSpace(x)) ||
lackeys.Values.Any(y => String.IsNullOrWhiteSpace(y)))
{
throw new Exception("The sleigh won't go far.");
} else {
_lead = lead;
_lackeys = lackeys;
}
}
public string this[int index]
{
get
{
SanityCheckPosition(index);
if (index != (_lackeys.Count*2))
{
int position;
if (index%2 == 0)
{
position = index/2;
} else {
position = (index-1)/2;
}
int counter = 0;
foreach (KeyValuePair<string, string> pairing in _lackeys)
{
if (counter == position)
{
if (index%2 == 0)
{
return pairing.Key;
} else {
return pairing.Value;
}
}
counter++;
}
}
return _lead;
}
set
{
SanityCheckPosition(index);
string key = null;
if (index != (_lackeys.Count*2))
{
int position;
if (index%2 == 0)
{
throw new Exception("Don't mess with the left side.");
} else {
position = (index-1)/2;
}
int counter = 0;
foreach (KeyValuePair<string, string> pairing in _lackeys)
{
if (counter == position)
{
key = pairing.Key;
break;
}
counter++;
}
}
if (key != null)
{
_lackeys[key] = value;
} else {
_lead = value;
}
}
}
public int Count()
{
return (_lackeys.Count*2)+1;
}
private void SanityCheckPosition(int position)
{
if (!(position < Count()) || position < 0)
{
throw new Exception("There is no one there.");
}
}
}
}
Let's test what is above like so:
using System;
using System.Collections.Generic;
using ComfyCozyAreWe.Core.Objects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ComfyCozyAreWe.Core.Tests.Objects
{
[TestClass]
public class SleighTests
{
private Sleigh _sleigh;
[TestInitialize]
public void Prepare()
{
Dictionary<string, string> lackeys = new Dictionary<string, string>();
lackeys.Add("Dasher", "Dancer");
lackeys.Add("Prancer", "Vixen");
lackeys.Add("Comet", "Cupid");
lackeys.Add("Dunder", "Blixem");
_sleigh = new Sleigh("Rudolph", lackeys);
}
[TestMethod]
public void getter_behaves_as_expected()
{
Assert.AreEqual(_sleigh[0], "Dasher");
Assert.AreEqual(_sleigh[1], "Dancer");
Assert.AreEqual(_sleigh[2], "Prancer");
Assert.AreEqual(_sleigh[3], "Vixen");
Assert.AreEqual(_sleigh[4], "Comet");
Assert.AreEqual(_sleigh[5], "Cupid");
Assert.AreEqual(_sleigh[6], "Dunder");
Assert.AreEqual(_sleigh[7], "Blixem");
Assert.AreEqual(_sleigh[8], "Rudolph");
}
[TestMethod]
public void setter_behaves_as_expected()
{
string error = null;
try
{
_sleigh[6] = "Donner";
}
catch (Exception exception)
{
error = exception.Message;
}
Assert.AreEqual("Don't mess with the left side.", error);
_sleigh[7] = "Blitzen";
Assert.AreEqual(_sleigh[7], "Blitzen");
_sleigh[8] = "Olive";
Assert.AreEqual(_sleigh[8], "Olive");
}
}
}
Monday, March 14, 2016
It was suggested to me tonight that a good use for the Strategy pattern...
...lies in cleaning up nested if/else logic that drills several steps deep to narrow in on a... whatever.
the old school .ExecuteScalar() way of writing a record with a sproc in C#
public void SaveFlight(Flight flight)
{
using (SqlConnection sqlConnection = new SqlConnection(foo))
{
using (SqlCommand sqlCommand = new SqlCommand())
{
sqlCommand.CommandText = "dbo.AddFlight";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Connection = sqlConnection;
sqlCommand.Parameters.AddWithValue("@Duration", flight.Duration);
sqlCommand.Parameters.AddWithValue("@DepartureTime", flight.DepartureTime);
sqlCommand.Parameters.AddWithValue("@DepartureCity", flight.DepartureCity);
sqlCommand.Parameters.AddWithValue("@DestinationCity",
flight.DestinationCity);
sqlConnection.Open();
sqlCommand.ExecuteScalar();
}
}
}
Prep .DropDownListFor lists in Razor with default empty first values which a user must explicitly change out.
This is basically the first half of this form revamped a bit:
@model Airport.Core.Objects.Flight
<h1>Add a Flight</h1>
@{
Dictionary<string,string> dictionary = ViewBag.Cities;
var cities = new SelectList(dictionary, "Key", "Value");
}
@using (Html.BeginForm("Add", "Flight", FormMethod.Post, new {id="form"}))
{
<div>
@Html.LabelFor(m => m.Duration)
@Html.TextBoxFor(m => m.Duration)
@Html.ValidationMessageFor(m => m.Duration)
</div>
<div>
@Html.LabelFor(m => m.DepartureTime)
@Html.TextBox("Date", null, new {@type = "date"})
@Html.TextBox("Time", null, new {@type = "time"})
@Html.TextBoxFor(m => m.DepartureTime, new {@class = "displaynone"})
@Html.ValidationMessageFor(m => m.DepartureTime)
</div>
<div>
@Html.LabelFor(m => m.DepartureCity)
@Html.DropDownListFor(m => m.DepartureCity, cities)
@Html.ValidationMessageFor(m => m.DepartureCity)
</div>
<div>
@Html.LabelFor(m => m.DestinationCity)
@Html.DropDownListFor(m => m.DestinationCity, cities)
@Html.ValidationMessageFor(m => m.DestinationCity)
</div>
<div>
<input type="submit" value="submit" onclick="var fate = prepare(); return fate;" />
</div>
}
The controller...
using System.Collections.Generic;
using System.Web.Mvc;
using Airport.Core.ExternalDependencies;
using Airport.Core.Objects;
namespace Airport.Mvc.Controllers5
{
public class FlightController : Controller
{
private IFlightRepository _flightRepository;
public FlightController(IFlightRepository flightRepository)
{
_flightRepository = flightRepository;
}
public ActionResult Index()
{
return View();
}
public ActionResult Add()
{
Dictionary<string, string> cities = new Dictionary<string, string>();
cities.Add("","");
foreach (City city in Session["cities"] as List<City>)
{
cities.Add(city.CityId.ToString(),city.CityName);
}
ViewBag.Cities = cities;
return View();
}
[HttpPost]
public ActionResult Add(Flight flight)
{
return View("EndOfAdd");
}
}
}
Restrict the number of decimal places at a float and validate a datetime at a Razor form!
@model Airport.Core.Objects.Flight
<h1>Add a Flight</h1>
@using (Html.BeginForm("Add", "Flight", FormMethod.Post, new {id="form"}))
{
<div>
@Html.LabelFor(m => m.Duration)
@Html.TextBoxFor(m => m.Duration)
@Html.ValidationMessageFor(m => m.Duration)
</div>
<div>
@Html.LabelFor(m => m.DepartureTime)
@Html.TextBox("Date", null, new { @type = "date" })
@Html.TextBox("Time", null, new { @type = "time" })
@Html.TextBoxFor(m => m.DepartureTime, new { @class="displaynone" })
@Html.ValidationMessageFor(m => m.DepartureTime)
</div>
<div>
<input type="submit" value="submit" onclick="var fate = prepare(); return fate;" />
</div>
}
<script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() { });
function prepare() {
var floaties = $("#Duration").val().split(".");
if (floaties.length !== 2) {
$("span[data-valmsg-for='Duration']").html("Keep float small.");
return false;
} else {
if (floaties[0].length > 2) {
$("span[data-valmsg-for='Duration']").html("Keep float small.");
return false;
} else {
if (floaties[1].length > 2) {
$("span[data-valmsg-for='Duration']").html("Keep float small.");
return false;
} else {
var datetime = $("#Date").val() + " " + $("#Time").val();
if (datetime.length < 16) {
$("span[data-valmsg-for='DepartureTime']").html("Give a time.");
return false;
} else {
$("#DepartureTime").val(datetime);
return true;
}
}
}
}
}
</script>
The displaynone class just does what you'd expect.
.displaynone {
display: none;
}
Use Data Annotations in tandem with the validate/unobtrusive thing to prevent angle brackets from being passed in a form in the MVC paradigm.
This controller is silly and does not save submissions, but just squint your eyes and pretend it's not silly for now. This isn't the important part.
using System.Web.Mvc;
using Airport.Core.ExternalDependencies;
using Airport.Core.Objects;
namespace Airport.Mvc.Controllers5
{
public class FlightController : Controller
{
private IFlightRepository _flightRepository;
public FlightController(IFlightRepository flightRepository)
{
_flightRepository = flightRepository;
}
public ActionResult Index()
{
return View();
}
public ActionResult Add()
{
return View();
}
[HttpPost]
public ActionResult Add(Flight flight)
{
return View(flight);
}
}
}
Alight, you do not want to do validations like this, instead you want to use data annotations. That allows for regular expressions. A model may be dressed up like so, and note the very different way (from this) in which I handled the double quote.
using System.ComponentModel.DataAnnotations;
namespace Airport.Core.Objects
{
public class Flight
{
public float Duration { get; set; }
[Required(ErrorMessage = "Don't leave whatever blank.")]
[RegularExpression(@"^([a-z]*[A-Z]*[0-9]*[\.]*[\s]*[\']*[""]*[?]*[!]*[-]*[=]*[\*]*[:]*[;]*[,]*
[\\]*[/]*[{]*[}]*[|]*[\[]*[\]]*[\(]*[\)]*[+]*[`]*[~]*[@]*[_]*[#]*[\$]*[%]*[\^]*[&]*)*$",
ErrorMessage = "Don't put angle brackets in whatever.")]
public string Whatever { get; set; }
}
}
The last thing I have to share below is my view. I think you can see how one cannot hand angle brackets in for Whatever, but beyond this one cannot hand angle brackets in for Duration either as Duration will validate against a float type datapoint and floats don't have angle brackets floating within them. Duh.
@model Airport.Core.Objects.Flight
<h1>Add a Flight</h1>
@using (Html.BeginForm("Add", "Flight"))
{
<div>
@Html.LabelFor(m => m.Duration)
@Html.TextBoxFor(m => m.Duration)
@Html.ValidationMessageFor(m => m.Duration)
</div>
<div>
@Html.LabelFor(m => m.Whatever)
@Html.TextBoxFor(m => m.Whatever)
@Html.ValidationMessageFor(m => m.Whatever)
</div>
<div>
<input type="submit" value="submit" />
</div>
}
<script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
});
</script>
.EditorFor
@Html.EditorFor(m => m.Email) instead of @Html.TextBoxFor(m => m.Email) in ASP.NET MVC's Razor trappings will not necessarily make a text type input. It will make a dropdown list for an enum or a checkbox for a Boolean, and so on. The error: Uncaught ReferenceError: ASPxClientTextBox is not defined ...at the console suggests DevExpress is screwing up and cannot make a ASPxClientTextBox for an EditorFor!
Every GridView gets its own partial in DevExpress' MVC paradigm.
The partial here in a dummy app I made is summoned into the main view like so:
@model List<Airport.Core.Objects.City>
<p>We are proud to offer flights to the following U.S. cities:</p>
@Html.Partial("GridViewPartialView", Model)
Friday, March 11, 2016
Error converting data type numeric to decimal.
This error occurred for me when I was trying to catch a decimal type variable at a stored procedure. I fixed this by making what I caught a numeric type variable and then I cast to a decimal like so:
CAST(@Duration AS DECIMAL(4,2))
Another error I bumped into was...
Arithmetic overflow error converting numeric to data type numeric.
...and this error comes when you are trying to shove something beyond a decimal's bounds into a container that can't contain it. My DECIMAL(4,2) column was orginally a DECIMAL(2,2) column meaning that it could have two decimal places but no numbers before the decimal itself. This isn't what I really wanted.
Addendum 3/14/2016: Don't try to cast a numeric to a decimal. The decimal places become zeros. I'm not sure if rounding is involved. Just don't do this. Also, zeros is the pural of zero and zeroes is the verb for zeroing out something.
You should be able to right-click on blocked .dlls and pick: "Unblock"
This came up in conversation today. I've not myself bumped into the blocked files. It seems TeamCity can make files the NTFS (New Technology File System) file system deems dangerous.
How do I change what column headers say at a DevExpress MVC GridView?
Assuming something like this:
@Html.DevExpress().GridView(
settings =>
{
settings.Name = "GridView";
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.SettingsPager.PageSize = 32;
settings.Settings.VerticalScrollBarMode = ScrollBarMode.Hidden;
settings.Settings.VerticalScrollableHeight = 350;
settings.ControlStyle.Paddings.Padding = System.Web.UI.WebControls.Unit.Pixel(0);
settings.ControlStyle.Border.BorderWidth = System.Web.UI.WebControls.Unit.Pixel(0);
settings.ControlStyle.BorderBottom.BorderWidth =
System.Web.UI.WebControls.Unit.Pixel(1);
settings.Columns.Add("CityName");
settings.Columns.Add("TimeZoneName");
}).Bind(Model).GetHtml()
How can we give friendlier names to the CityName and TimeZoneName columns? It turns out it's not too tough!
@Html.DevExpress().GridView(
settings =>
{
settings.Name = "GridView";
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.SettingsPager.PageSize = 32;
settings.Settings.VerticalScrollBarMode = ScrollBarMode.Hidden;
settings.Settings.VerticalScrollableHeight = 350;
settings.ControlStyle.Paddings.Padding = System.Web.UI.WebControls.Unit.Pixel(0);
settings.ControlStyle.Border.BorderWidth = System.Web.UI.WebControls.Unit.Pixel(0);
settings.ControlStyle.BorderBottom.BorderWidth =
System.Web.UI.WebControls.Unit.Pixel(1);
settings.Columns.Add("CityName");
settings.Columns.Add("TimeZoneName");
settings.Columns[0].Caption = "City";
settings.Columns[1].Caption = "Timezone";
}).Bind(Model).GetHtml()
Thursday, March 10, 2016
There are no primary or candidate keys in the referenced table 'dbo.Foo' that match the referencing column list in the foreign key 'FK_Bar'.
Good news! This is an easy T-SQL bug to beat. Before you can run something like this...
ALTER TABLE dbo.Foo ADD CONSTRAINT
FK_Bar FOREIGN KEY
(
BazId
) REFERENCES dbo.Baz (
BazId
) ON UPDATE NO ACTION ON DELETE NO ACTION
...you must remember to run something like this:
ALTER TABLE dbo.Baz ADD CONSTRAINT
PK_Baz PRIMARY KEY CLUSTERED
(
BazId
) WITH (
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
The ControllerConvention file which the StructureMap.MVC5 NuGet package creates is messed up in Visual Studio 2015 implementations.
I suggest replacing it with something like so:
using StructureMap;
using StructureMap.Graph.Scanning;
namespace Airport.UserInterface.DependencyResolution
{
using System;
using System.Web.Mvc;
using StructureMap.Graph;
using StructureMap.Pipeline;
using StructureMap.TypeRules;
public class ControllerConvention : IRegistrationConvention
{
public void ScanTypes(TypeSet types, Registry registry)
{
foreach (Type type in types.AllTypes())
{
if (type.CanBeCastTo<Controller>() && !type.IsAbstract)
{
registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
}
}
}
}
}
Obviously, this will need to be changed up some at your app as your app will not be named "Airport" right? I didn't know that using directives could be nested inside of a namespace, but it seems that they may be.
You may name a new solution and it's startup project two different things in Visual Studio 2015.
I'm just noticing this today. That find-the-folder dialog box allows one to spec two different settings. Behold:
Wednesday, March 9, 2016
If you try to cast something out of Session in C# with the as keyword and it's not really that type at all...
...you will end up with a variable of that type that is just null. Perhaps this won't work with things that cannot be null, but it will jive with a majority of types. I'm learning this is a C# distinction between casting with as versus casting with the type name in parenthesis. Also if you use the is keyword in lieu of the as keyword you can see if the thing in Session is even the type you anticipate in an if statement.
How do we set up the modern StructureMap wireups for MVC which do not use ObjectFactory?
Oh boy, it's not trivial at all. Let's start by creating a solution with the Onion Architecture in Visual Studio 2015. The UI will be an MVC project and there will also be a Core and an Infrastructure project which will be class libraries. The UI will inherit both the Core and the Infrastructure and the Infrastructure will inherit the Core so that the Core inherits no other projects and is not contaminated by external concerns (making it easy to unit test). Our interfaces will live in the Core and the classes that implement them and hydrate them will live in the Infrastructure.
- using System.Collections.Generic;
namespace Airport.Core.ExternalDependencies
{
public interface IFlightRepository
{
KeyValuePair<string, string> HappyPass();
}
}
- using System.Collections.Generic;
using Airport.Core.ExternalDependencies;
namespace Airport.Infrastructure.ExternalDependencies
{
public class FlightRepository : IFlightRepository
{
public KeyValuePair<string, string> HappyPass()
{
return new KeyValuePair<string, string>("Happy?", "Yes");
}
}
}
- using System.Web.Mvc;
using Airport.Core.ExternalDependencies;
namespace Airport.UserInterface.Controllers
{
public class HomeController : Controller
{
private IFlightRepository _flightRepository;
public HomeController(IFlightRepository flightRepository)
{
_flightRepository = flightRepository;
}
public ActionResult Index()
{
var model = _flightRepository.HappyPass();
return View(model);
}
}
}
Obviously our three example files in our three projects above could be a lot slicker, but something simple like this will suit our needs. The goal here is to hand "Happy? Yes" off to our view as a model. In order for that to happen something is going to have to hand in an instance of FlightRepository at the constructor of HomeController. How is that possible? Well, we will need some help. Running Install-Package StructureMap in NuGet's console gives us gives us version 4.1.0.361 of StructureMap and furthermore running Install-Package CommonServiceLocator gives us version 1.3.0 of CommonServiceLocator. We need these specifically at the UI project. Moving forward from here the next step is to make a new class in the App_Start folder like so:
using System.Web;
using System.Web.Mvc;
using Airport.UserInterface.App_Start;
using Airport.UserInterface.DependencyResolution;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using StructureMap;
[assembly: PreApplicationStartMethod(typeof(StructuremapMvc), "Start")]
namespace Airport.UserInterface.App_Start
{
public static class StructuremapMvc
{
public static StructureMapDependencyScope StructureMapDependencyScope { get;
set; }
public static void Start()
{
IContainer container = IoC.Initialize();
StructureMapDependencyScope = new
StructureMapDependencyScope(container);
DependencyResolver.SetResolver(StructureMapDependencyScope);
DynamicModuleUtility.RegisterModule(typeof(StructureMapScopeModule));
}
}
}
The PreApplicationStartMethod attribute in the class is going to force the Start method to run when the application is spun up. However, we need a lot more than just this class to hydrate our interface at our controller's constructor. Create a folder in the UI called DependencyResolution and put these five classes in it. (no kidding)
- using System;
using StructureMap;
using StructureMap.Graph;
using StructureMap.Graph.Scanning;
using StructureMap.Pipeline;
namespace Airport.UserInterface.DependencyResolution
{
public class ControllerConvention : IRegistrationConvention
{
public void ScanTypes(TypeSet types, Registry registry)
{
foreach (Type type in types.AllTypes())
{
registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
}
}
}
}
- using StructureMap;
namespace Airport.UserInterface.DependencyResolution
{
public static class IoC
{
public static IContainer Initialize()
{
var container = new Container(c => c.AddRegistry<DefaultRegistry>());
return container;
}
}
}
- using System.Web;
using Airport.UserInterface.App_Start;
namespace Airport.UserInterface.DependencyResolution
{
public class StructureMapScopeModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, e) =>
StructuremapMvc.StructureMapDependencyScope
.CreateNestedContainer();
context.EndRequest += (sender, e) => {
StructuremapMvc.StructureMapDependencyScope
.DisposeNestedContainer();
};
}
}
}
- using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.ServiceLocation;
using StructureMap;
namespace Airport.UserInterface.DependencyResolution
{
public class StructureMapDependencyScope : ServiceLocatorImplBase
{
private const string NestedContainerKey = "Nested.Container.Key";
public StructureMapDependencyScope(IContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
Container = container;
}
public IContainer Container { get; set; }
public IContainer CurrentNestedContainer
{
get
{
return (IContainer)HttpContext.Items[NestedContainerKey];
}
set
{
HttpContext.Items[NestedContainerKey] = value;
}
}
private HttpContextBase HttpContext
{
get
{
var ctx = Container.TryGetInstance<HttpContextBase>();
return ctx ?? new
HttpContextWrapper(System.Web.HttpContext.Current);
}
}
public void CreateNestedContainer()
{
if (CurrentNestedContainer != null)
{
return;
}
CurrentNestedContainer = Container.GetNestedContainer();
}
public void Dispose()
{
DisposeNestedContainer();
Container.Dispose();
}
public void DisposeNestedContainer()
{
if (CurrentNestedContainer != null)
{
CurrentNestedContainer.Dispose();
CurrentNestedContainer = null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return DoGetAllInstances(serviceType);
}
protected override IEnumerable<object> DoGetAllInstances(Type
serviceType)
{
return (CurrentNestedContainer ??
Container).GetAllInstances(serviceType).Cast<object>();
}
protected override object DoGetInstance(Type serviceType, string key)
{
IContainer container = (CurrentNestedContainer ?? Container);
if (string.IsNullOrEmpty(key))
{
return serviceType.IsAbstract || serviceType.IsInterface
? container.TryGetInstance(serviceType)
: container.GetInstance(serviceType);
}
return container.GetInstance(serviceType, key);
}
}
}
- using Airport.Core.ExternalDependencies;
using Airport.Infrastructure.ExternalDependencies;
using StructureMap;
using StructureMap.Graph;
namespace Airport.UserInterface.DependencyResolution
{
public class DefaultRegistry : Registry
{
public DefaultRegistry()
{
Scan(
scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
For<IFlightRepository>().Singleton().Use<FlightRepository>();
}
}
}
Notice that the very last of these actually has the magic to associate FlightRepository with IFlightRepository. What a journey! This alone will not empower Web API 2 controllers also. After I figured all of this out today my superior stopped by my desk and pointed out to me that the stuff I had stolen out of a Visual Studio 2013 app and recreated at my app could have been made for me if I had run Install-Package StructureMap.MVC5 to do all of the work I hand-rolled and also Install-Package StructureMap.WebAPI2 would add in the Web API stuff. #sadtrombone
Tuesday, March 8, 2016
Don't use the back button.
This could be a legit warning from a web site if you are hip-deep in a wizard. What if you are moving sensitive data forward in a wizard by way of a series of form posts in lieu of tucking it away to Session or ViewState or whatever. This isn't hacky or ghetto per say.
ghetto Angular?
In an MVC app why not just swap out partials with jQuery in lieu of using a formal SPA framework? Keep it light?
Amazon will buy back your gift cards at a loss to you.
Ever had a gift card you never used? Of course you have. Gift cards are something scamesque like rebates wherein a certain percentage of those who could redeem the redeemable will just be too apathetic to do so translating into a win for the orchestrating party. Amazon will let you just hand in a gift card in exchange for Amazon money/credit with which to shop at Amazon, so a gift card to one place in particular is now a gift card to everywhere making the gift cards suck less. The same coworker who told me about this today also mentioned that if you have less than five dollars on a gift card that it is the law here in Texas that the card may be redeemable for the balance in cash. I guess if you're a heroin addict but you have a bunch of gift cards you may scrounge together enough money for one more fix. Honestly, you could just buy stuff with the cards and then pawn what you bought too... well, depending on what the card is for. You can't pawn Alamo Drafthouse movie tickets I suppose.
AJAX forms in Razor!
This has this example for uploading files!
@using (Ajax.BeginForm("AsyncUpload", "Upload", new AjaxOptions() { HttpMethod =
"POST" }, new { enctype="multipart/form-data"})) {
Drink from an iFrame with jQuery and make a button disabled with a tooltip too!
If "refreshme" is the id attribute on the iFrame tag...
$(function () {
listenForLogoChange();
});
function listenForLogoChange() {
var listener = function () {
var backingstorewrapper = $("#refreshme").contents().find("#IsChanged")[0];
var backingstore = $(backingstorewrapper).val();
if (backingstore === "true") {
$("#EmailTriggerTest").attr("disabled", "disabled");
$("#EmailTriggerTest").attr("title", "Logo changes must be saved before they may
be tested.");
}
}
var interval = setInterval(listener, 100);
}
Word!
mint
This application manages your budget and helps you plan for retirement and that sort of thing. Meh.
Friday, March 4, 2016
Thursday, March 3, 2016
Did you know there are four heaps in .NET?
- generation 0
- generation 1
- generation 2
- Large Object Heap
Objects greater than 85,000 bytes go on the LOH!
Wednesday, March 2, 2016
What are filegroups in MSSQL?
These are where database tables are actually kept in files on a server, and, yes, they are kept somewhere. There is a folder structure that holds data files. The default is PRIMARY but you may change this setting. I remember when I first starting using mySQL databases in lieu of Microsoft Access databases what a big adjustment it was to think of a database as a thing running out there somewhere of which I didn't have to pay attention for an actual file, but MySQL did use files that I never saw and so too does SQL Server.
Limit a DevExpress ASPxTextBox to fifty alphanumeric characters!
This goes inside the tag.
<RegularExpression ValidationExpression="[A-Za-z0-9]{1,50}$" ErrorText="Allows up to
50 alphanumeric characters." />
at the "Defects" tab for the story...
Within CA Technologies (used to be Computer Associates) tool CA Agile Central (used to be Rally) one may see the Defects for a story at the "Defects" tab for the story. You may add a new defect under this tab too. Otherwise, I don't know how one associates a defect to a story after the fact. Wait, I spoke too soon! At the far right where you pick an owner for a defect there is a place to set the associated story.
Tuesday, March 1, 2016
you may right-click in the midst of a SQL file in SSMS and under "Connection" pick options for "Connect..." and "Disconnect..."
Yes, this will allow you to spec which database you want to connect to to run the script. A coworker suggested this today in the name of jogging things into working in a vein similar to restarting your computer. :P
Invalid filegroup 'DATA' specified.
When you get this error in SSMS, just remove...
ON [DATA]
...from the SQL script and you should have an easier time creating tables. This stuff shows up in the midst of constraints as defined in T-SQL.