PDA

View Full Version : ASP.NET 2.0: Update/Delete problems


CurtWRC
06-21-2006, 01:56 AM
I have just switched from ASP.NET 1.1 to ASP.NET 2.0. Before the switch my ASP.NET websites were working fine, but now there are a few problems. When I'm trying to delete records from a database table, or update them I get these errors:

Could not delete from specified tables.

Operation must use an updateable query.

Do you know any reason why I'm getting these errors now that Ive moved to a new server with ASP.NET 2.0?

Thanks.

vinyl-junkie
06-21-2006, 02:51 AM
Perhaps the logon id that is connecting to the database doesn't have sufficient privileges to update or delete.

otaku149
06-21-2006, 04:25 AM
Operation must use an updateable query.


Most likely you are running into this issue:
http://support.microsoft.com/default.aspx?scid=kb;en-us;316675

CurtWRC
06-21-2006, 10:22 PM
Would all ASP.NET 1.1 code be allowed on a ASP.NET 2.0 website?

I don't think my problem is either of them above though. Thanks for your help anyway.

otaku149
06-21-2006, 10:28 PM
No, some ASP.NET 1.1 code are not allowed on ASP.NET 2.0

otaku149
06-21-2006, 10:45 PM
You are using ms-access on IIS6, check permission for the folder where your access db is located. Make sure "Network Services" user has Full Control.

CurtWRC
06-21-2006, 10:53 PM
You are using ms-access on IIS6, check permission for the folder where your access db is located. Make sure "Network Services" user has Full Control.

That would seem to make sense as Ive been doing some testing and basically I can view data from the databases on my websites, but not edit them in any way. However I don't know how to check how much permission I have with the database folder I store them in. Would I do it through my host (Brinkster.com)?

otaku149
06-21-2006, 11:18 PM
If you are in shared hosting environment, you won't be able to check permission by yourself. Ask your host Brinkster to give Full Control to the "Network Services" user. If for some reasons they don't want just let me know, I can recommend you few very good asp.net hosting cie.

CurtWRC
06-22-2006, 12:47 AM
Thanks (once again) for your help otaku149 :)

I had a 'live-chat' with them and basically told them what you posted and theyve sorted it out to a certain degree. There are still some errors though which I dont understand. I plan to move to 'Easy-CGI' around November time anyway as Brinkster have other drawbacks. For example, I cannot upload images through an .aspx page without supplying FTP details. Therefore members wont be able to upload images and avatars to Version 3 of Rallystuff.net which will be a huge disadvantage.

Thanks again,

Curt.

otaku149
06-22-2006, 01:25 AM
You're welcome Curt. To upload images through an .aspx page you need first to create a folder and then ask Brinkster to give Full Control to the "Network Services" user for that specific folder.

Now with ASP.Net 2.0 it's easier than ever to upload images through an .aspx page. Use the FileUpLoad control, an example of that control can be found here:
http://www.asp.net/QuickStart/aspnet/doc/ctrlref/standard/fileupload.aspx

This should work even at Brinkster.

If you are looking for a new host, I am currently using Webecs and I am very satisfied.
http://www.webecs.com/index.asp?ref=getelementbyid.com

CurtWRC
06-22-2006, 06:38 PM
Ive just contacted Brinkster and theyve changed my permissions. I can now upload images without having to enter FTP details :) .
Thanks again Martial :thumbsup:

For my test I used this sub routine:

Sub Button_Click( s As Object, e As EventArgs )
inpFileUp.PostedFile.SaveAs( "PATH HERE" )
End Sub

Do you know of anyway of editing that to resize images to specified dimensions, or a way of not saving the file if its not the correct size or is too big a file size?

Thanks again,
Curt.

otaku149
06-22-2006, 07:55 PM
Yes I know both solution. My suggestion is to use the second one because the first one take a lot of memory resources.

We need to validate 4 things:

Make sure the user upload something
Make sure the user upload an image (.gif or .jpg or .png)
Make sure the user upload an image not more than 20kb
Make sure the user upload an image with a width not more than 50px and height not more than 50px

The 20kb and 50px are just examples, you can change those values.

