I get an email form Comcast today detailing various movies, PPV, highlights and a new (I think, as I’ve never seen it) service for safe and secure back-ups for free (up to 2 GB). Nice, I thought. That’s a value-add service that is cheap for them and a solution most consumers can appreciate especially with all the back-up chatter your hear now-a-days.
I headed over to Comcast’s Secure Backup and Share to see what it was all about – for fun, since I don’t need this service (I have my own solution with WHS, Mesh, SkyDrive and three PCs in the house. [SIDEBAR: Comcast is using ASP.NET MVC – cool.] So, I get there and see that 2GBs is free, 50 GB is $5 a month or $50 a year and 200 GB is $10a month or $100 a year. So, the 2GB is free, but who can get away with 2GB these days? No one! It’s obviously just bait into the more expensive levels: 50 and 200 GB is definitely inline with what most people would need. While I wasn't impressed with the pricing – there are plenty of players in the online backup world for less (Mesh is 5GB for free. SkyDrive 25 GB (FolderSync) for free). What caught my eye was the Powered by Mozy blurb in the bottom right of the page. It’s not a link, not even a tooltip. Mozy? Really? I thought Mozy was cheaper than this. Mozy, Carbonite, iDrive, et al. (at least it’s better than Norton’s…) they’re all cheaper – I thought.
I headed over to Mozy to confirm. In fact, I’ve been waiting for the online backup companies to support backing up WHS with home/resident pricing (business pricing is usually many times more expensive). I was right. Mozy’s price: Unlimited backup space for $55 a year. Oh yeah, 2GB are free. I can’t believe Comcast would resell a service at such a huge increase in price; blatantly saying this is someone else’s product that I want to make a huge profit from. Talk about screwing your customers with no shame. I’m all for businesses make a buck. Add value to a service; make it easier on the customer to get something; resell at a profit. But, even limiting what Mozy gives away for free!
Wow. Thanks Comcast!


Layers, what a craze it has become. I’ve been designing web sites and programming web applications (what’s the difference anymore? Future post on that) for just over 10 years. When I started, it was asp (with Snitz 2000 forums). That was some major spaghetti code. And if you started “modding” the forums, the includes, markup edits – that was fun. There is a great community over there and I learned a lot.
Soon after asp.net 1.0 and 1.1 came out. I began messing with it, but really got involved with asp.net 2.0; What a huge improvement 2.0 over 1.x was! Now that I got into OO, I broke all my code into business layers, data access layers, presentation layer (UI), code-behind…I had nearly no code in my aspx (html) page. Clean, Clean, Clean.
Fast forward to the days of JavaScript (jQuery is my library of choice), web services, AJAX, MVC, LINQ-to-SQL and those clearly defined layers begin blurring. That’s what led me here.
I was just thinking this week: I have code throughout my JavaScript files; I create UI in JavaScript; if my project is using L2S, it’s much harder (and, dare I say, needless) to have a BAL and DAL – or they’re a bit intertwined; code in web services…and I’m OK with it. Truth is, it needs to work and work well. It must be efficient (as the app user perceives it), it must not be a nightmare to maintain and it has to make sense (unlike the Snitz code after 20 mods have been installed).
So, what are layers? There’re an abstraction to make our jobs, as developers, easier and when they top doing that but in effect cause more work – then maybe it’s time to use less layers.
{Tags:Linq|Architecture}
I came across this article today by Jakob Nielsen from his useit.com site, about masking or hiding the passwords. I found it funny because he’s on the money – but I thought it about first :) - so true are his words, in fact, that in the application that I am about to release – DLVerification.com (Driver’s License Verification Service), I do not hide the password.
Of course, I am not oblivious to the principals of security. As such, I have an option that a user can choose to use when they want the password hidden. The default will display the password. And if a user so chooses that I can hide the password and even it make it their personal default – I’m not completely totalitarian!
If you think this isn’t the case – then you ain’t paying attention to how users interact with applications! Take a look.
I love extension methods. I really do. I know there are some that completely abhor them. “Why not just use static methods!” they say. And, to give them some credit, it’s more “readable” that a static method is doing something not necessarily that is not a “native” method. Although, in some cases, static methods are part of a class and implemented as such (static) for other reasons. Anyway, I'm not here to discuss the validity or usefulness of Extension Methods. Just where to put them.
You’ve decided that you’re on this side of the argument, where do you put them. There are proponents of the various methods (of course!). I didn;t have formal training in college – so I miss the subtle but forcibly argued “THAT’S NOT THE WAY IT’S DONE!” arguments one hears because of doctrine says so. I do what makes sense, what has proven over the last 8 years to work on large and small projects. These are the two options I struggle with:
Dedicated Extension Namespace
I’m actually doing this now, to separate my own, custom methods from BCL methods. I have something like:
namespace Webchanix.Fleetmanager.Extensions
or
namespace Webchanix.Extensions
Depending on the namespace, they contain classes that work with specific objects. For example, the Fleetmanager namespace only contains objects that exist in that namespace – no parents, only children. Whereas the Webchanix namespace contains everything that belongs to Webchanix and to System or below (string, int, ICollection, et al.) but not in a child class that has its own assembly.
Origin Class
If your working with a custom object say:
namespace Webchanix.Fleetmanager.Messaging
{
public class CannedMessages
If I have an extension method that goes like: myMessage.AddTechSupportEmail() I could include that in the Extension namespace, but I could also include it in the Messaging namespace – after all, this is where it’s from. This also maintains a certain amount cohesiveness between the extension methods and the classes it pertains to. If I ever do away with a class, I can easily do away with the extension methods and not wait for a compile error to tell me it doesn’t know what a CannedMessage is. Although I use the Extension namespace – I like them all together – this is a viable option that works well. The best argument for this is that you put object specific static methods in the class it belongs to, why not the extension method? Onviously, this doesn’t apply to string, MailMessage, int,, etc. whose namespace you don’t own.
System Namespace
To use my extension methods in any code I have to import the proper namespace. This is a little annoying. Let’s say I have a string that contains spaces that I want to remove. I created an extension method that works like this: myString.RemoveSpaces(). Easy. I love that :) Now, since this is in my Webchanix.Extensions class I have to import it. If I would have created the extension class in the system namespace (namespace System { public static class Extensions…), it would always be available. No need to import the namespace – saving some work and additional usings.
These are three options that I’ve considered. I like a option 1 and 2. I currently use option 1, but I am considering option 2 in some cases.
I’ve been using LINQ-To-SQL full-time for about a month now. I was slow to begin “playing” with LINQ (as far as SQL is concerned) and it’s a shame – because it is a breeze to use. If you haven’t been using LINQ, you need to – as long as you understand the caveats that come along with it. That’s the advantage of waiting a little longer – there is a lot more info available and hopefully, solutions.
I’ve been using Enterprise Library for the last few years (3.1) and I’ve been very happy – but I still had to write my queries by hand, which could be tedious and error prone – but once they were right, there was little else to worry about. And, if I did my job correctly, they were efficient. That’s where this post is heading:
Updating and Deleting in LINQ:
To perform an update or deletion in LINQ you must first query for your object (record) then you update/delete it. This take two queries: Select –> Update/Delete. This makes no sense. Why the LINQ folks did this as the only option is beyond me. Also, update/delete query is huge because the entire record is sent – even if it’s a varchar(500) column. In theory, this is for conflict resolution. In reality…well, perhaps you have a use for it, I don’t. Anyways, I thought that the timestamp function was for conflict resolution, so I’m not 100% convinced there was a need to send every single column in the where clause. So, for the record, the cons against updates and deletes in LINQ:
- Must SELECT first
- UPDATE/DELETE sends a lot of bytes over the wire.
Solution
My solution is to perform, </ sigh>, custom SQL. This saves me a DB hit and less is sent on the wire:
public void MakeAutomatic()
{
SqlDataContext db = new SqlDataContext(Global.ConnectionString);
var account = db.Accounts.Where(d => d.Id == Id).SingleOrDefault();
account.PaymentProcess = (byte)PaymentProcessType.Automatic;
db.SubmitChanges();
}
becomes:
public void MakeAutomatic()
{
PaymentProcess = (byte)PaymentProcessType.Automatic;
string sql = "UPDATE Accounts SET PaymentProcess = {0} WHERE Id = {1}";
object[] parameters = new object[] { PaymentProcess, Id };
using (SqlDataContext db = new SqlDataContext(Global.ConnectionString))
{
db.ExecuteCommand(sql, parameters);
}
}
A few more line of code and more SQL to maintain in code – things I hope to eliminate with LINQ-To-SQL, but for the sake of improved performance, both perceived and on the servers, there was little choice.
Did I miss something Let me know!
{Tags:SQL|LINQ|C#}
I have an application that performs some screen scraping. A necessary evil. You would think that the provider would offer a web service, but no, I have to screen scrape for three pieces of information on a page. This page I scrape, is not ad driven, it’s actually a government service to the public and you would think that this info…I digress.
This has been working for a while now. However, as any screen scraper knows, things can quickly change. They (the provider) decided to change their URL and then the format. No problem, worked it out. Now I have my info. Until last night…
This is of course the problem with screen scraping – you’re at the mercy of the provider’s developers. However, this change took me 3 hours to figure out. And i still don’t understand why they did this, but here’s what happens:
I “GET” http://domain.com/page.jsp I do this with this code:
CreateRequest();
using (WebResponse response = Request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
ResponseString = reader.ReadToEnd();
}
CreateRequest creates a new instance of the HttpWebRequest object and assigns it to the “Request” property. This usually works. But it stopped working. After some Firebuging I noticed that the site now assign a sessionid cookie and redirects to a new page http//domain.com/results.jsp . They create the results on one page and then display them on a secondary page based on the sessionid. WTF? After some back-and-forth, I found the solution: track the cookie (DUH!). Updated code:
CreateRequest();
if (CookiesRequired)
{
Cookies = new CookieContainer();
Request.CookieContainer = Cookies;
}
using (WebResponse response = Request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
ResponseString = reader.ReadToEnd();
}
I added a boolean property “CookiesRequired” which will create a CookieContainer and add it to the current request. This ensures that any cookies created and tracked by the site will be created and maintained for the life of the request. Since this is in a class library this makes it usable by all my apps, without having to needlessly create a cookie.
Total code to easily screenscrape a web page (GET). You’ll notice that there is a check for the URL scheme. This is because some HTTPS sites will throw errors (such as cert errors), that piece of code makes that all a non-issue.
namespace Webchanix.Import
{
public class WebImport
{
public string Url { get; set; }
public HttpWebRequest Request { get; set; }
public CookieContainer Cookies { get; set; }
public string ResponseString { get; set; }
public bool CookiesRequired { get; set; }
public Uri ImportUri { get; set; }
public string UserAgent { get; set; }
public string Referrer { get; set; }
public WebImport()
{
}
private void CreateRequest()
{
Uri uri;
bool tryCreateUri = Uri.TryCreate(Url, UriKind.Absolute, out uri);
Request = WebRequest.Create(Url) as HttpWebRequest;
if (null == Request || !tryCreateUri)
{
throw new ApplicationException("Request is NULL OR URL is bad");
}
ImportUri = uri;
Request.UserAgent = UserAgent;
Request.Referer = Referrer;
}
public virtual void Import()
{
CreateRequest();
if (ImportUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback =
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
};
}
if (CookiesRequired)
{
Cookies = new CookieContainer();
Request.CookieContainer = Cookies;
}
using (WebResponse response = Request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
ResponseString = reader.ReadToEnd();
}
}
}
}
When you go to the Doctor or the Lawyer do you tell them how to their job? Does the conversation go something like this:
| You: Doc, i have a pain deep in my head. That hurts when I get stressed. Dr: That’s an aneurism. We have to operate it if not there could be fatal consequences. You: No, that’s not right. It’s actually a migraine. You need to prescribe me Motrin, 800 mg, with 10 refills. Dr: Well…OK. Here you go. Please see me again if you need anything else. |
That probably would never happen. After all, who argues with the doctor. But this is all too common:
| You: I need an application that will handle my HR resources, including vacation, OT and sick days. Dev: You need a design with a 3-tier architecture that will use SQL Server as a back-end. Also, we will develop workflows for each different process (reporting attendance, approvals, managing employees). we’ll create web based front-ends for some portions, desktop front-ends for others and a few mobile versions for field employees that are not near a computer…. You: No, that’s not right. I need an Access front-end with an Excel back-end - all our data is in in Excel, I want to keep it that way. It will also scale to 200 concurrent users. Dev: Well, that may not work right… You: <stare>That’s what I need Dev: Ok. |
Both of these situations, the person represented by You above, thought they knew more about what they needed than the professional. In both cases, they were wrong. They know nothing about medicine and they know nothing about IT, much less about developing an application. The major difference? The doctor sends you to hell and the developer says OK. Of course, then the professional is blamed when it fails, even if the client/patient was warned. The doctor gets sued and the developer fired.
The problem is that developers are not treated as the professional that they are. They are not known as the last word in their field. The customer dictates how things are done, even if they nothing about it. they think because they saw an application work somewhere that they know the best way to develop an entire app. While this may not apply to CIOs, who might have some idea of what they’re talking about. Some CIOs are just great managers and executives with little actual programming/architecture experience and know how. Most of the time, the adage: Leave it to the professionals has a lot of merit.
At some point, developers will have to decide to be treated as the professionals they are. Not say “Yes” just to get the job; they need to command the respect that they deserve – they are after all the professional. But they have to act like professionals. They need to take a lesson from the doctor and say: “Sorry, I can’t do that.” and the client is in all their right to get a second opinion. Let’s hope they pick a professional.
By the way, don’t get me wrong. There’s nothing wrong with a healthy discussion about options. The same discussions that occur with a doctor – chemo or gamma knife. Pros and Cons of SQL Server and SQL Server Express. Web based vs. thin client. True n-tier design, do we build a rules engine or just hard code for quicker deployment. These are discussion points that are valid (unless you’re a zealot for a specific form: “MVC or you will DIE!”; "”WE MUST HAVE 150% code coverage!”
{Tags:Professional|Development|Developers}
Though not a programming or development post, by any means, this was too precious not to share – and create a reminder for myself.
I have a Compaq DeskPro EN which I will be using as a music server in my house. It will be running iTunes which feeds the house via different methods. This headless box, a P3 800 MHz, 384 MB ram, will run with no mouse or keyboard. It’s running XP and will auto login using registry settings. However, on boot up I get a post error because of no keyboard. No problem, BIOS setting…nope, nothing there. Now what?
Ahhh, you got to love the internet! I found this gem, which worked perfectly: http://m0n0.ch/wall/list/showmsg.php?id=137/36 and in case it’s purged from the internet, in all its glory, the original text (sans email information, as a courtesy):
-----Oorspronkelijk bericht-----
Van: Barry Mather [removed email]
Verzonden: vrijdag 18 februari 2005 2:40
Aan: m0n0wall at lists dot m0n0 dot ch
Onderwerp: [m0n0wall] compaq sff no keyboard boot (No F1)
Have been running m0n0 on a Compaq sff for ages, just installing another
one now, and couldn't for the life of me remember howto run them without
a keyboard ... after much googling, here it is for those who care ..
The SFF's are great for m0n0walls, p2 350, 128mb ...
- Run BIOS setup by pressing F10
- Goto 'Security' and 'Set Power On Password'
- Type in a password and F10 to accept the change
- As soon as password is set, 'Password Options' will appear under
'Security' tab
- Enable 'Network Server' mode in there
- F10 to save changes and exit
When booting up it won't ask you for F1 anymore. However, if you or
someone else plugs in a keyboard it will ask for a power-on password.
Cheers
| |
Thanks Barry, this was a life saver!
{Tags|Compaq, Boot, No Keyboard}
One of the best articles I have ever read on ViewState. Definitely a good read. I’m no longer sure where I got this from (someone’s blog I’m sure), but I am glad I did. There’s always been a few nuances in the way ViewState did some of its tasks that where enigmatic and this cleared it up. There was an update on February 19th, 20
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
An Update post with a comment index: http://weblogs.asp.net/infinitiesloop/archive/2008/02/19/truly-understanding-viewstate-comment-index.aspx
After so many studies, surveys, blogs, reports etc. discussing user reaction to sign up forms (that is, the inclination to follow-through or or run) why do web sites – especially “web savvy” sites - continue the practice of this:
I was reading Mary Joe Foley’s blog (a favorite and a bit lighter fare), a post on code names provided a download of code names that MS was using. Neat, after all, who can keep track of all the code names that MS tosses around like a hot potato. I tried to download and I was redirected to the “you must register” page and the aforementioned screenshot. 18 Fields! Who the heck has a 2-part registration page where the part one is 18 fields long!! It would be longer if I counted all the stuff you can sign-up for. I can’t share what part two looks like since I quickly left.
If it was just name, email and password I would have signed up – sorry, ZDNet, you ain’t getting my address. ZDNet, I recommend the following resource: http://www.lukew.com/ and specifically these posts: you’ll learn a thing or two about keeping folks once they decide to sign up (maybe).
{Tags:Form|Design|UI}