I finished reading it for a second time through yesterday.

I finished reading it for a second time through yesterday.
A distinction was made between:
This offers something like:
string xml = null;
using (var memoryStream = new MemoryStream())
{
using (var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8))
{
var xmlSerializer = new XmlSerializer(whatever.GetType());
xmlSerializer.Serialize(xmlTextWriter, whatever);
using (var xmlTextWriterMemoryStream = (MemoryStream)
xmlTextWriter.BaseStream)
{
UTF8Encoding utf8Encoding = new UTF8Encoding();
xml = utf8Encoding.GetString(xmlTextWriterMemoryStream
.ToArray()).Substring(1);
}
}
}
This suggests a way to get the string back to a C# type might look something like this:
Whatever whatever;
using (var stringReader = new StringReader(xml))
{
var xmlSerializer = new XmlSerializer(typeof(Whatever));
whatever = (Whatever) xmlSerializer.Deserialize(stringReader);
}
If you serialize a type to XML in C#, put it in a string, and then, while stopped at a breakpoint in Visual Studio, copy and paste the text out of the string, remember to take out the backslashes before you do anything substantive with it. Otherwise the backslashes will cause C# to blow up when you attempt to deserialize.
Per this, this needs to go into Web.config in the system.webserver section:
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
.trim() in JavaScript does just what you'd think...
var urlVariables = window.location.href.split("/");
if (urlVariables[urlVariables.length-1].trim() == "") {
Addendum 2/3/2018: .trimRight() and .trimLeft() are also a thing. There is a way to do left padding to right align things too. I'm not sure how "pad left" and "trim end" or "trim start" all work.
...are the diagrams which show a piece of a dataset (circle) partially overlaying a different dataset (circle) where common data exists in the two different datasets.
...is a NuGet package which allows one to bring in dependencies at an ASP.NET MVC controller implicitly when the constructor is called like so:
namespace Whatever
{
public class MyController : Controller
{
public IMyRepository MyRepository { get; set; }
public IFrameController(IMyRepository myRepository)
{
MyRepository = myRepository;
}
public ActionResult Index()
{
var model = MyRepository.GetThatOneThingWeNeed();
return View(model);
}
}
}
In this example, when one tries to visit http://www.example.com/my/ at a browser, the appropriate class which implements the IMyRepository interface is magically hydrated at the controller's constructor. The NuGet package creates a "DependencyResolution" folder at an MVC project to facilitate the code to empower this trick. The code in the classes at the App_Start folder are dressed up some to appropriately utilize what is in the DependencyResolution folder too. DefaultRegistry.cs in DependencyResolution seems to be the new place to wire up the dependencies one used to wire up in the Global.asax.cs in yesteryear (MVC3). StructureMap.WebApi2 is the sister NuGet package for the Web API. WebActivatorEx is used to pull some of the new code that comes with the other two packages out into attributes in lieu of having it liter Global.asax.cs.
Make one like so:
public ActionResult Whatever()
{
IHtmlString html = new HtmlString("<strong>I'm yelling!</strong>");
return View(html);
}
Use what you just made like this:
@model IHtmlString
@{
Layout = null;
}
<html>
<head>
<title>Whatever</title>
</head>
<body>
@Html.Raw(Model)
</body>
</html>
...are replacing mirroring. The groups have replicas instead of mirrors and one may query replicas and not just the master.
In an ASP.NET MVC Web API method one may typically throw an exception like so:
throw new Exception("No data was provided.");
...and then catch it at a jQuery .ajax implementation like so:
$.ajax({
type: "POST",
url: 'http://www.example.com/api/whatever',
dataType: 'json',
data: whatever,
success: function (result) {
alert("success: " + result);
},
error: function (request, status, error) {
var responseText = JSON.parse(request.responseText);
alert(responseText.ExceptionMessage);
}
});
HOWEVER, if you are doing cross-site interactions and CORS is thrown into the mix, you cannot throw an error in this way and expect the specific error to make its way back to the jQuery implementation. Instead, try doing something like so in a method that returns an HttpResponseMessage anyways in the event of everything going well:
var error = Request.CreateResponse<string>(HttpStatusCode.BadRequest,
"No data was provided.");
error.Headers.Add("Access-Control-Allow-Origin", "*");
return error;
The catching looks a bit different too:
$.ajax({
type: "POST",
url: 'http://www.example.com/api/whatever',
dataType: 'json',
data: whatever,
success: function (result) {
alert("success: " + result);
},
error: function (request, status, error) {
alert(request.responseJSON);
}
});
To fix:
This error suggests that something has not yet been prepped in IIS. Type "turn windows features on or off" at the search at the charm bar in Windows Server 2012 R2 Datacenter to get the "Add Roles and Features Wizard" anew, then... well, you know...
Not all Maestro cards have start dates (or issue dates) on them as it turns out, and another field which one should try to collect when payment processing a Maestro card which may or may not be on an individual card is an issue number. As a concept, an issue number identifies a particular card for an account. In an American Express account, two cards, perhaps for a husband and wife, may both have the same credit card number, but may be distinguished in terms of which card was actually used to make a payment by the CVV number. The issue number in the Maestro scenario facilitates differentiation comparably. This concept may have existed in Switch and Solo cards too, but these card types are now absorbed into Maestro.
This suggests the "modern" way to make a singleton which brings back an injected dependency in a StructureMap implementation might be like so:
public static BreadcrumbTracker ObtainTracker()
{
return StructureMap.ObjectFactory.Container.GetInstance<BreadcrumbTracker>();
}
A vendor offering a way to pay by credit card does not have to provide a way for cards with 3-D Secure security to go through 3-D Secure sanity checking. This form of security may be enabled if a vendor wishes if or it may not be. Think of how SPF records help in DNS and yet how they too are really just optional.
WQL stand for WMI Query Language and WMI stands for Windows Management Instrumentation. Some links:
Here are how the four types of joins will behave against these two database tables. First off, I got a surprise when it turned out the ambiguous join wherein only the world join is specified like so...
SELECT *
FROM LowercaseLetters AS l
JOIN UppercaseLetters AS u
ON l.LowerId = u.UpperId
...behaved not like a left join as I expected here, but like an inner join. It did the same thing as this:
SELECT *
FROM LowercaseLetters AS l
INNER JOIN UppercaseLetters AS u
ON l.LowerId = u.UpperId
The left join looks like so in contrast:
SELECT *
FROM LowercaseLetters AS l
LEFT JOIN UppercaseLetters AS u
ON l.LowerId = u.UpperId
The super magic amazing right join looks like this:
SELECT *
FROM LowercaseLetters AS l
RIGHT JOIN UppercaseLetters AS u
ON l.LowerId = u.UpperId
The cross join returns 169 rows!
SELECT *
FROM LowercaseLetters AS l
CROSS JOIN UppercaseLetters AS u
One. Make a new project in Visual Studio 2013. Under the Windows templates within the Visual C# templates there is now a "Windows Service" template. You will want to use this. I name my application JaeschkeService in this example. In Visual Studio 2010 implementations I get the impression that one just made a console application and then made the one class inherit from ServiceBase, bringing in a reference to System.ServiceProcess. Don't do this. I tried to set something up in this manner and whenever I went to start the service I'd get an opaque error message which read:
Error 1053: The service did not respond to the start or control request in a timely fashion.
Two. Make code changes. There are really only two files of interest in the new application. One is the typical Program.cs that exists in any console application. It basically looks like this:
using System.ServiceProcess;
namespace JaeschkeService
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
The other is our service. It is called Service1.cs and it basically looks like this:
using System.ServiceProcess;
namespace JaeschkeService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
}
You may have noticed that Service1.cs does a lot of nothing. Let's fix that. Using suggestions here, I have doctored up Service1.cs to once per minute write the current time to a text file at C:\Whatever\stuff.txt like so:
using System;
using System.IO;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace JaeschkeService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Timer timer = new Timer();
timer.Interval = 60000;
timer.Elapsed += OnTimer;
timer.Start();
}
protected override void OnStop()
{
}
public void OnTimer(object sender, ElapsedEventArgs args)
{
string file = @"C:\Whatever\stuff.txt";
using (Stream stream = new FileStream(file, FileMode.Append))
{
byte[] bytes = ASCIIEncoding.ASCII.GetBytes(DateTime.Now + " ... ");
stream.Write(bytes, 0, bytes.Length);
}
}
}
}
Three. You will need to switch to viewing Service1.cs in the designer mode to make the next few changes, so let's make the switch now. To be honest, you will most likely have started out seeing Service1.cs in designer mode and would have had to manually switch to the code view in the previous step to make the code changes. I guess I should have said something before now. Anyways, you may switch views by right-clicking upon Service1.cs in the Solution Explorer and then picking either "View Designer" or "View Code" from the menu which appears.
Four. If you just click in the designer pane for Service1.cs you will see properties for the service in the "Properties" pane. The default name is just "Service1" and I think we should change this. I change it, the "ServiceName" setting, to "MyService" in this example.
Five. We need an installer. Right-click in the designer pane for Service1.cs and pick "Add Installer" to make this happen.
Six. You will now see a new file for the installer in the Solution Explorer. Build the application at this point. Once you build the application you will be done working in Visual Studio 2013. We are well over halfway through the steps at this point. w00t!
Seven. Next let's install the service by opening the "Developer Command Prompt for VS2103" as administrator, navigating to the Debug folder inside of the bin folder within the project we made, and then running this command:
installutil.exe JaeschkeService.exe
By the way, if you ever want to uninstall a service, you also navigate to the same place and then run a command like this:
installutil.exe /u JaeschkeService.exe
Eight. You will need to enter credentials for an account to run the service in the "Set Service Login" dialog box which appears. The account you use should be an account that has permissions to do the things you need done. For example, I used an account that had permissions to access and edit C:\Whatever\stuff.txt of course.
Nine. Open the "Services (Local)" list. In Windows 8, I found it by typing "services.msc" at the "Search" at the charm bar. Right-click on the service you just made and pick "Start" to get it running. Double-clicking on the service will expose even more options and at the "General" tab one may set the "Startup type:" to "Automatic" to make the service start automatically when the PC itself starts up. My service was found under the list with the name "MyService" where I started it and let it run a bit. I checked C:\Whatever\stuff.txt and as expected I could see the precious minutes left in the last day I have before I turn forty just ticking away like so:
8/23/2014 10:14:05 PM ... 8/23/2014 10:15:05 PM ... 8/23/2014 10:16:05 PM ...
That means that as painful as 1.1 was, there was once something even worse!
When stopped at a breakpoint or a line you walked to by way of F10 or F11 from a breakpoint, right-click at the line you wish to back up to and pick "Set Next Statement" from the line items which appear. You may also click where you wish to be and then press Ctrl-Shift-F10!
I tried just downloading the .vsix online and trying to double-click it to install it but it misbehaved. :( This is the other way to approach the same challenge.
To make this DotNetNuke error go away:
Note: For this to work, you will need the "DNNCorp" folder in the "DesktopModules" folder within the DotNetNuke application. I hate to say this explicitly as you probably should just already have this folder, but in my circumstance, I did not. I seem to be cobbling together a working DotNetNuke app. Anyways, in the absence of this folder the "Activate your License" link more or less goes nowhere.
This command will give you information on your memory banks:
Get-WmiObject CIM_PhysicalMemory | select banklabel,capacity,caption,devicelocator,partnumber
These interesting metrics were suggested by a Joel Rice at an event I went to last night which was a warm up for the 2014 Austin Heart Walk to be held on October 18. The event was at "Maggiano's Little Italy" in the Domain.
at the "Network Adapter" setting check the checkbox for: "Bridged: Connected directly to the physical network"
In the name of fixing this ASP.NET error...
Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same. If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection. If the server is on the local machine, and if the before mentioned registry value does not exist or is set to 0, then the state server connection string must use either 'localhost' or '127.0.0.1' as the server name.
...this suggests you need to start the "ASP.NET State Service" Windows Service.
This has a pretty good cheat sheet.
Follow the first three steps here and then click the "More..." button.
I am learning today that this is not something to do willy-nilly.
VirtualBox is another way to do Virtual Machines not unlike VMware. I think we may have been using this @hand. I sounds familiar.
...seems pretty awesome. There are a lot of recordings of tech talks you may have missed there. I've been to two different talks now (one in Fort Worth and one in Austin) where Shawn Weisfeld was taping the talk for UserGroup.tv. Cool!
As of the coming of new CEO Satya Nadella, Microsoft has shut down its Xbox wing and let go of thousands of Xbox related employees. This article suggests that perhaps Microsoft will just sell off Xbox to another company so maybe the Xbox isn't done, done, done. The Xbox and also Bing were the biggest money holes for Microsoft at the beginning of this year. I can remember going to a talk in the 1990s wherein a speaker said that if you put Sony and... I dunno, maybe Nintendo, together that you'd have a company as big as Microsoft in terms of revenue. Microsoft seems to charge into technologies where it feels another entity might challenge it (threaten it) and thus I guess they thought they needed to get into gaming. It does seem that they are more legitimately threatened anymore by Google which has grown quite impressive, though I cannot imagine Bing rivaling google.com. Meh. I digress.
This has some notes on it. The Wikipedia write up says it is to: "implement long-running processes as workflows"
Six years later... this fact has really changed the web, huh? Flash is gone, and I don't miss it.
This isn't too tough in our modern time. In Visual Studio 2013, right click on a .xaml file and pick "Open in Blend..." which will spin up the Blend app where you should next just pick: File > Import > Import Adobe Illustrator File... (just save the file when you're done importing/that's it)
This tells us that running... Select * from Assemblies ...at the DotNetNuke database will reveal what version of DotNetNuke is running and that sure seems to be true! Word.
I went to lunch with two coworkers today. I drove my car to the restaurant. As I drove the CD I bought recently played. One of my coworkers asked what was playing and when I showed him the case he wondered aloud if he could get the songs on Spotify. He uses Spotify to manage his music instead of buying CDs (as I do) because he is... smart/modern. I Googled Spotify today and it looks like it is a music service for a smartphone or a tablet like iTunes, but also platform agnostic and, per this, less expensive all and all. The CD in my story is "Pitch Black Prism" by "Alias" which is brand new as of this month and contains a lot of cool instrumental tracks. The restaurant in my story is "WinFlo" which is also pretty new (newer than this three-year-old blog) and has Italian food and pizzas. (It is in Austin, Texas.)
You may perhaps hack PDF concatenation like so if you don't have Adobe Acrobat, but if you actually have the software, you may definitely slurp the contents of one PDF into another by going to "Insert from File" under "Pages" under "Tools" as seen here:
Let's make some icons! Yay!
Addendum 8/22/2014: My boss pointed out to me today that http://icofx.ro/ might be a better tool to use. (Just get a free trial.) The reason is that the first tool doesn't do transparencies as good and transparent pixels may appear as black instead of transparent in some cases when they are done wrong. While I am talking about icons, it is possible to make an icon in a tool like Photoshop too by making a .bmp and then manually changing the extension to be .ico, but you don't want to do this. Icon files have four sizes:
...and, if you do the .bmp to .ico trick you are just accomodating one of the four sizes and the image will just scale poorly to fit the other three sizes when circumstance demands.
Addendum 10/6/2014: This is wrong. I think there are eight sizes.
...not without being guilty of breaking with PCI standards. You may store a credit card number if the credit card number is tokenized. You may also dance in the grey areas a little bit by storing an encoded* CVV temporarily at a database and then wiping it out when a transaction is completed. In this scenario you'll also have to have a process running that cleans away CVVs from abandoned transactions. If you are wondering how a wallet works without storing CVVs it is merely by not storing CVVs at all. You do not have to use a CVV in a transaction, but parties which take payments which do not require CVVs are apt to pay higher interchange rates and stick their necks out for more liability in general should a claim be disputed.
*or perhaps encrypted. Does it matter? If the number is encrypted one may quickly encrypt the numbers between 001 and 999 to find the match. How much does encrypting versus encoding matter in this scenario. I'm not sure of the standard here.
This tells the old lie: "It's not a bug, it's a feature." ...like so: "For the 2014 release, the anchor handles are disengaged from snapping to a grid or a point, so you can have fine control while editing your paths." And yet this, raises the suspicion that the new freedom is really just a defect. I hope the suspicion is the reality. I hope there is another version of Adobe Illustrator coming to us that reverts back to the old way of doing things or at least allows us to toggle the old snapping back on. I have read online some arguments to the contrary of my disgust here which suggest that it is just peachy to have the freedom to drag handles without the angst of having them snap to grid intersections or the overhead of toggling "Snap to Grid" on and off while working, but I am not swayed. Imagine making a circle with four vertices at the topmost point, the rightmost point, the bottommost point, and the leftmost point. Imagine you wish to deform the circle at the leftmost point with the "Anchor Point Tool" and then turn around and deform the circle at the other side, the rightmost point, in a perfectly symmetrical way. You can't. While I'm on a rant, I am not in love with the image of a lion with a vagina in the middle of his forehead that I see when spin up the latest Adobe Illustrator.
The concept of 3-D Secure has at least these four implementations:
organization | their version of 3-D Secure |
American Express | American Express SafeKey |
Visa | Verified By Visa |
MasterCard | MasterCard SecureCode |
JCB (Japan Credit Bureau) International | J/Secure (for Discover card???) |
As a concept, what this entails is a circumstance in which when you buy something online you are routed to your bank where you have to enter a password at your bank to affirm that you really want to allow the purchase to be. This adds one more security hurdle to prevent another party from abusing your credit card online.
This will bring the HTML in IE where: View > Source ...will show the source code within Internet Explorer.
Why do I care? Why can't I just do that on the C# side? Aren't this...
public List<Person> GetPersons()
{
using (var db = new PersonContext())
{
var people = from person in db.People orderby person.Email select person;
return people.ToList();
}
}
...and this...
public List<Person> GetPersons()
{
List<Person> results;
using (var db = new PersonContext())
{
var people = from person in db.People select person;
results = people.ToList();
}
return results.OrderBy(p => p.Email).ToList();
}
...basically equal?
This HTML, styled as it is, is going to create a consistent footer within the page.
<!DOCTYPE html>
<html style="height: 100%;">
<body style="margin: 0; padding:0; height: 100%;">
<div style="min-height: 100%; background-color: #EEEEEE;">
Do<br />
Re<br />
Mi<br />
Fa<br />
Sol<br />
La<br />
Ti
<div style="padding-bottom: 20px;">
brings us back to...
</div>
</div>
<div style="margin-top: -20px; height: 20px; background-color: #CCCCCC;">
Do
</div>
</body>
</hmtl>
It is important that:
Whew! That is a lot of rules which have to dance together for this to work. If you can get it all to work the result looks like this:
In contrast to the JavaScript stuff I cooked up here, this approach will conditionally show or not show a scrollbar at the browser itself as the situation demands and requires no JavaScript to be made to work.
These will behave just like temp tables. You may comparably carry things around in them. If you have a temp table of the same shape sprinkled across numerous stored procedures, perhaps you would have less overhead in using a custom data type. The challenge with these is that there is no way to run an ALTER command on them. If you want to change their shapes you have to drop all the stored procedures which use them, then drop them (the custom data types), and finally then recreate them.
...in the credit card space is a check to see if a credit card number entered may possibly be legitimate for a given credit card type.
Addendum 8/21/2014: A Luhn check is not card type validation. That is a bigger thing. A Luhn check just checks to see if a credit card number could be legitimate for any one of the card types.
Well... good news... you may! Pick "Options..." from the "RESHARPER" menu in Visual Studio 2013. Then select the node for "Keyboard & Menus" below "Environment" where you will click the "Apply Scheme" button while the radio button for "ReSharper 2.x IntelliJ IDEA" is selected. When you try your hotkey again, you should get the "Use ReSharper command" versus "Use Visual Studio commands" prompt again.
Per the REST spec DELETE and PUT should be implemented in a fire and forget manner. (It is POST and GET which return data.) If you're not going to get anything back upon success however, how will you know if something goes wrong? Well, you can still catch an error in a jQuery .ajax implementation like so:
$.ajax({
type: "DELETE",
url: '/api/Person?identity=' + $('#FlatIdentity').val(),
dataType: 'json',
success: function () {
isBlinkingDeleteAccountButton = false;
window.location = "/home/exit/";
},
error: function (request, status, error) {
var responseText = JSON.parse(request.responseText);
$('#DeleteAccountError').html(responseText.ExceptionMessage);
}
});
My code reaches out to an ASP.NET MVC Web API controller action. I, when applicable, throw exceptions therein like so:
throw new Exception("Sad trombone.");
$.ajax({
type: "DELETE",
url: '/api/Person?identity=' + $('#FlatIdentity').val(),
dataType: 'json',
success: function() {
isBlinkingDeleteAccountButton = false;
},
async: false
});
alert('this is after it all');
public void DeletePerson(Person person)
{
using (var db = new PersonContext())
{
db.People.Attach(person);
db.People.Remove(person);
db.SaveChanges();
}
}
http://msdn.microsoft.com/en-us/magazine/dn532203.aspx seems to show off an attribute-based approach to specifying CORS rules at an action at an ASP.NET MVC Web API controller like so:
[EnableCors("http://localhost:55912", "Accept, Origin, Content-Type", "POST",
PreflightMaxAge=600)]
public HttpResponseMessage Post(Resource data)
{
return Request.CreateResponse(HttpStatusCode.OK, data);
}
I haven't tried this stuff yet, but... I'm intrigued.
In the stylesheet I have at http://www.tomjaeschke.com/blog/code.zip one may see:
.swirl
{
width: 141px;
padding-left: 859px;
height: 30px;
padding-top: 527px;
_background-image: url("/images/swirl.gif");
background-repeat: no-repeat;
position: absolute;
z-index: 2;
}
.swirl[class]
{
background-image: url("/images/swirl.png");
}
The leading underscore at _background-image: url("/images/swirl.gif"); means that only Internet Explorer 6 will see the style. A leading asterisk would have the effect of making the style only applicable to Internet Explorer 7 and 6 and of course one may override a style with a leading asterisk with a style with a leading underscore in the name of making a differentiation between an Internet Explorer 7 specific styling and an Internet Explorer 6 specific styling. This trick was taught to me by Dustin Wells himself. Clearly that was some time ago as... well, who worries about this stuff anymore? .swirl[class] will only be seen by browsers BETTER than Internet Explorer 6! In this CSS I am trying to use a transparent .png for a background, but I am failing over to using a transparent .gif for a background (with, sigh, no antialiasing) if I really have to in Internet Explorer 6 where a transparent .png will not be transparent. Old school, eh?
In doing a postMessage/addEventListener/receiveMessage messaging means in JavaScript between an iFrame's contents and the page the iFrame itself sits in which is hosted at a different domain name, one may let the iFrame know what domain name is poking at it (a vital piece of information) by talking from the outside to the inside first as seen here or alternatively by handing that data in at the URL line when calling the iFrame content's.
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
function receiveMessage(event) {
if (event.origin == "http://bar") {
alert(event.data);
}
};
window.addEventListener("message", receiveMessage, false);
</script>
<p>This page holds an iframe at: "foo"</p>
<iframe name="eye" src="http://bar/index.html?whoisoutside=foo">
</iframe>
</body>
</html>
Make sense of what was handed in like so.
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var urlVariables = window.location.href.substring(window.location.href.indexOf('?')
+ 1, window.location.href.length);
var whoIsOutside;
var cat = {
name: "Patches",
color: "Calico",
about: function() {
return this.name + " is " + this.color;
}
};
function findWhoIsOutside(segment) {
if (urlVariables.indexOf('=') == -1)
{
return null;
} else {
var name = segment.substring(0, segment.indexOf('='));
if(name.toLowerCase() == "whoisoutside") {
return segment.substring(segment.indexOf('=') + 1, segment.length);
} else {
return null;
}
}
};
while (whoIsOutside === undefined) {
if (urlVariables.indexOf('&') == -1)
{
whoIsOutside = findWhoIsOutside(urlVariables);
} else {
var attemptToMatch = findWhoIsOutside(urlVariables.substring(0,
urlVariables.indexOf('&')));
urlVariables = urlVariables.substring(urlVariables.indexOf('&') + 1,
urlVariables.length);
if (attemptToMatch) {
whoIsOutside = attemptToMatch;
}
}
};
top.postMessage(cat.about(), "http://" + whoIsOutside);
</script>
<p>This page sits inside an iframe at: "bar"</p>
</body>
</html>
The second page here is the page inside of the iFrame and the first page is the page that actually holds the iFrame. The first page lives at http://foo/index.html and the second page lives at http://bar/index.html in this example. The second page will hand the string made by cat.about() up to the first page which will then cough it up to view in an alert.
The trick is to get your iOS device to look to your PC's hosts file and then use the hosts file to route requests. You will first need the local IP from your PC and you may get this by opening a command prompt, typing "ipconfig" and making note of the "IPv4 Address" that comes back in the results. Once you have this do the following at your iPhone or iPad:
The page holding the iFrame as specified here would need to be tweaked to be like so:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var theOtherWorld;
function findTheOtherWorld(world) {
theOtherWorld = world;
};
function reachIntoTheOtherWorld() {
theOtherWorld.postMessage("letmein", "http://bar");
};
function receiveMessage(event) {
if (event.origin == "http://bar") {
alert(event.data);
}
};
if (window.addEventListener) {
window.addEventListener("message", receiveMessage, false);
} else {
window.attachEvent("onmessage", receiveMessage);
};
</script>
<p>This page holds an iframe at: "foo"</p>
<iframe name="eye" src="http://bar/index.html"
onload="findTheOtherWorld(window.eye);">
</iframe>
<div>
<button onClick="reachIntoTheOtherWorld();">reach into the iFrame</button>
</div>
</body>
</html>
The actual content in the iFrame looks like this now:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var cat = {
name: "Patches",
color: "Calico",
about: function() {
return this.name + " is " + this.color;
}
};
function receiveMessage(event) {
if (event.data == "letmein") {
if (event.origin == "http://foo") {
top.postMessage(cat.about(), "http://foo");
}
}
};
if (window.addEventListener) {
window.addEventListener("message", receiveMessage, false);
} else {
window.attachEvent("onmessage", receiveMessage);
};
</script>
<p>This page sits inside an iframe at: "bar"</p>
</body>
</html>
This isn't as easy as I make it seem here. Let's say I have this web page hosted at http://foo/index.html:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var theOtherWorld;
function findTheOtherWorld(world) {
theOtherWorld = world;
};
function reachIntoTheOtherWorld() {
alert(theOtherWorld.cat.about());
};
</script>
<p>This page holds an iframe at: "foo"</p>
<iframe name="eye" src="http://bar/index.html"
onload="findTheOtherWorld(window.eye);">
</iframe>
<div>
<button onClick="reachIntoTheOtherWorld();">reach into the iFrame</button>
</div>
</body>
</html>
...and let's also say that at http://bar/index.html lives the page nested inside of the iFrame at http://foo/index.html which looks like this:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var cat = {
name: "Patches",
color: "Calico",
about: function() {
return this.name + " is " + this.color;
}
};
</script>
<p>This page sits inside an iframe at: "bar"</p>
</body>
</html>
Well, then when I press the button it's going to throw up an alert like so, correct?
Wrong! That's not what is going to happen. If I were not trying to reach across from the hosting at one domain name to hosting at another the code above would work great, but alas that's not our circumstance and I'm going to get an error in the console like so:
Uncaught SecurityError: Blocked a frame with origin "http://foo" from accessing a frame with origin "http://bar". Protocols, domains, and ports must match.
I found this online which gives us a solution to this problem. To accomodate the fix, I can refactor my web page with an iFrame to be like so:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var theOtherWorld;
function findTheOtherWorld(world) {
theOtherWorld = world;
};
function reachIntoTheOtherWorld() {
theOtherWorld.postMessage("letmein", "http://bar");
};
</script>
<p>This page holds an iframe at: "foo"</p>
<iframe name="eye" src="http://bar/index.html"
onload="findTheOtherWorld(window.eye);">
</iframe>
<div>
<button onClick="reachIntoTheOtherWorld();">reach into the iFrame</button>
</div>
</body>
</html>
The web page which sits inside of the iFrame ends up looking like this:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var cat = {
name: "Patches",
color: "Calico",
about: function() {
return this.name + " is " + this.color;
}
};
function receiveMessage(event) {
if (event.data == "letmein") {
if (event.origin == "http://foo") {
alert(cat.about());
}
}
};
window.addEventListener("message", receiveMessage, false);
</script>
<p>This page sits inside an iframe at: "bar"</p>
</body>
</html>
Hmmm... now we are able to get back info about Patches, our calico cat, from the page within the iFrame, but we are deferring to it to inform us instead of throwing the alert in the page actually holding the iFrame as we had before. If we are going to throw an alert with the info about Patches from the first web page we will need yet another refactoring. How may we round trip data from first outside of the iFrame, then into it, and finally back again? That looks like this:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var theOtherWorld;
function findTheOtherWorld(world) {
theOtherWorld = world;
};
function reachIntoTheOtherWorld() {
theOtherWorld.postMessage("letmein", "http://bar");
};
function receiveMessage(event) {
if (event.origin == "http://bar") {
alert(event.data);
}
};
window.addEventListener("message", receiveMessage, false);
</script>
<p>This page holds an iframe at: "foo"</p>
<iframe name="eye" src="http://bar/index.html"
onload="findTheOtherWorld(window.eye);">
</iframe>
<div>
<button onClick="reachIntoTheOtherWorld();">reach into the iFrame</button>
</div>
</body>
</html>
...and it also looks like what is below. I may have been able to use event.source below instead of top. event.source was suggested in the blog posting at the link I offer above, but top also worked for me. Whatever.
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var cat = {
name: "Patches",
color: "Calico",
about: function() {
return this.name + " is " + this.color;
}
};
function receiveMessage(event) {
if (event.data == "letmein") {
if (event.origin == "http://foo") {
top.postMessage(cat.about(), "http://foo");
}
}
};
window.addEventListener("message", receiveMessage, false);
</script>
<p>This page sits inside an iframe at: "bar"</p>
</body>
</html>
You will notice that I do not just hand back the cat variable. If I did that I would get this error in the console:
Uncaught DataCloneError: Failed to execute 'postMessage' on 'Window': An object could not be cloned.
The biggest time hole that I fought today in getting this stuff working lay in this error. It stems from the fact that there is a method on cat. If cat only had name and color and not about then it might be transfered as a JSON object to become event.data at the page holding the iFrame, but then, naturally, we would have to create our "Patches is Calico" message another way. There is no way to bring the about method across the wire. I noticed today that JSON.stringify just drops methods off of objects that it serializes to strings. I guess JavaScript methods just do not travel through the eyes of needles very well all and all.
By brain tries to juggle the difference in common computer science concepts between C# and JavaScript. Yes, there is not private versus public in JavaScript, but one may still have encapsulation nonetheless by just nesting one function inside of another allowing only the outer function to use the inner function. This touches on three ways to make "classes!" (There is NOT really such a thing as a class in JavaScript.) The first is to just make an instance of a named function like so:
function Orange (valueToMsPacman) {
this.name = "Orange";
this.points = valueToMsPacman;
}
Orange.prototype.description = function() {
return "The " + this.name + " is worth " + this.points + "!";
}
var orange = new Orange(500);
alert(orange.name);
alert(orange.points);
alert(orange.description());
The link I just gave also recommends bolting on function functionality that is never going to vary from instance to instance with the prototype inheritance trick in lieu of recreating it every time an instance of a named function is made (by nesting it in the function). This entails less overhead. I always wondered why I should care about JavaScript's lightweight inheritance and now I know why. You may see the inheritance stuff in action in the code above. Also, I offer a reminder. (I think I have blogged of this before.) A method in JavaScript is a function hanging off of a JSON object as a property like so:
var orange = {
name: "Orange",
points: 500,
description: function() {
return "The " + this.name + " is worth " + this.points + "!";
}
};
alert(orange.name);
alert(orange.points);
alert(orange.description());
The author (Stoyan Stefanov) of the blog post at the link I provide at the very top of this blog posting would also consider the JSON object I just showed off to be a "class." There is also one last way to make a "class" per Mr. Stefanov and that is like so:
var orange = new function() {
this.name = "Orange";
this.points = 500;
this.description = function() {
return "The " + this.name + " is worth " + this.points + "!";
};
};
alert(orange.name);
alert(orange.points);
alert(orange.description());
This is more or less the same thing as the prior example, however commas become semicolons, colons become equals signs, and "this" gets thrown into the mix.
...is pretty frustrating. I made line breaks in a .txt file in Notepad, pushed the file up to Github, pulled it down elsewhere, and upon looking at it in Notepad, my line breaks where gone! Or were they? My application was still able to split a string read from the file's contents on the line breaks. If I look at the copy in Wordpad I see the line breaks. This just suggests this is merely a quirk of Notepad rather than anything I did wrong. It also recommends copying to Word (from Notepad) and then back to Notepad to see the line breaks. I tried as much and it works! ...meaning that the line breaks were always there to begin with. Whatever.
Internet Explorer is another thing. As long as we keep using Windows XP, Internet Explorer 6 will be with us.
...doesn't seem that hard if you don't have to support Internet Explorer 9. It may be done like so with JavaScript alone:
<!DOCTYPE html>
<html>
<body>
<script context="text/javascript">
var myping=new XMLHttpRequest();
myping.open("GET", "http://opendoor/api/square?number=7", true);
myping.setRequestHeader("Content-type","application/x-www-form-urlencoded");
myping.setRequestHeader("Accept", "application/json; charset=utf-8");
myping.onload = function (data) {
alert(data.currentTarget.response);
console.log(data.currentTarget.response);
}
myping.send();
</script>
</body>
</html>
"What's at opendoor/api/square then?" you ask? It is an ASP.NET MVC Web API controller action which looks like this:
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace OpenDoor.Controllers
{
public class SquareController : ApiController
{
public HttpResponseMessage Get(string number)
{
string answer;
decimal interpretation = 0;
bool isDecimal = decimal.TryParse(number, out interpretation);
if (isDecimal)
{
answer = interpretation + " squared is: " + (interpretation * interpretation);
} else {
answer = "The value provided was not a number.";
}
var response = Request.CreateResponse<string>(HttpStatusCode.OK, answer);
response.Headers.Add("Access-Control-Allow-Origin","*");
return response;
}
}
}
The following links helped me figure this out and also offered some insights as to how to polyfill older versions of IE.
This suggests that you'd use the jsonp dataType (in a jQuery .ajax implementation) in lieu of the json dataType when reaching out to a web service that returns JSON at a different domain in a cross-origin attempt to drink data from afar.
It also suggests that jsonp "wraps the returned JSON data in a function call" apparently allowing for the cross-origin stuff to work instead of just blowing up as it would if merely json was used.
I really haven't thought that much about what the modules and handlers do. I experimented with them some today however. I set up system.webServer in the configuration of Web.config to hold the following:
<system.webServer>
<modules>
<add name="SessionTimeout" type="HandleThis.Magic.LifeAndDeathModule"
preCondition="managedHandler" />
</modules>
<handlers>
<add name="LifeAndDeathHandler" verb="*" path="Speak.ashx"
type="HandleThis.Magic.LifeAndDeathHandler" />
</handlers>
</system.webServer>
I believe this would work just fine in system.web too, but of course system.web is just for IIS6 hosting. Let's look at what our token module and handler do. Here is the module first:
using System;
using System.Runtime.Caching;
using System.Web;
namespace HandleThis.Magic
{
public class LifeAndDeathModule : IHttpModule
{
public void Init(HttpApplication httpApplication)
{
CacheSomething("life", "I live! ");
}
public void Dispose()
{
CacheSomething("death", "I die! ");
}
private void CacheSomething(string key, string value)
{
if (MemoryCache.Default[key] != null)
{
MemoryCache.Default.Remove(key);
}
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
cacheItemPolicy.AbsoluteExpiration = DateTime.Now +
TimeSpan.FromMinutes(30);
MemoryCache.Default.Add(new CacheItem(key, value), cacheItemPolicy);
}
}
}
The modules will run all the time whenever one spins up the application or whenever one just changes the URL within the application. Therefore, you can sort of do some AOP stuff within modules. For example, if I have a web form with a code behind like so:
using System;
using System.Runtime.Caching;
using System.Web.UI;
namespace HandleThis
{
public partial class _Default : Page
{
public string MyState;
protected void Page_Load(object sender, EventArgs e)
{
MyState = MemoryCache.Default["life"] as string +
MemoryCache.Default["death"];
}
}
}
...I may in the web form expose some of the stuff my module put in the cache by just using some markup like this:
<h1><%= MyState %></h1>
When the app first spins up the H1 tag will say "I live!" and after some time has passed and the garbage collector has done its thing one may refresh the browser and instead see "I live! I die!" There will never be a time when at the very least "I live!" is not displayed. In setting breakpoints, I witnessed the application, upon spinning up, call the Init method on the module three times before the Page_Load method on the web form's code behind (the code behind for Default.aspx, the default first web form loaded) was called. Our handler will not run automatically by itself like our module so we must call out to it. Putting a script tag like this in our web form will do the trick:
<script src="http://localhost:65413/Speak.ashx?instructions=yell" type="text/javascript">
</script>
Here is our handler:
using System.Runtime.Caching;
using System.Web;
namespace HandleThis.Magic
{
public class LifeAndDeathHandler : IHttpHandler
{
public void ProcessRequest(HttpContext httpContext)
{
string instructions = httpContext.Request.QueryString["instructions"];
string message = MemoryCache.Default["life"] as string +
MemoryCache.Default["death"];
if (instructions == "yell") message = message.ToUpper();
httpContext.Response.Write("alert('" + message + "');");
}
public bool IsReusable
{
get { return false; }
}
}
}
As you can see, it will return some JavaScript for the script tag!
It worked great! This was another something I picked up at Fry's Electronics. I bless this product as I bless the JVC Sport Headphones I got there too.