Now you need to decide the name of the uploaded image. Because your forum users must be authenticated to edit their profile and upload image and because the image name must be unique, my suggestion is to use their username using "User.Identity.Name", this will create something like:

Curt.gif
toto.gif
Sam.jpg

Or you can update their profile in your database using the Guid to create a random 6 char, this will create something like:

9c8225.gif
abg3ue.jpg
7fk28s.gif

Here is below the variable fileNameOnServer for both above solutions, choose the solution that you prefer:


string fileNameOnServer = Guid.NewGuid().ToString().Substring(0, 6) + fileExtension;
string fileNameOnServer = User.Identity.Name.ToString() + fileExtension;


In the below code, edit the folder path using the serverPath variable:

string serverPath = Server.MapPath("avatars/");


I made the code in C#, just let me know if you prefer vb.net

<%@ Page Language="C#" %>
<%@ import Namespace="System.IO" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

protected void btUpload_Click(object sender, EventArgs e)
{
//Make sure the user upload something
if (FileUpload1.HasFile)
{
string serverPath = Server.MapPath("avatars/");
string fileToUpload = FileUpload1.PostedFile.FileName;
string fileExtension = Path.GetExtension(fileToUpload);
string fileNameOnServer = Guid.NewGuid().ToString().Substring(0, 6) + fileExtension;
//string fileNameOnServer = User.Identity.Name.ToString() + fileExtension;
string fileContentType = FileUpload1.PostedFile.ContentType;
int fileSize = FileUpload1.PostedFile.ContentLength;

//Make sure the user upload an image (.gif or .jpg or .png)
if (fileContentType.ToLower().IndexOf("image") == -1)
{
string errMsg = "Error, only .gif .jpg or .png are allowed.";
lblMsg.Attributes.Add("style", "color:Red;");
lblMsg.Text = errMsg;
AlertMsg.Display(this.Page, "ErrorContentType", errMsg);
return;
}

//Make sure the user upload an image not more than 20kb
if (fileSize > 20000)
{
string errMsg = "Error, 20 kb maximum.";
lblMsg.Attributes.Add("style", "color:Red;");
lblMsg.Text = errMsg;
AlertMsg.Display(this.Page, "ErrorContentLength", errMsg);
return;
}
try
{
FileUpload1.SaveAs(serverPath + fileNameOnServer);
}
catch (Exception ex)
{
lblMsg.Attributes.Add("style", "color:Red;");
lblMsg.Text = ex.Message.ToString();
AlertMsg.Display(this.Page, "ErrorException", ex.Message.ToString());
}
System.Drawing.Image img;
System.IO.FileStream fs = new System.IO.FileStream(serverPath + fileNameOnServer, System.IO.FileMode.Open);
img = System.Drawing.Image.FromStream(fs);
fs.Close();
int width = img.Width;
int height = img.Height;

//Make sure the user upload an image with a width not more than 50px
//and height not more than 50px
if (width > 50 | height > 50)
{
string errMsg = "Error, your image must be 50px X 50px maximum.";
lblMsg.Attributes.Add("style", "color:Red;");
lblMsg.Text = errMsg;
AlertMsg.Display(this.Page, "ErrorContentLength", errMsg);
FileInfo f;
f = new FileInfo(serverPath + fileNameOnServer);
f.Delete();
return;
}
lblMsg.Attributes.Add("style", "color:Black;");
lblMsg.Text = "We received your image, thank you!";
}
else
{
string errMsg = "Error, Please browse and select a file to upload.";
lblMsg.Attributes.Add("style", "color:Red;");
lblMsg.Text = errMsg;
AlertMsg.Display(this.Page, "ErrorEmpty", errMsg);
}
}

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Upload Image</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="FileUpload1" runat="server" AlternateText="You cannot upload files" />
<asp:Button ID="btUpload" runat="server" OnClick="btUpload_Click" Text="Upload" />
<br />
<asp:Label ID="lblMsg" runat="server" Font-Bold="True"></asp:Label>
</div>
</form>
</body>
</html>


I added the below class utility AlertMsg.cs to display javascript alert message. You need to create a folder "App_Code" and place that file inside that folder:

AlertMsg.cs

using System.Text;

