Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Unable to display Word Doc in ASP.NET correctly

Status
Not open for further replies.

tshad

Programmer
Jul 15, 2004
386
0
0
US
I have a word file stored in an SQL database and am trying to read and display on my ASP.Net page. It seems to work OK as far as reading and displaying on the page, but it is not displaying as a word document, but as a text with all the garbage characters (formatting, non text characters).

What am I doing wrong?

Code:
<%@ Page Language="VB" ContentType="text/html" trace="true" ResponseEncoding="iso-8859-1" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<html>
<head>
<title>Temp display</title>
<script runat="server">

	Sub Page_Load(sender as Object, e as EventArgs)

			Dim sResults As String

			Dim ConnectionString as String =System.Configuration.ConfigurationSettings.AppSettings("MM_CONNECTION_STRING_Contour_Server")
			Dim objConn as New SqlConnection (ConnectionString)
			objConn.Open()
			
			Dim CommandText as String = "select document from openworx..qadocs"
			Dim objCmd as New SqlCommand(CommandText,objConn)
			Dim objCommand as SqlCommand = new SqlCommand(CommandText, objConn)
			Dim objDataReader as SqlDataReader = objCommand.ExecuteReader( _
				CommandBehavior.CloseConnection)


		Dim arrByteData As Byte()
	
		while (objDataReader.Read() = true)
				if(objDataReader(0) is System.DBNull.value) then
					exit while
				else
					Response.Clear()
					Response.AddHeader("content-disposition", "inline;filename=Stuff.doc")
					Response.ContentType = "application/msword"
					arrByteData = Ctype(objDataReader(0),Byte())
 					response.BinaryWrite(arrByteData)
				end if
		end while
	End Sub		
</script>

</head>
<body>

</body>
</html>

Thanks,

Tom.
 
Tom,

I am not sure, but I think you can remove the response.addHeadder.
Also I think that the body section could be causing a problem. i.e. Remove your <body></body> tags.


I will need to look over some code I wrote a while ago, as well has how it saved word documents and redisplayed them.

However it's approach was simple, it stored the document into a database and stored the content type.. Jpeg, PDF, Excel, Doc etc...

then it did nothing more than read the content type and binary data back to the client via a stream..


No body section, no response.headder..

HTH


Rob
 
Tried both and get the same result.

Actually, the way I had it set up, I have to comment out the line:

Response.ContentType = "application/msword"

If I don't I get a message saying it can't load the page I am running. If I take out the line, I get all the text from the record (the word document) and then I am just printing the text with all the formatting codes.

For some reason, it won't allow me to display it as an MSWORD doce (I get the same problem if I set it as msexcel).

I am going to have to just read the document directly from the disk, if I can't solve this. I would prefer not to do this.

Thanks,

Tom.
 
Try this example(you will need to edit names and things for your own project)

