Wednesday, August 13, 2008

ASP.Net, Tilde(~), Virtual Paths and the Image Control

When using master pages and content pages located in different sub directory levels, you usually use a url with a root indicator (~). Sometimes the designer is unable to resolve or display images located off of the application root, even when the url containes a tilde (~) at the beginning of the path.

< img src="~/Image/picture.jpg" />

The tilde (~) is a shortcut to the HttpRuntime.AppDomainAppVirtualPath which will normally resolve back to the root of the virtual directory but this shortcut will only be resolved within server side controls. The standard HTML image control (img) is not rendered at the server and will simply pass the tilde on to the client browser. The issue was related to this and not directly to the use of master pages.
The solution is to insure that the control is rendered at the server. This can be done by adding the runat="server" property to the standard HTML image control or by using the ASP.NET image control.

< img src="~/Image/picture.jpg" runat="server" />
< asp:image runat="server" imageurl="~/Image/picture.jpg" />

Friday, January 04, 2008

VS2003: "unable to read the project file" "the system cannot find the file specified"

The web project would not be loaded, only be displayed as "unavailable".

Solution:
  • Exit VS
  • Delete the .SUO file
  • Start VS
  • Set the source control that you lost

Monday, April 16, 2007

VS2003: How do I retrieve the current row from a DataTable to which a DataGrid is bound after the grid has been sorted?


In an unsorted DataGrid bound to a DataTable, you can get a reference to a row in the DataTable through the DataGrid.CurrentRowIndex. DataTable dataTable = (DataTable)

dataGrid1.DataSource;
DataRow dataRow = dataTable.Rows[ dataGrid1.CurrentRowIndex ];

But if the grid has been sorted, you can no longer get at the current row in the table through the grid's CurrentRowIndex. But for both unsorted and sorted grids, you can get at the current row through the BindingContext and the Current property of the BindingManagerBase.

BindingManagerBase bm =
dataGrid1.BindingContextr[ dataGrid1.DataSource, dataGrid1.DataMember ];
DataRow dataRow = ( (DataRowView) bm.Current ).Row;

Wednesday, March 21, 2007

SQL: Creating search Stored Procedures

Below you'll find a good way to create a search stored procedure. This way you avoid creating different stored procedures to search or filtering the data in-memory.

DECLARE
@ProductName VARCHAR(50),
@CompanyName VARCHAR(50),
@CategoryName VARCHAR(50)
DECLARE
@UnitPrice MONEY,
@UnitsInStock SmallInt

--SET @ProductName = '%Cha%'
SET @CompanyName = '%exotic%'
SET @CategoryName = '%condi%'

SELECT
[Products].[ProductName],
[Suppliers].[CompanyName],
[Categories].[CategoryName],
[Products].[UnitPrice],
[Products].[UnitsInStock]
FROM
[Products]
INNER JOIN [Suppliers] ON [Products].[SupplierId] = [Suppliers].[SupplierId]
INNER JOIN [Categories] ON [Products].[CategoryId] = [Categories].[CategoryId]
WHERE
(@ProductName IS NULL OR [Products].[ProductName] LIKE @ProductName)
AND
(@CompanyName IS NULL OR [Suppliers].[CompanyName] LIKE @CompanyName )
AND
(@CategoryName IS NULL OR [Categories].[CategoryName] LIKE @CategoryName )

Monday, September 18, 2006

Sourcesafe: Reset Sourcesafe Admin Password

Hack the um.dat file to remove the Admin password

from offset 80 the bytes are (all numbers are hex)

0:80 55 55 bc 7f 41 64 6d 69 6e 00 00 00 00 00 00 00
0:90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:a0 00 00 00 00 90 6e 00 00 a8 01 00 00 00 00 00 00

This information is at YOUR OWN RISK

Friday, August 25, 2006

VS: Retrieving value of Enum

It's obvious you want to use Enums instead of numeric or even string values. But you still want to be as flexible as using a numeric or string value.

public enum enJudgement
{
Bad= 1,
Average= 2,
Good = 3
}