public class AlertMsg
{
public static void Display(System.Web.UI.Page aspxPage, string strKey, string msg)
{
string strUniqueScriptName = strKey;
StringBuilder OutputString = new StringBuilder();
OutputString.Append("<script type=\"text/javascript\">" + "\n");
OutputString.Append("<!--" + "\n");
OutputString.Append("alert('" + msg + "');" + "\n");
OutputString.Append("//-->" + "\n");
OutputString.Append("</script>" + "\n");
if (aspxPage.IsPostBack & !(aspxPage.ClientScript.IsStartupScriptRegistered(strUniqueScriptName)))
{
aspxPage.ClientScript.RegisterStartupScript(aspxPage.GetType(), strUniqueScriptName, OutputString.ToString());
}
}
}

CurtWRC
06-22-2006, 10:10 PM
Before reading this I had a go at allowing users to uploads avatars on my site. I'm not to concerned about how big the image is as I have included a way of resizing when displaying by storing values of width and height. I then just included an if statement so that they cannot display it any larger than 100x100. I also saved the files as 'avatar-username.gif'. However like youve mentioned in your post I need to be able to ensure they cannot upload other file types such as an .aspx file. Also it cannot be more than 20kb. I am coding in VB so could you post those particular parts of code in VB please?

Thanks.

otaku149
06-22-2006, 10:48 PM
Here is the VB.Net code with the modifications:

<%@ Page Language="VB" %>
<%@ import Namespace="System.IO" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

Protected Sub btUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs)

If FileUpload1.HasFile Then

Dim serverPath As String = Server.MapPath("avatars/")
Dim fileToUpload As String = FileUpload1.PostedFile.FileName
Dim fileExtension As String = Path.GetExtension(fileToUpload)
Dim fileNameOnServer As String = "avatar-" & User.Identity.Name & fileExtension
Dim fileContentType As String = FileUpload1.PostedFile.ContentType
Dim fileSize As Integer = FileUpload1.PostedFile.ContentLength

If Not InStr(fileContentType.ToLower(), "image") = 1 Then
Dim errMsg As String = "Error, only .gif .jpg or .png are allowed."
lblMsg.Attributes.Add("style", "color:Red;")
lblMsg.Text = errMsg
AlertMsg.Display(Me.Page, "ErrorContentType", errMsg)
Return
End If

If fileSize > 20000 Then
Dim errMsg As String = "Error, 20 kb maximum."
lblMsg.Attributes.Add("style", "color:Red;")
lblMsg.Text = errMsg
AlertMsg.Display(Me.Page, "ErrorContentLength", errMsg)
Return
End If

Try
FileUpload1.SaveAs(serverPath & fileNameOnServer)
Catch ex As Exception
lblMsg.Attributes.Add("style", "color:Red;")
lblMsg.Text = ex.Message.ToString()
AlertMsg.Display(Me.Page, "ErrorException", ex.Message.ToString())
End Try

lblMsg.Attributes.Add("style", "color:Black;")
lblMsg.Text = "We received your image, thank you!"

Else

Dim errMsg As String = "Error, Please browse and select a file to upload."
lblMsg.Attributes.Add("style", "color:Red;")
lblMsg.Text = errMsg
AlertMsg.Display(Me.Page, "ErrorEmpty", errMsg)

End If

End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Upload Image</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="FileUpload1" runat="server" AlternateText="You cannot upload files" />
<asp:Button ID="btUpload" runat="server" OnClick="btUpload_Click" Text="Upload" />
<br />
<asp:Label ID="lblMsg" runat="server" Font-Bold="True"></asp:Label>
</div>
</form>
</body>
</html>



AlertMsg.vb

Imports System.Text

Public Class AlertMsg

Public Shared Sub Display(ByRef aspxPage As System.Web.UI.Page, ByVal strKey As String, ByVal msg As String)