(from playing around today, the length argument of the response.output argument is critical - wrong size, it doesn't display correctly..



Database Code

Code:
Create Table Files
(DocID int identity primary key,
 Headding varchar(300) not null,
 MimeType varchar(300) not null,
 FileName varchar(1000) not null,
 [Size] int not null,
 Data image not null)
go
create proc StoreFiles
@headding varchar(300),
@MimeType varchar(300),
@FileName varchar(1000),
@Data image,
@Size int

as
set nocount on
insert into files (headding,mimetype,filename,data,[size])
values (@headding,@mimetype,@filename,@data,@size)
go
grant execute on storefiles to aspnet
go
create proc GetDocument
@DocID int
as
Select Headding,MimeType,FileName,Data,[size] 
from files
where Docid = @docid
go
grant execute on getdocument to aspnet

DocumentStorage.aspx
Code:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="DocumentStorage.aspx.vb" Inherits="LynchDOM.DocumentStorage"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
	<HEAD>
		<title>DocumentStorage</title>
		<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
		<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
		<meta name="vs_defaultClientScript" content="JavaScript">
		<meta name="vs_targetSchema" content="[URL unfurl="true"]http://schemas.microsoft.com/intellisense/ie5">[/URL]
	</HEAD>
	<body MS_POSITIONING="GridLayout">
		<form id="Form1" method="post" runat="server">
			<asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 80px" runat="server"
				Text="Button"></asp:Button><INPUT id="File1" style="Z-INDEX: 102; LEFT: 8px; POSITION: absolute; TOP: 48px" type="file"
				name="File1" runat="server">
		</form>
	</body>
</HTML>

DocumentStorage.aspx.vb

[red]Alter Database names to suit your server[/red]
Code:
Public Class DocumentStorage
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents Button1 As System.Web.UI.WebControls.Button
    Protected WithEvents File1 As System.Web.UI.HtmlControls.HtmlInputFile

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
    End Sub

  
    Sub ProcessFile(ByVal FILE As HttpPostedFile)

        Dim imgFull As System.Drawing.Image
        Dim imgToSave As System.Drawing.Image
        Dim length As Integer = FILE.InputStream.Length
        Dim ContentType As String = FILE.ContentType
        Dim Content As Byte()
        ReDim Content(length)
        FILE.InputStream.Read(Content, 0, length)
        UseStoreFiles(Content, "test", FILE.ContentType, FILE.FileName, length)


    End Sub

    Private Function UseStoreFiles(ByVal Data As Byte(), ByVal headding As String, ByVal MimeType As String, ByVal FileName As String, ByVal Size As Integer) As Boolean
        Dim con As New SqlClient.SqlConnection("server=(local);database=lynchdom;trusted_connection=yes")
        Dim cmd As New SqlClient.SqlCommand("StoreFiles", con)
        Dim da As New SqlClient.SqlDataAdapter(cmd)
        Dim dt As New DataTable
        With cmd
            .CommandType = CommandType.StoredProcedure
            With .Parameters
                .Add("@Data", SqlDbType.Image).Value = Data
                .Add("@headding", SqlDbType.VarChar, 300).Value = headding
                .Add("@MimeType", SqlDbType.VarChar, 300).Value = MimeType
                .Add("@Size", SqlDbType.VarChar, 300).Value = Size
                .Add("@FileName", SqlDbType.VarChar, 1000).Value = FileName
            End With
            con.Open()
            Try
                cmd.ExecuteNonQuery() ' For a stored proc with no records...
            Catch ex As Exception
                Response.Write(ex.Message)
                Return False
                Exit Function
            Finally
                con.Close()
                cmd.Dispose()
            End Try
        End With
        Return True

    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim pf As HttpPostedFile
        Dim fc As HttpFileCollection = Request.Files
        Dim i As Integer
        For i = 0 To fc.Count - 1
            pf = fc(i)
            ProcessFile(pf)
        Next
    End Sub
End Class

DisplayDocumnet.aspx

Code:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="DisplayDocumnet.aspx.vb" Inherits="LynchDOM.DisplayDocumnet"%>

DisplayDocumnet.aspx.VB
[red]Alter Database names to suit your server[/red]
Code:
Public Class DisplayDocumnet
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim fileid As Integer
        If Len(Request("FileID")) > 0 Then
            fileid = Request("fileid")
            Dim imageResponseType As String
            Dim imgfull As Drawing.Image
            Dim dt As DataTable
            dt = UseGetDocument(fileid)


            'Dim byAry() As Byte = dt.Rows(0)("Data")
            Response.ContentType = dt.Rows(0)("MimeType")
            Response.OutputStream.Write(dt.Rows(0)("data"), 0, dt.Rows(0)("Size"))
            Response.End()

        End If


        'Put user code to initialize the page here
    End Sub



    Private Function UseGetDocument(ByVal DocID As Int32) As DataTable
        Dim con As New SqlClient.SqlConnection("server=(local);database=lynchdom;trusted_connection=yes")
        Dim cmd As New SqlClient.SqlCommand("GetDocument", con)
        Dim da As New SqlClient.SqlDataAdapter(cmd)
        Dim dt As New DataTable
        With cmd
            .CommandType = CommandType.StoredProcedure
            With .Parameters
                .Add("@DocID", SqlDbType.Int, 4).Value = DocID
            End With
            con.Open()
            Try
                da.Fill(dt)
            Catch ex As Exception
                Response.Write(ex.Message)
                Return Nothing
                Exit Function
            Finally
                con.Close()
                cmd.Dispose()
            End Try
        End With
        If dt Is Nothing Then
            Return Nothing
        Else
            Return dt
        End If
    End Function

End Class


HTH


Rob
 
You know I think the whole problme is you are/were trying to return some html data with your worddoc..

The <html>
<head>
<title>Temp display</title>

and closing tags are enough to blow it all up...
The only thing you can return is the document...

Rob
 
Thanks for the feedback... I guess I won't bother waisting my time answering any more of your questions. If you can't let us know what worked and what didn't, there doesn't seem to be to much reason spending the our time to help you.

[soapbox]

booo humbug


[cannon][sleeping]

wondering why we bother [hairpull]
 
What???

I did give feedback and then this one just came through.

I just saw the post and was getting ready to try your example.

I am confused about the post on my closing tags and not sure what you meant.

Are you saying that my Document had tags in it, or was I doing the <script> in the wrong place?

Thanks,

Tom.
 
Also,

I am looking at your code now.

But here is the article I found from Microsoft KB that I looked at to solve the problem before and can't seem to find a correlation to mine, unless that "nocache line is being added that I can't see". It's KB 316431.

This is an intranet, so there is no firewall adding code. And it isn't a secure site.

Thanks,

Tom
 
I ran the Sql code with no problem.

I did have a problem running the DocumentStorage.aspx page. It gave me an error:

Code:
Compilation Error 
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 

Compiler Error Message: BC30002: Type 'HttpPostedFile' is not defined.

Source Error:

 

Line 28: 
Line 29:   
Line 30:     Sub ProcessFile(ByVal FILE As HttpPostedFile)
Line 31: 
Line 32:         Dim imgFull As System.Drawing.Image
 

Source File: C:\Inetpub\[URL unfurl="true"]wwwroot\Contour\DocumentStorage.aspx.vb[/URL]    Line: 30

I did change the "codebehind" to "src" as I am not compiling this, but running this straight.

Do I need to add an import?

Thanks,

Tom
 
Tom, sorry yesterday wasn't a very good day for me.

Re what i would possible try first
try running this altered code from your original post
Code:
<%@ Page Language="VB" ContentType="text/html" trace="true" ResponseEncoding="iso-8859-1" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="server">

    Sub Page_Load(sender as Object, e as EventArgs)

            Dim sResults As String

            Dim ConnectionString as String =System.Configuration.ConfigurationSettings.AppSettings("MM_CONNECTION_STRING_Contour_Server")
            Dim objConn as New SqlConnection (ConnectionString)
            objConn.Open()
            
            Dim CommandText as String = "select document from openworx..qadocs"
            Dim objCmd as New SqlCommand(CommandText,objConn)
            Dim objCommand as SqlCommand = new SqlCommand(CommandText, objConn)
            Dim objDataReader as SqlDataReader = objCommand.ExecuteReader( _
                CommandBehavior.CloseConnection)


        Dim arrByteData As Byte()
    
        while (objDataReader.Read() = true)
                if(objDataReader(0) is System.DBNull.value) then
                    exit while
                else
                    Response.Clear()
                    Response.AddHeader("content-disposition", "inline;filename=Stuff.doc")
                    Response.ContentType = "application/msword"
                    arrByteData = Ctype(objDataReader(0),Byte())
                     response.BinaryWrite(arrByteData)
                end if
        end while
    End Sub        
</script>
You will notice that the code is identical but I have removed the HTML tags. Because the page you are building is supposed to be a Valid Word doc the html was causing it to blow up.

Rob
 
No problem. I get those kind of days all the time. I am having one now trying to get this to work.

I am dealing with 3 different projects that need to be done yesterday (which is why it took a day or so to get back to this the other day).

I tried that and still got the same (unable to load the .aspx page).

I get the same error on both my machines at home as well as the office.

No one said it would be easy.

Thanks,

Tom
 
Can you get the ability to use codebehind pages?

re the HttpPostedFile, it is part of the System.Web Namespace [blue]System.Web.HttpPostedFile[/blue]

So I would expect that an import of System.Web should do it.

This is new teritory for me as I have always had the luxury of codebehind pages.

regarding the whole issue with the httpPostedFile. It is only necessary for storeing files that have been posted over the internet, you could also ftp files in and then open them with a streamreader.. and then stream that into the byte array, then store that to the database.

Also it shouldn't have too much impact on displaying the doc/image/pdf/xls back to the client browser. I believe you display problem all stems from sending too much back. Any unnecessary tags or attributes could cause it to be returned wrong..

Let me know how it goes..

If you want I could post a working copy of the sample above to my personal website, but I suspect the need is to get it working from the site you are hosting from.

I the old days of asp you could still do it, but you would extract a the files a different way from memory (getting fuzzy)-> but I am sure I can dig it out of an old site or some code that is probably lying around somewhere.
 
I will try both code pages and the import.

I have never set up a codebehind before, but I do have visual studio - so I should be able to figure it out.

I probably won't get to this until this weekend as I will be up all night and tomorrow, finishing up a payroll program that has to work by Monday.

Thanks,

Tom.
 
I'm trying to do the same thing. I have incorporated your code and it compiles just fine and runs fine with my DDL. It is just the DisplayDocument.aspx returns null and Page Load doesn't seemt to be firing?

Thanks,
~fit
 
Sorry. I had to pass the parameters in the URL...dohhh..


I'm using the fileid as a String...

I'm getting this error though and am not sure how to fix it.? How would I return values back any values from the database and also return the image(word doc) to the screen?


System.NullReferenceException: Object reference not set to an instance of an object.

Response.OutputStream.Write(dt.Rows(0)("ObjectBinary"), 0, dt.Rows(0)("Document"))

thanks
~fit
 
I have been trying to do the same thing. Here is what I have so far:

1. Upload a word document and save it to SQL server. I use the following code to save the document to sql server.

Code:
        private int SaveToDB(string emailTo, string emailFrom, string customerNbr, string docName, byte[] docBin, string docContentType, int docFileSize,string createUser)
        {
            //use the web.config to store the connection string
            SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["DSN"]);                      

            SqlCommand command = new SqlCommand( BuildInsertCmd(), connection );

            SqlParameter param0 = new SqlParameter( "@EmailTo", SqlDbType.VarChar,50 );
            param0.Value = emailTo;
            command.Parameters.Add( param0 );
            
            SqlParameter param1 = new SqlParameter( "@EmailFrom", SqlDbType.VarChar,50 );
            param1.Value = emailFrom;
            command.Parameters.Add( param1 );

            SqlParameter param2 = new SqlParameter( "@CustomerNumber", SqlDbType.VarChar,50 );
            param2.Value = customerNbr;
            command.Parameters.Add( param2 );

            SqlParameter param3 = new SqlParameter( "@DocName", SqlDbType.VarChar,50 );
            param3.Value = docName;
            command.Parameters.Add( param3 );

            SqlParameter param4 = new SqlParameter( "@DocData", SqlDbType.Image,50 );
            param4.Value = docBin;
            command.Parameters.Add( param4 );

            SqlParameter param5 = new SqlParameter( "@DocContentType", SqlDbType.VarChar,50 );
            param5.Value = docContentType;
            command.Parameters.Add( param5 );

            SqlParameter param6 = new SqlParameter( "@DocFileSize", SqlDbType.Int );
            param6.Value = docFileSize;
            command.Parameters.Add( param6 );

            SqlParameter param7 = new SqlParameter( "@CreateUser", SqlDbType.VarChar,50 );
            param7.Value = createUser;
            command.Parameters.Add( param7 ); 
             
            connection.Open();
            int numRowsAffected = command.ExecuteNonQuery();

            SqlCommand command2 = new SqlCommand("select max(mdr_id) from MDRData" , connection );
            int identity = (int)command2.ExecuteScalar();
            connection.Close();
            return identity;
        }
        private string BuildInsertCmd()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Insert into MDRData (\n");
            sb.Append("                      EmailTo\n");
            sb.Append("                     ,EmailFrom\n");
            sb.Append("                     ,CustomerNumber\n");
            sb.Append("                     ,DocName\n");
            sb.Append("                     ,DocData\n");
            sb.Append("                     ,DocContentType\n");
            sb.Append("                     ,DocFileSize\n");
            sb.Append("                     ,CreateUser\n)");
            sb.Append("                     Values(\n");
            sb.Append("                      @EmailTo\n");
            sb.Append("                     ,@EmailFrom\n");
            sb.Append("                     ,@CustomerNumber\n");
            sb.Append("                     ,@DocName\n");
            sb.Append("                     ,@DocData\n");
            sb.Append("                     ,@DocContentType\n");
            sb.Append("                     ,@DocFileSize\n");
            sb.Append("                     ,@CreateUser\n)");

            System.Diagnostics.Debug.WriteLine(sb.ToString());
            return sb.ToString();

        }

