Job-Board Journalism, A critique of online job boards
Here’s a good update on the game played by the online job boards. No real news but confirmation that the system is broken and whose system it is.
Here’s a good update on the game played by the online job boards. No real news but confirmation that the system is broken and whose system it is.
The only way the HttpWebRequest will generate a POST method request is using the HTTP 1.1 Expect header set to at least 100-continue. This has the effect of not including the posted data with the initial request, but rather waiting for the server to request the content. This is intended to allow the server to return an error before you ship it a ton of stuff it doesn’t want but is clearly slower for the 99% of traffic that knows what to post where.
Some servers (like www.jobsearch.org) don’t understand the Expect header and respond with a protocol error.
Form.Controls.Add of the DataGrid control (or of a control containing it) causes:
a. ListManager initialized.
b. Bound set to true.
c. BindingContext initialized to Form’s BindingContext.
d. IsHandleCreated still false.
e. DataBindings.Count still zero, this is independent of the BindingContext.
f. BindingContext collection has entries which are System.WeakReference’s to CurrencyManager or RelatedCurrencyManager objects. RCM’s extend CM’s. RCM’s have a parent reference to a CM.
a. “” is CurrencyManager for entire data set.
b. “job” is RelatedCurrencyManager.
g. grid.ListManager.GetHashCode() == grid.BindingContext[grid.DataSource, grid.DataMember].GetHashCode()
but
grid.ListManager != grid.BindingContext[grid.DataSource, grid.DataMember]
h. Form’s BindingContext == DataGrid.BindingContext
So far:
1. The AllowNew DataView property must be set true prior to a Clear-Fill load dataset operation. Failing to do so will cause the Grid to stop accepting new values for existing cells.
Problem: After re-loading a DataGrid via a context menu pick, edited cells revert to their pre-edit state as soon as new cell is selected.
Diagnosing:
1. Loading multiple times before first display of Form doesn’t fail.
2. Removing relation from schema doesn’t change behavior.
3. Removing LinkLabel columns & sorting and AllowNew = false eliminates problem.
4. It’s the AllowNew = false.
5. Switching to Merge instead of direct Fill data set load pattern eliminates problem.
6. Inserting a AllowNew = true & AllowNew = false around the clear/fill also eliminates the problem.
When using a remote data source that delivers a dataset, it may be necessary to maintain a second DataSet into which new DataSets are merged in the LoadData function. This enables – among other things – data bindings that don’t need to be rebound.
The downside is that merging is a very slow (human scale) operation for DataSets with hundreds of rows.
If DataAdapters are used to fill a persistent local DataSet, there’s no need to use the merge pattern.
Still chasing the bug that prevents editing grid cells after a load.
Added calls to the google API to Job Blaster.
Make a note of the wsdl files url and how to add it to a project!
http://api.google.com/search/beta2/GoogleSearch.wsdl
Avoiding some really horrible performance with DataSet and DataGrid classes when following a pattern from the documentation for loading data which fills a temporary DataSet which is then Merged into the persistent DataSet. Merging more than a few hundred rows is dog slow.
I modified the .xsd file produced by dragging tables to a new file according to the pattern from the MasterDetails QuickStart sample. The key thing, I think, is that the generated .cs file defines a DataRelation between the Company and Job tables, “CompanyJobs”. By setting the DataMember property to “Company.CompanyJobs” instead of just “Job”, I get just the kind of linkage I expected. By controlling the DataMember property via a menu pick, the same DataGrid layout serves double duty.
It’s key to also use the data member string when obtaining a DataView object for the grid, for pick correlation for example.
osql is the simple command line tool for processing .sql files.
An existing database can be emptied, shrunk, detached and then connected with a connection string such as:
data source=PELL\VSDOTNET;AttachDBFilename=c:\tone\kzdev\vsp\jobsearch\jobsearch0.mdf;initial catalog=JobSearch;integrated security=SSPI;persist security info=False;workstation id=localhost;packet size=4096
A very simple batch file for running osql:
@echo on
set server=PELL\VSDOTNET
set newdbname=JobSearch
osql -e -d master -S %server% -E -Q "create database %newdbname%"
osql -e -d %newdbname% -S %server% -E -i "JobSearch.sql"
Converted the JobSearchDesignerOnly project to use a second Thread for the Spider. Turned out to be easier than expected. The only trick was in the CrawlResultsEventHandler which returns a results summary of each page crawled. With the Spider running on its own thread, the first event handler would violate the Windows.Forms STA threading model if it tried to directly update the GUI, so the event is redirected by a BeginInvoke call to a second delegate which runs on the controls thread. Worked like a charm. There’s also some complexity around making sure the thread gets cleaned up and only started once the GUI is up. See JobSearchControls.SpiderPanel.cs.
ArrayLists of objects with public properties only sort-of works with DataGrids. I could find no way of having the grid update when results where added to the ArrayList. Switched to DataTable and DataView and everything works like a charm.
Put the GUI for the Spider results in a UserControl with a WebBrowser and DataGrid on it. This is definitely the way to build hunks of UI.
KzDataGrid derives from DataGrid and adds support for automatic column width adjustments, but only when using DataTableStyles.
Finally figured out how to inhibit the “AddNew” row in a DataGrid bound to a DataSet:
((DataView)((CurrencyManager) jobDataGrid.BindingContext[dataSet, "Job"]).List).AllowNew = false;
The List member returns the object which implements the IList interface, which in the case of a DataSet will be a DataView. The BindingContext of the data for the grid will be handled by a CurrencyManager, the alternative PropertyManager only handles single values.