Retrieving the string value
enJudgement.Bad.ToString();

Retrieving the numeric value
Type tJudgement = typeof(enJudgement);
Enum.Format(tJudgement , Enum.Parse(tJudgement , enJudgement.Bad.ToString()), "d"));


Converting numeric/string value to Enum
(enJudgement)Enum.Parse(typeof(enJudgement), NumericOrStringvalue);

Tuesday, July 18, 2006

Install Microsoft apps that require SP2 without installing SP2

Launch regedit.exe
Go to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Windows
Change the CSDVersion value to be 512 or higher (0x0000200 in hexadecimal)
Close regedit.exe and install for example Visual Studio 2005
Rerun regedit.exe and change the CSDVersion value back to what it was originally

NB Don't forget to restore the CSDVersion, otherwise your PC won't boot after a Windows Update

More info: Aaron Sebner's Weblog

Tuesday, May 23, 2006

VS: Excel datasource reads values as DBNull

When using a connectionstring to connect to a Excel sheet like this:

SELECT * FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=C:\test\xltest.xls;Extended Properties=Excel 8.0')...[Customers$]


you can create a dataset based on the excel sheet.

However, using this connectionstring with mixed colums (columns that contain numeric values and tekst values) the provider will think the column is numeric and won't read the tekstual values.

To solve this problem you have to add an extended property IMEX to the connectionstring, tellling the provider to treat mixed colums (default) as string.
This way all the values in the columns will be read:

SELECT * INTO XLImport3 FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=C:\test\xltest.xls;Extended Properties=''Excel 8.0;IMEX=1''')...[Customers$]

Thursday, April 13, 2006

VS2005: Formview insert mode - Fill with initial value

Use the FindControl method to automatically fill your controls:

protected void FormView1_PreRender(object sender, EventArgs e)
{
string strDefaultProdName = "Product name";
if (FormView1.CurrentMode == FormViewMode.Insert &&
((TextBox)FormView1.FindControl("ProductNameTextBox")).Text.Length==0)
((TextBox)FormView1.FindControl("ProductNameTextBox")).Text =
strDefaultProdName;
}

Thursday, March 23, 2006

VS: Using Windows Authentication on a webservice called by an ASP.NET webapplication

It’s relatively simple to use the right authentication, but unfortunately mostly after you know it! Here are the steps to call a webservice with Windows Authentication:

1. Modify the web.config of the ASP.NET webapplication:
<authentication mode="Windows" />
<identity impersonate="true" />

2. Modify the web.config of the webservice:
<authentication mode="Windows" />
<authorization>
<allow users="Administrator" />
<deny users="*" />
</authorization>

3. Disable anonymous authentication in IIS for the ASP.NET webapplication and the webservice

4. Before calling the webservice set the credentials
localhost.Service1 srv= new WebAppTest.localhost.Service1();
srv.Credentials = System.Net.CredentialCache.DefaultCredentials;
srv.WebserviceFunction();


Good luck!

Wednesday, March 22, 2006

SQL: SQL Server marks DB as Suspect.

I hope it won't happen to you often, but it may occur you see a database in the Enterprise Manager marked as suspect. When so, you won't be able to open it or drop it. When a reboot of SQL server doesn't help, you can try the following:

use master
go
exec sp_resetstatus msdb -- replace msdb with your database name


Restart SQL server and you should be able to access the database again.

Run DBCC NEWALLOC, DBCC TEXTALL, and DBCC CHECKDB.

If you still can't access the DB, try the following:
Bypass (Emergency) mode and DUMP TRANSACTION WITH NO_LOG

Monday, March 20, 2006

VS: Ask user to confirm delete of record

Using a grid with a delete button, you often want the user to confirm the delete action. This is how to do it:

In VS 2005 add this to your button:
OnClientClick="return confirm('Are you sure you want to delete this record?');"
In VS 2003 add this to your button
OnClick="return confirm('Are you sure you want to delete this record?');"

Or bind it in code:

protected void myDataGrid_OnItemDataBound(object sender, DataGridItemEventArgs e)
{
if(e.Item.FindControl("DeleteLink") != null)
{
((LinkButton) e.Item.FindControl("DeleteLink")).Attributes.Add
("onClick", "return confirm('Are you sure you want to delete this record?');");
}
}

When the user presses the button it receives a messagebox with the text. When the user presses OK the server event is called. When the user presses Cancel, nothing happens.
Installed Windows XP Service Pack 2 to install VS 2005 and now you can't be reached in the network?

Follow the steps on this URL to solve your problem:

http://support.microsoft.com/kb/892199/en-us

Friday, March 17, 2006

VS: How to show a messagebox in a ASP.NET application

The following class implements messagebox functionality. When calling this function a messagebox is shown and the current page is still shown. (often the messagebox functions create a blank form with a messagebox on top)

You can call the function at any place (because it's static) like this: Messagebox.Show("Hello World");

public class Messagebox
{
public Messagebox()
{

}

private static Hashtable m_executingPages = new Hashtable();

public static void Show(string sMessage)
{
// If this is the first time a page has called this method then
if (!m_executingPages.Contains(HttpContext.Current.Handler))
{
// Attempt to cast HttpHandler as a Page.
Page executingPage = HttpContext.Current.Handler as Page;

if (executingPage != null)
{
// Create a Queue to hold one or more messages.
Queue messageQueue = new Queue();

sMessage = sMessage.Replace("\r", " ");

// Add our message to the Queue
messageQueue.Enqueue(sMessage);

// Add our message queue to the hash table. Use our page reference
// (IHttpHandler) as the key.
m_executingPages.Add(HttpContext.Current.Handler, messageQueue);

// Wire up Unload event so that we can inject some JavaScript for the alerts.
executingPage.Unload += new EventHandler(ExecutingPage_Unload);
}
}
else
{
// If were here then the method has allready been called from the executing Page.
// We have allready created a message queue and stored a reference to it in our hastable.
Queue queue = (Queue)m_executingPages[HttpContext.Current.Handler];

// Add our message to the Queue
queue.Enqueue(sMessage);
}
}

// Our page has finished rendering so lets output the JavaScript to produce the alert's
private static void ExecutingPage_Unload(object sender, EventArgs e)
{
// Get our message queue from the hashtable
Queue queue = (Queue)m_executingPages[HttpContext.Current.Handler];

if (queue != null)
{
StringBuilder sb = new StringBuilder();

// How many messages have been registered?
int iMsgCount = queue.Count;

// Use StringBuilder to build up our client slide JavaScript.
sb.Append("<script language='javascript'>");

// Loop round registered messages
string sMsg;
while (iMsgCount-- > 0)
{
sMsg = (string)queue.Dequeue();
sMsg = sMsg.Replace("\n", "\\n");
sMsg = sMsg.Replace("\"", "'");
sb.Append(@"alert( """ + sMsg + @""" );");
}

// Close our JS
sb.Append(@"</script>");

// Were done, so remove our page reference from the hashtable
m_executingPages.Remove(HttpContext.Current.Handler);

// Write the JavaScript to the end of the response stream.
HttpContext.Current.Response.Write(sb.ToString());
}
}
}

Tuesday, March 14, 2006

VS2003: How to enable JavaScript debugging

Step 1:
The most forgotten step in enabling script debugging in VS 2003 is enabling the browser to debug scripts. You can find this option in Internet Explorer. Tools -> Internet Options…-> Advanced. You should disable the checkbox Disable script debugging.

Step 2:
Start your VS solution. After starting go to the page you want to debug. In VS go to Debug->Windows->Running documents. Here you see the documents that have been currently loaded in the Internet Explorer.
Open the document (in the running documents window) you want to debug and place a breakpoint.

When you refresh the page your code will stop at the breakpoint when the code passes.

If you have any problems, check to see if VS is set to debug scripts. Tools->Options…->Debugging->Just-In-Time->Script