by Oliver
15. October 2014 19:39
I'm currently attending the first .NET Developer Days conference in Wrocław, Poland, and will put up a few posts with my notes from some of the sessions I was able to attend. The conference took place from 14.10. to 16.10.2014 in the Wrocław Stadium. Here's a list of all posts (I'll update the links as soon as I finish a given post): Visual Studio 2013 Hidden Gems ASP.NET vNEXT SQL Server Data Tools: An Intro Continuous Deployment WebAPI, OData There's already been a lot of input and the third day is still ahead of me! I hope I'll be able to update the above list soon. Happy Coding!
by Oliver
13. June 2013 15:27
This post is most of all a log drop of an SMTP session I had with our mail server over telnet. We use hMailServer for all of our own and hosted e-mail accounts. Today, I set up a new account to use for our SQL servers to report any problems. I couldn't get SQL Server's DatabaseMail to successfully send any e-mail so I went to find out what might be wrong by myself. Here's my first successful chat with our mail server using AUTH LOGIN, i.e. username and password authentication: 1: 220 mail.teamaton.com ESMTP // started session with: telnet mail.teamaton.com 25
2: hello // my first try - not quite ;-)
3: 502 Use HELO/EHLO first.
4: HELO // ok, I got you
5: 501 HELO Invalid domain address.
6: HELO // say again?
7: 502 Use HELO/EHLO first.
8: EHLO 25.0.153.55 // send a host name of the computer you're on
9: 250-mail.teamaton.com
10: 250-SIZE 15000000
11: 250 AUTH LOGIN
12: MAIL FROM: <sql*******@teamaton.com> // the from address to use for the e-mail
13: 250 OK
14: RCPT TO: <oliver*******@******.com> // trying to set a recipient's address
15: 530 SMTP authentication is required.
16: AUTH LOGIN // initiating login
17: 334 VXNlcm5hbWU6 // the server is asking for my username in base64 encoding
18: c3FsLXNl***************vbi5jb20= // sending my username in base64 encoding
19: 334 UGFzc3dvcmQ6 // the server is asking for my password in base64 encoding
20: YkZwN***************A1dng= // sending my password in base64 encoding
21: 535 Authentication failed. Restarting authentication process. // oops, I copied some invisible character from that encoding web page
22: auth login // try again
23: 502 Unimplemented command. // case seems to matter
24: AUTH LOGIN
25: 334 VXNlcm5hbWU6
26: c3FsLXNl***************vbi5jb20=
27: 334 UGFzc3dvcmQ6
28: YkZwN***************A1dng=
29: 235 authenticated. // finally!
30: DATA // set the body of the e-mail
31: 503 Must have sender and recipient first. // hm, I thought I set the sender already…
32: MAIL FROM: <sql*******@teamaton.com> // oh well, set it again
33: 503 Issue a reset if you want to start over // I didn't want to start over!
34: RCPT TO: <oliver*******@******.com> // set only the missing recipient, then
35: 250 OK
36: DATA // now, set the mail body
37: 354 OK, send.
38: Test mail here.
39:
40: . // mark the end of the mail body
41: 250 Queued (11.247 seconds)
42: 421 Connection timeout. // that's what happened after a while when I left the shell open
43:
44: Connection to host lost.
45:
46: C:\Users\Oliver>
Every line that starts with a status code was sent by the server, the rest of them is what I entered.
Just for the record.
by Oliver
16. September 2011 20:06
Lately, I was having trouble debugging certain parts of my code in Visual Studio, and all I wanted to know was the value of some variable at some point in time. Well, I’d use some logging if I could just get at that value easily. But for some objects I don’t really know what I’m looking for or where I should be looking for it. So just give me the values of all the members of that object, will ya? And could you recurse that? But no deeper than 3 levels, alright? Or let’s say… 5? public static string ToDebugString(this object obj, int maxdepth, int depth=0)
{
if (obj == null)
return "null";
if (obj is IConvertible)
return obj.ToString();
if (depth >= maxdepth)
return "...";
var sb = new StringBuilder();
if (depth > 0)
sb.AppendLine();
foreach (var propertyInfo in obj.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance))
{
sb.Append(new string(' ', 2*depth)).Append(propertyInfo.Name).Append(": ");
try
{
var value = propertyInfo.GetValue(obj, new object[0]);
sb.AppendLine(ToDebugString(value, maxdepth, depth + 1));
}
catch (Exception ex)
{
sb.AppendLine(string.Format("[{0}]", ex.Message));
}
}
// remove newline from end of string
var newLine = Environment.NewLine;
if (sb.Length >= newLine.Length)
sb.Replace(newLine, "", sb.Length - newLine.Length, newLine.Length);
return sb.ToString();
}
With this little helper I can now simply call anyobject.ToDebugString(4 /* maxdepth */) and I get a nicely formatted debug view of that object; e.g. Request.Url.ToDebugString(3) gives me:
AbsolutePath: /logg.aspxAbsoluteUri: http://localhost:55235/logg.aspxAuthority: localhost:55235Host: localhostHostNameType: DnsIsDefaultPort: FalseIsFile: FalseIsLoopback: TrueIsUnc: FalseLocalPath: /logg.aspxPathAndQuery: /logg.aspxPort: 55235Query: Fragment: Scheme: httpOriginalString: http://localhost:55235/logg.aspxDnsSafeHost: localhostIsAbsoluteUri: TrueSegments: Length: 2 LongLength: 2 Rank: 1 SyncRoot: Length: 2 LongLength: 2 Rank: 1 SyncRoot: ... IsReadOnly: False IsFixedSize: True IsSynchronized: False IsReadOnly: False IsFixedSize: True IsSynchronized: FalseUserEscaped: FalseUserInfo:
Nice
Right now this method chokes on indexed properties but once I’ll need it I’ll go and look for a way to include them. It also chokes any exceptions on the way to just get the job done.
Happy coding!
by Oliver
15. September 2011 17:05
Today, I tried importing a CSV file like the following into one of our MS SQL Server databases: Id;Latitude;Longitude 4610;43.7119;-1.0737 5502;49.4297;-1.806 11360;46.9343;-1.8875 I tried it using the following command line: 1: bcp GeoDataImport in geodata.csv -w -t; -T
but that threw the mentioned error:
“Unexpected EOF encountered in BCP data-file”
cmd> bcp GeoDataImport in geodata.csv -w -t; -TStarting copy...
SQLState = S1000, NativeError = 0
Error = [Microsoft][SQL Server Native Client 10.0]Unexpected EOF encountered in BCP data-file
0 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total : 1
I’ve had this problem before and somehow managed to remember that it might have something to do with the encoding of the file. So I opened it with Notepad++ where you can easily check and change the file encoding and found it was ANSI encoded:
Well, the UCS-2 Little Endian encoding is what SQL Server expects as default encoding, so I changed the encoding, saved the file and imported it again – with success. UCS-2 might be something you rarely hear about – that’s because it’s been superseded by UTF-16 but in most situations they are pretty much identical (check out http://en.wikipedia.org/wiki/UTF-16/UCS-2 for more info).
That’s all for now – happy coding!
by Oliver
15. July 2011 09:07
For our portal software discoverize I was looking for a way to create new modules faster and more reliably. The basic structure would always be the same, so a Visual Studio multi-file template seemed appropriate: Well, unfortunately I didn’t find a way to create new folders with that approach. Multi-file templates really do what they say: they create multiple files from templates. Nothing else. So I put together a short batch script that would create the directory structure needed for any new module: I can quickly open a new command line window by using any one of several Visual Studio extensions (e.g. PowerCommands for Visual Studio 2010): … and simply run: Now going back to Visual Studio we have to include the new Feature folder in the project: Then hit Ctrl + Shift + A to open the Add New Item dialog, select ‘Discoverize Module’ and type Feature in the Name textbox (unfortunately, there seems to be no easy way to automatically put the name of the folder inside that textbox): This step will generate three code files, that are the backbone of every module: FeatureConfig.cs, FeatureModule.cs, and FeatureViews.cs. Finally, our multi-file item template comes into play! Handling the multi-file template The multi-file item template for a new module consists of four files: the template definition file Module.vstemplate and the template code files Config.cs, Module.cs, and Views.cs: Those four files have to be packed into a zip file and copied to a folder underneath %UserProfile%\My Documents\Visual Studio 2010\Templates\ItemTemplates\ – I put this one into Visual C#\Code. That’s how it appeared under the Visual C# –> Code section in the Add New Item dialog. Since it is somewhat cumbersome to zip and copy updated versions of the template (especially during early development where I keep adjusting and tuning the template code), I put together another batch file that does that for me. It basically does three things: Get the name of current folder to use as name for the zip file (found the solution here) Use 7-zip to zip the four files. Copy the zip file to the VS custom template directory. The real script contains some safety nets and more output so that in case it won’t work across all developer machines I can get quick feedback as to what exactly didn’t work instead of just “it didn’t work”. Happy Coding!
by Oliver
28. June 2011 01:27
Three year old code: 1: protected string CpeBehaviorIds()
2: {
3: var cpeIds = "";
4:
5: var helpItems = GetHelpItems(divGlobal);
6:
7: foreach (var helpItem in helpItems)
8: cpeIds += helpItem.CollapsiblePanelBehaviorID + ',';
9:
10: // remove comma at end
11: if (cpeIds.Length > 0)
12: cpeIds = cpeIds.Remove(cpeIds.Length - 1);
13:
14: return cpeIds;
15: }
16:
17: protected string CpeExpandIds()
18: {
19: var cpeIds = "";
20:
21: var helpItems = GetHelpItems(divGlobal);
22:
23: foreach (var helpItem in helpItems)
24: cpeIds += helpItem.CollapsiblePanelExpandID + ',';
25:
26: // remove comma at end
27: if (cpeIds.Length > 0)
28: cpeIds = cpeIds.Remove(cpeIds.Length - 1);
29:
30: return cpeIds;
31: }
32:
33: protected static List<HelpItem> GetHelpItems(Control control)
34: {
35: var idList = new List<HelpItem>();
36:
37: if (control is HelpItem)
38: idList.Add(control as HelpItem);
39: else
40: foreach (Control child in control.Controls)
41: idList.AddRange(GetHelpItems(child));
42:
43: return idList;
44: }
New code:
1: protected string CpeBehaviorIds()
2: {
3: return divGlobal.Controls<HelpItem>().Select(h => h.CollapsiblePanelBehaviorID).JoinNonEmpty(",");
4: }
5:
6: protected string CpeExpandIds()
7: {
8: return divGlobal.Controls<HelpItem>().Select(h => h.CollapsiblePanelExpandID).JoinNonEmpty(",");
9: }
10:
11: public static string JoinNonEmpty(this IEnumerable<string> values, string separator)
12: {
13: return String.Join(separator, values.Where(s => !string.IsNullOrEmpty(s)).ToArray());
14: }
LINQ – we love you!
Oliver
P.S. Controls<Type>() is another extension method defined like this:
1: /// <summary>
2: /// Returns all controls of the given Type that are found inside this control.
3: /// Searches recursively.
4: /// </summary>
5: public static IEnumerable<T> Controls<T>(this Control control) where T : Control
6: {
7: var controls = control.Controls;
8:
9: if (controls.Count == 0) return new List<T>(0);
10:
11: var newColl = new HashedSet<T>();
12: foreach (Control child in controls)
13: {
14: if (child is T)
15: newColl.Add((T) child);
16:
17: var childColl = child.Controls<T>();
18: foreach (T ctrl in childColl)
19: newColl.Add(ctrl);
20: }
21:
22: return newColl;
23: }
by andrej
10. March 2011 14:54
Web Developers vs Web Developers from Cassie McDaniel on Vimeo. I love the role the designer plays in this video :) [via graphic.is]