Dim strUniqueScriptName As String = strKey
Dim OutputString As New StringBuilder
OutputString.Append(ControlChars.Lf & "<script type=""text/javascript"">" & ControlChars.Lf)
OutputString.Append("<!--" & ControlChars.Lf)
OutputString.Append(ControlChars.Tab & "alert('" & msg & "');" & ControlChars.Lf)
OutputString.Append("//-->" & ControlChars.Lf)
OutputString.Append("</script>" & ControlChars.Lf)
If aspxPage.IsPostBack And Not aspxPage.ClientScript.IsStartupScriptRegistered(strUniqueScriptName) Then
aspxPage.ClientScript.RegisterStartupScript(aspxPage.GetType(), strUniqueScriptName, OutputString.ToString())
End If

End Sub

End Class

CurtWRC
06-23-2006, 03:01 PM
I understand the majority of that code, but what I don't get is how the .aspx page knows that Im referring to the AlertMsg.vb file without having to import it. Also the AlertMsg.vb is alien to me. Ive been looking through a book I have on ASP.NET 2.0 (Professional ASP.NET 2.0) and thats helped explain the code a bit better. I tried copying over your code to my page first just to see if it would work how it is and I get an error because of this line:

Dim fileExtension As String = Path.GetExtension(fileToUpload)

Compiler Error Message: BC30451: Name 'Path' is not declared.

Thanks,
Curt.

otaku149
06-23-2006, 05:27 PM
First let's start with the Compiler Error Message: BC30451: Name 'Path' is not declared. I will explain to you the AlertMsg.vb after.

To help you I need to know some infos Curt.

Do you test directly online or on your PC ?
Do you have both Visual Studio version 2003 and 2005 on your PC ?

You told me in your previous thread that you want to learn ASP.Net 2.0. It's possible to get side by side both version of Visual Studio and both version of the .NET Framework (1.1 and 2.0) on the same PC.

You can get a light but very powerfull version of Visual Studio .Net 2005 and it's free. This version come with codebehind and Intellisense etc...

Because it's easier to debug code locally, let me know what software you are using exactly to test the code I provided to you. If you don't have Studio version 2005 installed on your PC, I can explain how to perform a clean installation and give you some tips on running both .NET Framework (1.1 and 2.0) on the same PC.

CurtWRC
06-24-2006, 01:21 PM
I do use Visual Studio 2005, and I save directly to the website through FTP. I dont have Visual Studio 2003 though.

otaku149
06-24-2006, 02:24 PM
I do use Visual Studio 2005, and I save directly to the website through FTP. I dont have Visual Studio 2003 though.

My suggestion Curt is to install Visual Web Developer 2005 Express Edition and SQL Server 2005 Express Edition with SQL Server Management Studio Express, it's completly free:

If you want to learn ASP.Net 2.0 at a professional level, specially with the book you have bought, you really need these software.

Would you like to install these software ?
If yes, what is your Operating System (WinXP Pro SP2 or WinXP Home Edition or something) ?

Let me know if you wish to install these software, I will provide you some good links and help you to start if you wish.

CurtWRC
06-24-2006, 02:31 PM
Sorry, Ive made a mistake. I have got Visual Web Developer 2005 Express Edition. I thought that was Visual Studio. I am using Access databases to store my data so I don't need those other software do I?

otaku149
06-24-2006, 03:19 PM
Sorry, Ive made a mistake. I have got Visual Web Developer 2005 Express Edition. I thought that was Visual Studio.


Visual Web Developer 2005 Express Edition is the light but very powerfull version of Visual Studio 2005.


I am using Access databases to store my data so I don't need those other software do I?


It's up to you, if you wish to learn SQL Server you can download SQL Server 2005 Express Edition with SQL Server Management Studio Express:
http://msdn.microsoft.com/vstudio/express/sql/download/

Access databases is good but SQL Server is much powerful. One thing is sure, if you move to SQL Server you won't go back to access anymore. That's depend on how much time you have to learn new stuff. I am sure that the book you have bought has a lot of SQL Server code too. It's really up to you Curt. I provided these infos because most people don't know that software are free.

About the Compiler Error Message: BC30451: Name 'Path' is not declared. Create a new project using Visual Web Developer with the code I gave you.

You need to add the System.IO Namespace <%@ Import Namespace="System.IO" %> and build the website. In the solution explorer, right-click on your website and click on "Build Website". If you are using code-behind you will need to import the namespace in your .aspx.vb file like this:

Imports System.IO

Public Class ......
'etc...


