19 May, 2011
Recovering a SQLEXPRESS Installation
With that in mind, I set out on the path to discover how I can recover that installation, and not have to go through the process of uninstalling and re-installing SqlExpress. I finally came across this old post at Phoenix blog.
A few things to keep in mind; His instructions are for full-blown SQL Server, so instead of using “NET STOP MSSQLSERVER” you’ll have to use “NET STOP MSSQL$SQLEXPRESS”. This is for all the stop and starts. Also, one has to have local administrator privileges on the machine, if you don’t have that, as far as I know, you’re pretty much up a creek without a paddle. The process is quick and simple really, I’ll post the steps here (without the nice screen-scrapes that Deepak has in his blog, you can go there and look at them if you need to).
1) Open command line window
2) type NET STOP MSSQL$SQLEXPRESS and wait for the service to stop
3) type NET START MSSQL$SQLEXPRESS /m - this puts sql server in single-user mode (I am not sure what that is really, but hey,it works!)
4) Open your SQL Server Management Studio, and click “New Query” you’ll be presented with the connection dialog window, select the instance of SqlExpress and open the connection.
5) In the new query window type “sp_addsrvrolemember ‘YOUR_USER_NAME’, ‘SYSADMIN’” (sans quotes, of course). This will add your login to the sysadmin role.
6) Close Management Studio.
7) Back in the command prompt window type “NET STOP MSSQL$SQLEXPRESS” to stop the service
8) Next time “NET START MSSQL$SQLEXPRESS” in the command prompt to start the service again, but in normal mode (not single user mode this time, notice the lack of ‘/m’ switch in the command.
06 May, 2011
SalesForce excitement with .NET
Next project on deck is creating a Single-Sign-On into SalesForce. This is going to be a bit more daunting I think. All of the SalesForce samples and help deal with OpenSSO running on it's own server. We're going to go with the Windows Identity Foundation tools, using the SSO into SalesForce as a launching pad for a new login process for all of the apps across the board. Creating an SSO for everything will mean that all logins will hit the same page, utilize the same processes, no matter if they come to the app via a web browser, or an iPhone, or a Xoom tablet or whatever. Should be great fun and a terrific learning experience.
FireFox 4 jQuery document height and width
After some aggravating trial and error, I discovered the culprit. See, in the jQuery documentation, they say you can use two methods to get the height and width of a document:
$(document).height();
$(document).css('height');
The former gives you just the pixel numbers, while the latter is supposed to give you the entire CSS height (i.e. "450" for the first, and "450px" for the second). The problem is, that FireFox 4 doesn't recognize $(document).css('height') - or width for that matter. So you have to get it with just the .height() command, and append 'px' to the end of it.
17 March, 2011
CSS funkiness with Firefox
Anyway, I was fitting a checkbox today, and cursed a little under my breath when it didn't show up properly positioned in IE9. It's possible that if I'd been using IE8 or even IE7, I might not have found this, since those pretty much handle CSS in the same manner as Firefox. To be honest, I was ready for this to be IE9's fault, so I fired up Chrome and Opera to verify my assumptions. You could have knocked me over with a feather when the page rendered in Chrome and Opera just the same as it did in IE9. It was Firefox that was the problem.
Now, I'm used to making exceptions for IE, so I had to do a bit of research on how to do it with Firefox, and this is what I found:
<style type="text/css">
.complete-checkbox
{
position:relative;
top:23px;
display:block;
float:right;
color:white;
font-weight:bold;
}
@-moz-document url-prefix() {
.complete-checkbox-ff
{
position:relative;
top:0px;
display:block;
float:right;
color:white;
font-weight:bold;
}
}
</style>
Essentially, I added a second class specifically for Firefox and used those properties only if the browser is Mozilla.
06 June, 2008
ESRI & ASP.NET Master Pages
One of the great things about VS 2005 & ASP.NET 2.0+ is the ability to quickly and easily create and user Master Pages in your ASP.NET web application.
One of the horribly difficult things about Master Pages is when using mash-ups, figuring out how they work exactly. Ok, if you don't know about Master Pages, then you should probably investigate them some.
A Master Page is not really a page, but rather a template that holds containers into which pages render (but can also regular HTML there as well). So a Master Page can have your title, image banner, navigation links, login stuff, breadcrumb trail...all that stuff, and also contains one or more "ContentPlaceHolder" controls.
The problem when putting an ArcGIS Server map in a page that has a master page is that when the page is rendered, the name of the map changes. That is, if you leave you map the default "Map1" name, when rendered, it has the name "ct00_ContentPlaceHolder1_Map1". Assuming, of course, you lave the ContentPlaceHolder name the default AND you put the map in the first instance of the ContentPlaceHolder controls.
This creates issue when attempting to access the map via JavaScript. In the WebMapApp.js file that is defaultly created when a Web Mapping Application is created in VS2005, it is assuming that you leave everything as the default names when you put stuff in the map. With that in mind, it uses names like "Map1", "TaskResults1" etc.
To fix this, I created a global var in the javascript file:
var webMapControlPrefix = "ctl00_ContentPlaceHolder1_";
So, for instance, the setpageElementSizes() function goes to define the scale bar , it used to do:
webMapAppScaleBar = document.getElementById("ScaleBar1");But now, I have it looking like this:
webMapAppScaleBar = document.getElementById(webMapControlPrefix+"ScaleBar1");You probably get the idea. If not, drop a comment and I'll see what I can find out about whatever confusion there is.
21 April, 2008
GridView RowUpdating: Stupid, stupid stupid error
Making an error in your code is one thing. But making an error that is so brilliantly, blatantly and egregiously stupid...well, that is something wholly and completely different.
Case in point. I have a GridView control on a page. I need to be able to edit that GridView control. However, to populate the GridView, I need a dataset which contains a " WHERE [COLUMN] IN (values)" where clause. The problem is, that the SqlDataSource really doesn't seem to support this very easily. I'm almost-but-not-quite certain it probably-might-possibly does, but I couldn't figure it out.
Because of that, I needed to bind the GridView to a DataSource programmatically. And that I did, right off the bat, right when the page loads, because, you know, I want the damn data right the hell away.
So what I neglected to do was put the data binding declarations in the good ol' trusty "if (!Page.IsPostBack)" statement. Which means that each and ever time the page loaded (i.e, when I clicked the "Edit" and "Update" links) the GridView was rebound to the original data. No fracking wonder my stuff wasn't working.
31 March, 2008
Highlighting features with ArcGis Server 9.2
I have the need to highlight items when the user selects to zoom to a particular item from a custom search. If I was using the ResultsTask control, then the user could simply check the checkbox next to the feature, and it would highlight. However, since the client doesn't like the treeview style of the ResultsTask, I have put the search results into an HTML table. Now, when the user selects to zoom to a feature, it will automatically highlight the feature.
I found this code in the ESRI forums, and it works well.
// This gives us a nice light blue color. You can change the color to whatever you want.
ESRI.ArcGIS.ADF.ArcGISServer.RgbColor irgbc = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor();
irgbc.Red = 50;
irgbc.Green = 255;
irgbc.Blue = 255;
irgbc.AlphaValue = 255;
ESRI.ArcGIS.ADF.ArcGISServer.FIDSet fids = new ESRI.ArcGIS.ADF.ArcGISServer.FIDSet();
int[] ids = new int[1];
ids[0] = Convert.ToInt32(key); //<-- OBJECTID of the feature to highlight
fids.FIDArray = ids;
ESRI.ArcGIS.ADF.ArcGISServer.MapDescription mapdesc = ((MapFunctionality)mf).MapDescription;
ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription[] layerdescs = mapdesc.LayerDescriptions;
ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription layerdesc = layerdescs[layerid];
layerdesc.Visible = true;
layerdesc.SelectionColor = irgbc;
layerdesc.SelectionFeatures = fids.FIDArray;
The problem with the above code is that it highlights the entire area. Not bad for point features, but for polygons, it covers everything underneath it completely. I tried adjusting the RgbColor.AlphaValue, but that didn't change anything at all. I'm thinking that is a red herring, and doesn't really do anything at all. So what I decided to do was instead of filling the entire polygon, I just use ShowSelectBuffer as seen below:
ESRI.ArcGIS.ADF.ArcGISServer.RgbColor irgbc = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor();
irgbc.Red = 50;
irgbc.Green = 255;
irgbc.Blue = 255;
irgbc.AlphaValue = 255;
ESRI.ArcGIS.ADF.ArcGISServer.FIDSet fids = new ESRI.ArcGIS.ADF.ArcGISServer.FIDSet();
int[] ids = new int[1];
ids[0] = Convert.ToInt32(key);
fids.FIDArray = ids;
ESRI.ArcGIS.ADF.ArcGISServer.MapDescription mapdesc = ((MapFunctionality)mf).MapDescription;
ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription[] layerdescs = mapdesc.LayerDescriptions;
ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription layerdesc = layerdescs[layerid];
layerdesc.Visible = true;
layerdesc.ShowSelectionBuffer = true;
layerdesc.SelectionFeatures = fids.FIDArray;
By using LayerDescription.ShowSelectBuffer, the feature is outlined with the highligh color, instead of filled in. This gives us the ability to see what is within the feature, while still knowing where the feature was located.
References:
http://forums.esri.com/Thread.asp?c=158&f=2276&t=211190&mc=12#msgid719661
http://forums.esri.com/Thread.asp?c=158&f=2276&t=223224&mc=1
28 March, 2008
ESRI breaks my custom zoom to method
I have an ArcGIS Server application. The client didn't like the standard format ESRI uses for displaying search results. So I made my own version. Basically, I return an HTML table through Callback scripting and populate a DIV with it. That table contains a column which is a hyperlink which calls functionality to zoom to that particular feature. Here's my code for that:
System.Data.DataTable dataTable = null;
ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality )Map1.GetFunctionality(0);
if (mf != null)
{
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource;
bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
int shapeInd = -1;
if (supported)
{
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc;
qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
string[] lids;
string[] lnames;
qfunc.GetQueryableLayers(null, out lids, out lnames);
All this works splendidly...or at least it did. That was until I went an used ESRI's MapIdentify tool. This tool by default puts things in the task results panel. When I used the zoom to functionality in the task results panel, I noticed that my custom zoom to method suddenly quick functioning. This was distressing to say the least. It seems that every time I actually start to feel like I somewhat understand ArcGIS, I get blind-sided by something stupid like this.
After some careful debugging, I discovered what was happening was that ESRI stacks new MapResourceItems on top of the actual map when you interact with the task results. So originally my code was working fine when I was getting MapResourceItems[0] since that was the only MapResourceItem. But after running the task results, both the layer names and layer ids returned from the GetQueryalbleLayers() method were coming back as GUIDs.
My solution was to loop through all MapResourceItems until I found a MapResourceItem with a name that matches the map name.
System.Data.DataTable dataTable = null;
ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = null;
for (int i = 0; i < this.MapResourceManager1.ResourceItems.Count; i++)
{
if (string.Compare(this.MapResourceManager1.ResourceItems[i].Name, this.m_mapName, true) == 0)
{
mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(i);
}
}
if (mf != null)
{
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource;
bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
int shapeInd = -1;
if (supported)
{
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc;
qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
string[] lids;
string[] lnames;
qfunc.GetQueryableLayers(null, out lids, out lnames);
