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
28. January 2013 14:26
Today, I faced the exception mentioned in the post title: SQL Server Compact timed out waiting for a lock. The default lock time is 2000ms for devices and 5000ms for desktops. The default lock timeout can be increased in the connection string using the ssce: default lock timeout property. (Plus some session details). Circumstances The exception was thrown in my local dev environment while working on our Orchard CMS based portal software discoverize, calling any page in the portal. Obviously, something was wrong not with a single page but rather with a piece of infrastructure. Interestingly enough, only a few moments before trying to open the web site I had done some database manipulation using SqlCeCmd deleting some unneeded columns from one of our tables. It seems that after that the site broke. Solutions tried I tried to get hold of the DB like this: stop and start the web site in IIS (using appcmd stop site "discoverize" and appcmd stop site "discoverize") – no change take DB offline by renaming the file – waited a few moments, renamed it back – no change! Here I started wondering where the lock is saved – is it inside the DB? took the whole application pool offline and restarted it – bang! That helped. I now have my site back up and running and can continue develepment. Conclusion If you encounter the SQL CE timeout error during development inside a web application, restarting the app's app pool will probably get you back to work. Happy coding!
by Oliver
28. January 2013 14:26
Today, I faced the exception mentioned in the post title: SQL Server Compact timed out waiting for a lock. The default lock time is 2000ms for devices and 5000ms for desktops. The default lock timeout can be increased in the connection string using the ssce: default lock timeout property. (Plus some session details). Circumstances The exception was thrown in my local dev environment while working on our Orchard CMS based portal software discoverize, calling any page in the portal. Obviously, something was wrong not with a single page but rather with a piece of infrastructure. Interestingly enough, only a few moments before trying to open the web site I had done some database manipulation using SqlCeCmd deleting some unneeded columns from one of our tables. It seems that after that the site broke. Solutions tried I tried to get hold of the DB like this: stop and start the web site in IIS (using appcmd stop site "discoverize" and appcmd stop site "discoverize") – no change take DB offline by renaming the file – waited a few moments, renamed it back – no change! Here I started wondering where the lock is saved – is it inside the DB? took the whole application pool offline and restarted it – bang! That helped. I now have my site back up and running and can continue develepment. Conclusion If you encounter the SQL CE timeout error during development inside a web application, restarting the app's app pool will probably get you back to work. Happy coding!
by Oliver
2. August 2012 15:19
On Camping.Info, we lately had a user report that hitting the enter key while in the login form one would be redirected to the search page instead of being logged in. This happened when the focus was still on the password text box because the “Search” button on the page was the first input element on the page (inside the single <form> element that WebForms allows for) of type submit which would by default handle the enter key press event. To improve the user experience, we set out to find a way to postback the correct UpdatePanel – the one which currently has the focus (or one of its child controls). Using an ASP.NET Panel and the DefaultButton property There is a built-in solution to this problem if you’re willing to slightly change your markup and add a hidden <asp:Button> element to your part of the page you want to asynchronously update. You need to wrap your existing html into an <asp:Panel> element and set its DefaultButton property to the ID of that hidden button. This would look something like this: 1: <div class="form21">
2: <asp:Panel runat="server" DefaultButton="btnHiddenRegister">
3: <asp:TextBox ID="txtEmail" runat="server" />
4: <asp:TextBox ID="txtPassword" runat="server" TextMode="Password" />
5: <asp:LinkButton ID="btnRegister" runat="server">Register</asp:LinkButton>
6: <asp:Button ID="btnHiddenRegister" runat="server"style="display:none" />
7: </asp:Panel>
8: </div>
Of course, you need to hook up the code-behind Click handler for the btnRegister LinkButton to the hidden Button element as well to make this work.
The proposed solution will instead have html like the following:
1: <div class="form21 jq-form">
2: <asp:TextBox ID="txtEmail" runat="server" />
3: <asp:TextBox ID="txtPassword" runat="server" TextMode="Password" />
4: <asp:LinkButton ID="btnRegister" runat="server" CssClass="jq-form-submit">Register</asp:LinkButton>
5: </div>
Let’s see how we get this to work.
Using jQuery
On stackoverflow.com, I quickly found this post about a jQuery replacement for DefaultButton or Link where the this answer points to the original solution from March 2009 proposed by this post on fixing the enter key in ASP.NET with jQuery. I’ve improved on the proposed answer in a few ways, so this is what this post is about.
The original solution
1: $(document).ready(function(){
2: var $btn = $('.form_submit');
3: var $form = $btn.parents('.form');
4:
5: $form.keypress(function(e){
6: if (e.which == 13 && e.target.type != 'textarea') {
7: if ($btn[0].type == 'submit')
8: $btn[0].click();
9: else
10: eval($btn[0].href);
11: return false;
12: }
13: });
14: });
Remarks: works only if the content is present at the time the script executes, and works only for a single pair of form and form-submit elements.
Our improved solution
1: $('body')
2: .off('keypress.enter')
3: .on('keypress.enter', function (e) {
4: if (e.which == 13 && e.target.type != 'textarea') {
5: var $btn = $(e.target).closest('.jq-form').find('.jq-form-submit');
6: if ($btn.length > 0) {
7: if ($btn[0].type == 'submit') {
8: $btn[0].click();
9: }
10: else {
11: eval($btn[0].href);
12: }
13: return false;
14: }
15: }
16: });
Improvements
The first thing to improve is the registration of the keypress event handler. Since Camping.Info is quite a dynamic site with lots of asynchronous postbacks to the server (mostly using WebForms’ UpdatePanels) a lot of the javascript code we need on our page won’t execute properly as is because it expects the elements it works with to be present at the time of the script’s execution. That’s also the case with the original solution: both the submit button element with class .form_submit and the pseudo-form element .form (I’ve called it pseudo-form element since it’s just a parent element of any type marked with the class .form) must be present when the script executes, otherwise nothing will happen. That’s why – using jQuery 1.7 syntax – we register the keypress event handler NOT on the pseudo-form element but directly on the body using on(). We also the event namespace it by appending .enter to its name keypress so that we can safely remove it (using off()) in case we call the script a second time during postback to prevent it from being attached twice. Please note, that at this point neither the pseudo-form nor the form submit element must be present on the page for this to work.
Once the enter key has been pressed anywhere on the page and we’re inside the event handler, we set out to check for a pseudo-form surrounding the element that received the enter key press event and inside it we look for a submit element. [I’ve also changed the class names for those elements by our internal convention to prefix all those that are jQuery related by jq- to set them apart from the CSS class names our designer works with.] Only if we’ve found both those elements, we proceed with either clicking the element if it’s really a button or executing the javascript code that ASP.NET rendered into our LinkButton’s href tag which asynchronously posts back to the server for some update to our page.
A subtle but important detail here is to return false (and thus prevent the event from being processed any further) only in case we actually found the pseudo-form and submit elements, so that in the opposite case the default behavior of the page will be preserved.
Conclusion
The solution presented here works equally well with static and dynamically loaded page content and for any number of forms on your page. It replaces the solution provided by ASP.NET WebForms’ using a Panel and its DefaultButton property, resulting also in cleaner markup.
Happy Coding!
by Oliver
31. July 2012 17:27
Developing our web application www.marinas.info using Orchard CMS, I often find myself at the command prompt to run different sets of build actions: in place compilation packaging for stage deploying to a local app instance running spec tests … Sometimes I have trouble remembering the correct target name, so today I set out to attack this simple problem (displaying the names of all target defined in our build script) using Powershell. I’ve long waited for a good occasion to get my hands on it – today was finally the day. Following this inspiring walk-through by the Windows Scripting guy to parse an XML file, I made my first firm steps in Powershell, and after some guesswork I came up with this one-liner that omits the definition of a variable: [xml](Get-Content C:\Projects\discoverize\Discoverize.proj) | Foreach-Object {$_.project.target} | % {$_.Name} | sort
It might help to know that % is an alias for the Foreach-Object cmdlet, and $_ references the item currently piped in.
I saved this into a file that from now on I can simply call to get an up-to-date list of build target names.
by Oliver
27. June 2012 14:40
This is only the beginning… Batch String replacement: http://ss64.com/nt/syntax-replace.html Date formatting T-SQL, using CONVERT or CAST: http://msdn.microsoft.com/en-us/library/ms187928.aspx .NET: Custom Date and Time Format Strings, Standard Date and Time Format Strings Windows Open recent window from taskbar when clicking on icon instead of showing list of open windows: http://www.howtogeek.com/howto/16334/make-the-taskbar-buttons-switch-to-the-last-active-window-in-windows-7/ Logging Filters for log4net: http://www.claassen.net/geek/blog/2009/06/log4net-filtering-by-logger.html
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
24. June 2011 21:47
Imagine we have the following list of ids of some kind of objects and a mapping of some of the ids to some values (also int’s here): 1: var ids = new List<int> { 6, 2, 5, 3, 7 };
2: var valueMap = new List<int[]> { new[] { 5, 15 }, new[] { 2, 12 }, new[] { 3, 13 } };
Now, if we want to return the results a.k.a. the valueMap in the same order we have the ids, we can use the LINQ extension method .Join()like this:
1: var joined = ids.Join(valueMap, id => id, arr => arr[0], (id, arr) => string.Format("id: {0} - value: {1}", id, arr[1]));
Really convenient! Let’s look at the output:
1: Console.WriteLine(string.Join("\r\n", joined));
2:
3: // Prints:
4: // id: 2 - value: 12
5: // id: 5 - value: 15
6: // id: 3 - value: 13
By the way, I use FastSharp to write and test this kind of small code snippets
Happy Coding,
Oliver