Or you can add the Namespace in your web.config. This is a new feature on ASP.Net 2.0. Instead of importing all the namespace on every page you can simply add it on your web.config like the below example:

web.config sample:

<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true" strict="false" explicit="true"/>
<pages>
<namespaces>
<clear/>
<add namespace="System"/>
<add namespace="System.IO"/>
<add namespace="System.Data"/>
<add namespace="System.Collections"/>
<add namespace="System.Collections.Specialized"/>
<add namespace="System.Configuration"/>
<add namespace="System.Text"/>
<add namespace="System.Text.RegularExpressions"/>
<add namespace="System.Web"/>
<add namespace="System.Web.Caching"/>
<add namespace="System.Web.SessionState"/>
<add namespace="System.Web.Security"/>
<add namespace="System.Web.Profile"/>
<add namespace="System.Web.UI"/>
<add namespace="System.Web.UI.WebControls"/>
<add namespace="System.Web.UI.WebControls.WebParts"/>
<add namespace="System.Web.UI.HtmlControls"/>
</namespaces>
</pages>
<authentication mode="Windows"/>
</system.web>
</configuration>


Test the code I provided to you on Visual Web Developer. Once the code will work in your Visual Web Developer, it will work on Brinkster.

If it's not already done, you should place your website on Visual Web Developer to convert from framework 1.1 to 2.0.

otaku149
06-24-2006, 04:16 PM
About your App_Code folder and AlertMsg.vb question:

Use App_Code folder to place source code that is then compiled automatically as part of your Web site, making it unnecessary to compile components or controls before using them in your site.

Here is for an example, on Visual Web Developer, go to solution explorer, right-click on website and click "Add ASP.NET Folder" + "App_Code", this will create the App_Code folder. Right click on that folder and click "Add new Item" and create a class Person.vb:

Person.vb

Public Class Person

'member variables
Private mFirstName As String
Private mLastName As String

'property
Public Property FirstName() As String
Get
Return mFirstName
End Get
Set(ByVal value As String)
mFirstName = value
End Set
End Property

'property
Public Property LastName() As String
Get
Return mLastName
End Get
Set(ByVal value As String)
mLastName = value
End Set
End Property

'function returning the full name
Public Function DisplayFullName() As String
Return FirstName() & " " & LastName()
End Function

End Class


Than create a test.aspx page to create an object of the Person Class, set the FirstName property, set the LastName property and use the DisplayFullName() function to display the full name.

test.aspx

<%@ Page Language="VB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

'create an object of the Person Class
Dim oPerson As New Person()
'set the FirstName property
oPerson.FirstName = "Fernando"
'set the LastName property
oPerson.LastName = "Alonso"
'use the DisplayFullName() function to display the full name in a label
lblMsg.Text = oPerson.DisplayFullName()

End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Class Sample</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblMsg" runat="server"></asp:Label>
</div>
</form>
</body>
</html>


If we come back to your AlertMsg.vb question, I used a shared method "Shared Sub Display". In VB.Net, you can have methods that are available without creating an instance of the class. These are known as shared methods (C# use static methods). That why I was able to call the method directly without creating an instance, like below:


AlertMsg.Display(Me.Page, "ErrorContentType", errMsg)


Now why use class like that? Simply because an application has a lot of repetitive code like database connection, data binding etc... Class are reusable and flexible. In this particular case, I am using the StringBuilder Class to display javascript alert message.

Hope this help!

CurtWRC
06-24-2006, 06:53 PM
Thanks Martial.

This coding is quite advanced for the level Im at so its been very helpful. Just curious, why is SQL more powerful than access?

Thanks.

otaku149
06-24-2006, 08:18 PM
MS-Access has some limitations such as the number of concurrent users, stored procedure, database structure, data types, speed, application performance, scalability, robustness, security, reliability, recoverability and availability.

The main reason why developer used MS-Access in the past is the licensing fees. But now you can get good SQL Server hosting for less than $10/mo. And good ASP.Net with SQL Server hosting for less than $20/mo.

SQL Server can be a little harder to learn at the beginning but it's well worth the effort. Once you get up to speed and comfortable with it, you should find it better than MS-Access.