Thoughts from Dan Miser RSS 2.0
 Friday, June 23, 2006
The following code snippet shows how to pick up the SQL that will be generated by a given LINQ query. The DataContext.GetQueryText() method makes this very easy. However, what we REALLY need is an easy way to go the other way, too. For example, given an adhoc string, generate the DLINQ query to allow further processing. I've looked through the Interactive Query sample, but that's not exactly what I want. The 2 main things wrong with it are that the baseQuery is already defined as an IQueryable variable, as opposed to a simple string; and the code to build up the expression tree is much too complex for every day needs. If we had a generic string to IQueryable method, we wouldn't need all of the expression code.


        static void Main(string[] args)
        {
            string s;
            var q  = from e in db.Employees select e.FirstName;
            
            s = db.GetQueryText(q);

            Console.WriteLine(s);
            Console.ReadLine();
        }
Friday, June 23, 2006 11:08:00 AM (Central Standard Time, UTC-06:00)  #    Comments [5] -
LINQ
 Thursday, June 22, 2006
I noticed Captain Jake wrote about his experience with AOL cancellation recently. It appears that he is not alone. Listen to the mp3 and be prepared to just be amazed.

It looks like Vincent has become a minor celebrity over this incident. I think the funniest part of this is the AOL executive that decided to use the press release for AOL's apology.

Thursday, June 22, 2006 10:35:00 AM (Central Standard Time, UTC-06:00)  #    Comments [6] -

 Tuesday, June 20, 2006
OK, so it doesn't have the same ring as Eminem's song, but it is accurate. :-) I was going through some of the older sections of my hard drive looking to reorganize and cleanup unwanted files. While I was doing that, I came across a project, TerraService, that I did ages ago. To the best of my recollection, it may have been ported from a VB application that I found somewhere on MSDN, but a search on that site isn't turning up any positive hits. Sorry for any lack of proper attribution. If this was written by someone else in another language, let me know, and I'll give the proper credit.

The reason I'm making the Delphi source available is that it shows how Delphi has improved over the years. I originally wrote this application using Delphi 6. As a result, I had to manually deal with the TByteDynArray types to decode them from base64 before display. Using Delphi 2006, this is no longer necessary - the types come back decoded and in usable fashion without any extra work on your part. This sample shows several interesting concepts: stream to variant conversion, drawing tiled images, calling a webservice, dealing with GIF and JPG files, and interception of webservice traffic for debugging.

While I don't know which specific version of Delphi fixes the TByteDynArray/Base64 de/encoding, this much I know for certain: Delphi 2006 makes web services very easy to do.

Tuesday, June 20, 2006 2:06:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
Delphi
 Thursday, June 01, 2006
In the last in the series of posts on writing a .NET application to communicate over HTTP, I thought I'd talk about HtmlAgilityPack (download available here). This tool allows you to write XPATH-like expressions to parse HTML files easily.

In my application, I upload a file and some form variables to a web server, which then responds with an HTML page. On that HTML page, buried in the middle, is a confirmation ID. In order to easily grab that ID and store it for later use, I use code like the following:


        private string CheckResponse(string response)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(response);
            HtmlNodeCollection coll = doc.DocumentNode.SelectNodes("//td[@id]");
            if (coll == null) 
                return null;

            foreach (HtmlNode node in coll)
            {
                if (node.Attributes["id"].Value.Equals("confirmation"))
                {
                    return node.InnerText;
                }
            }

            return null;
        }
Thursday, June 01, 2006 8:18:00 AM (Central Standard Time, UTC-06:00)  #    Comments [2] -

 Wednesday, May 31, 2006
When using a .NET client to communicate via HTTP, you may notice an HTTP header that looks like this:
Expect: 100-continue

Depending on how stringent the web server is, it may or may not be fine to have this extra header. If you must remove this header, it's very easy to do in .NET 2.0. Just include the following line of code in your application:

ServicePointManager.Expect100Continue = false;

Wednesday, May 31, 2006 8:24:00 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -

 Tuesday, May 30, 2006
I've been writing a .NET client application that must upload a file to a IBM WebSphere (Java) server. This journey was met with mis-steps all over the place. For starters, it looked like the WebClient class was what I wanted, but it turns out you can't POST both a file and HTML form variables. That meant that I needed to go to the low-level class, HttpWebRequest, to get this done. There is code on google that got me most of the way there, but the web server always ended up rejecting the submission with errors. To make matters worse, I don't own the web server, so support on exactly what was wrong was extremely limited.

Then I stumbled across a paper, Retrieving HTTP content in .NET by Rick Strahl. In that paper, Rick ends up writing a very nice wrapper class to deal with all of the details for you. I put together a test case to try this out, and the amount of code I had to write dropped from 123 lines down to 15. The new code even works with WebSphere. What's more, the wrapper class provides a very nice model for programming applications that need to communicate via HTTP. In my opinion, this is what Microsoft should have delivered with the framework, as opposed to making people write their own wrapper or find Rick's code (which was last updated in 2002, yet still works great).

I made 2 changes to Rick's base class:

  • I changed the cMultiPartBoundary variable to look like this in order to give a unique boundary marker: string cMultiPartBoundary = "-----------------------------" + DateTime.Now.Ticks.ToString("x");
  • In the method GetUrlStream, there is a place where the end boundary marker is written to the stream. However, according to the RFC on uploading files via POST, you need to have 2 trailing dashes to mark the last end. I added those dashes like this: this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes( "--" + this.cMultiPartBoundary + "--\r\n" ) );

I am one happy camper. I've done this very thing with other web applications in Delphi before, and with the Indy components, it was very easy. Now with Rick's wrapper class, it's easy to do the same kind of thing in .NET.

Tuesday, May 30, 2006 11:32:00 AM (Central Standard Time, UTC-06:00)  #    Comments [4] -
Delphi
 Friday, May 26, 2006
Using LINQ, you can use variables for evaluation of the query. For example, the following query works just fine. It would also work if you used something like textBox1.Text instead of the variable s.


    string s = "Beverages";
    var results = from c in db.Categories
                  where c.CategoryName == s
                  select c.CategoryName;
Friday, May 26, 2006 7:18:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
LINQ
 Wednesday, May 24, 2006
I recently needed to monitor the HTTP traffic of an application that I wrote in order to debug why things were failing. Unfortunately, a simple proxy wouldn't work since the HTTPS traffic is encryped by SSL. This makes sense, since you really would hope that the data you send when surfing on a secure web page would be secure. I ended up solving this problem the same way you can solve every programming problem in the world: add a layer of indirection.

To start, I downloaded and installed the latest binaries of stunnel. Before starting, I modified the conf file to add the following entry:


[dor]
accept=localhost:8080
connect=www.MySuperSecureSite.com:443

Then, I installed tcpTrace and set things up to Listen on port 8079 and forward to localhost:8080. Lastly, in my application, I connected to http://localhost:8079/MyPath. This would eventually forward all of the traffic to the real destination, but I was able to spy on the details in tcpTrace since that was just HTTP traffic.

After doing this, I could see where things were malformed and clean my code up to submit things in the desired format.

Wednesday, May 24, 2006 1:08:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -

Navigation
Archive
<June 2006>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Dan Miser
Sign In
Statistics
Total Posts: 305
This Year: 20
This Month: 1
This Week: 0
Comments: 601
All Content © 2008, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)