the table is defined as:
CREATE TABLE [dbo].[MDRData] (
	[MDR_ID] [int] IDENTITY (1, 1) NOT NULL ,
	[EmailTo] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[EmailFrom] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[CustomerNumber] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[DocName] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[DocData] [image] NULL ,
	[DocContentType] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[DocFileSize] [int] NULL ,
	[CreateUser] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[CreateDatetime] [datetime] NOT NULL ,
	[ApprovedUser] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
	[ApprovedDatetime] [datetime] NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
2. Display the word document back to the user via asp.net. I have had difficulty getting this to work. At best, the file seems to be corrupted on the trip back to the client.

This is the code to send the word doc back to the client browser;
ViewMDR.aspx
Code:
<%@ Page language="c#" Codebehind="StreamMDR.aspx.cs" AutoEventWireup="false" Inherits="MDR.StreamMDR" %>
ViewMDR.aspx.cs (Codebehind)
Code:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Configuration;
namespace MDR
{
	/// <summary>
	/// Summary description for StreamMDR.
	/// </summary>
	public class StreamMDR : System.Web.UI.Page
	{
		private void Page_Load(object sender, System.EventArgs e)
		{
            string mdrid = Request.QueryString["mdrid"];
            string sql = "select DocData, DocContentType, DocFileSize from MDRData  where MDR_ID = " + mdrid;
            SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["DSN"]);                      
            SqlCommand command = new SqlCommand(sql , connection );                
            connection.Open();
            SqlDataReader dr = command.ExecuteReader();            
            if (dr.Read())
            {
                
                //Response.Flush();
                Response.ContentType = (string)dr["DocContentType"];
                Response.OutputStream.Write((byte[]) dr["DocData"],0,(int)dr["DocFileSize"]);
            }
            connection.Close();
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.Load += new System.EventHandler(this.Page_Load);
		}
		#endregion
	}
}
when i attempt to view the document i get a dialog asking me wha to convert the document from then Word gives a error complaing about the document. I am open to suggestions if anyone has gotten this to work.

I was developing a proof of concept and i just ended up saving the word file to disk and streaming it back that way. the file saves clean so the problem must either exist in how i save to the Db or pull it from the DB.

j

j
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top