您的位置:首页 > 编程语言 > ASP

ASP.NET Forums 2.0 修改集锦(二)

2004-08-30 14:47 609 查看
今天我们要说的是“如何将论坛附件直接以文件形式保存,并读取照片文件的Exif信息;”

废话少说,直接进入主题:


      准备工作:下载PhotoProperties类库,用于读取Exif信息,在Components中引用该类库

1、修改web.config配置文件,在forums/forums下增加一个配置项
      uploadFilesPath="/Upload/"
      值可以自行修改,用来保存用户上传的文件;

2、修改数据库
      forums_PostAttachments表增加如下字段
      DiskFileName nvarchar(256),  保存附件在硬盘上的文件名
      Exif  nvarchar(200),    用于保存照片附件的Exif信息
      CheckGuid nvarchar(50)     用于保存检测的Guid
      注意:我们修改的最终方案是会删除原有的Content字段的

      修改存储过程:


create procedure forums_PostAttachment_Add 


(


    @PostID int,


    @UserID int,


    @ForumID int,


    @Filename nvarchar(256),


    @DiskFileName nvarchar(256),


    @ContentType nvarchar(50),


    @ContentSize int,


    @Exif nvarchar(500),


    @CheckGuid nvarchar(50)


)


AS


BEGIN




    IF EXISTS (SELECT PostID FROM forums_PostAttachments WHERE PostID = @PostID)


        RETURN




    INSERT INTO 


        forums_PostAttachments


    (


        PostID,


        ForumID,


        UserID,


        [FileName],


        DiskFileName,


        ContentType,


        ContentSize,


        Exif,


        CheckGuid


    )


    VALUES


    (


        @PostID,


        @ForumID,


        @UserID,


        @Filename,


        @DiskFileName,


        @ContentType,


        @ContentSize,


        @Exif,


        @CheckGuid


    )




END






GO


SET QUOTED_IDENTIFIER OFF 


GO


SET ANSI_NULLS ON 


GO




SET QUOTED_IDENTIFIER ON 


GO


SET ANSI_NULLS ON 


GO

     
3、修改系统配置管理类Components项目下的Configuration/ForumConfiguration.cs文件:
      1)在头部增加一变量


string uploadFilesPath="/Upload/";       2)在LoadValuesFromConfigurationXml方法里增加以下代码,读取配置文件中的值:


uploadFilesPath = attributeCollection["uploadFilesPath"].Value;      3)给ForumConfiguration类增加UploadFilesPath属性:




 public string UploadFilesPath { get { return uploadFilesPath; } }


      配置文件部分完成。

4、修改Components项目下的PostAttachment类
      增加如下引用:


using System.IO;


using JSG.PhotoPropertiesLibrary;
      增加如下变量:     


string exif;


string diskFileName;        


string checkGuid;     
     增加如下方法:




/**//// <summary>


        /// 获取文件的Exif信息


        /// </summary>


        /// <param name="postedFile"></param>


        /// <returns></returns>


        private string GetExif(string ContentType,string FullFileName) 




        

{


            

            


            string imgFilePath = FullFileName;


            string exif="";


            


            try




            

{


                PhotoProperties pp = new PhotoProperties();




                pp.Initialize();


                pp.Analyze(imgFilePath);


                        


                if(ContentType.ToLower() == "image/pjpeg")




                

{


                    //Exif Version


                    exif += "Exif版本:" +  pp.GetTagDatum(36864).PrettyPrintValue;




                    //制造商


                    exif += " 制造商:" + pp.GetTagDatum(271).PrettyPrintValue;




                    //型号


                    exif += " 型号:" + pp.GetTagDatum(272).PrettyPrintValue;




                    //拍摄时间


                    exif += " 拍摄时间:" + pp.GetTagDatum(36868).PrettyPrintValue;




                    //暴光时间:


                    exif += "<BR>暴光时间:" +  pp.GetTagDatum(33434).PrettyPrintValue + "秒";




                    //光圈


                    exif += " 光圈:" + pp.GetTagDatum(33437).PrettyPrintValue;




                    //ISO


                    exif += "  ISO:" + pp.GetTagDatum(34855).PrettyPrintValue;




                    //分辨率


                    exif += " 分辨率:" +  pp.GetTagDatum(282).PrettyPrintValue + "/" +  pp.GetTagDatum(283).PrettyPrintValue;


                }


            }




            catch

{}




            return exif;


        }       在构造函数的最下面增加:


string uploadPath = HttpContext.Current.Server.MapPath("~" + AspNetForums.Configuration.ForumConfiguration.GetConfig().UploadFilesPath);


            uploadPath += "/" + Users.GetUser().UserID.ToString() + "/";


            if(!System.IO.Directory.Exists(uploadPath))




            

{


                System.IO.Directory.CreateDirectory(uploadPath);


            }


        


            //HttpContext.Current.User.Identity


            


            diskFileName =  System.Guid.NewGuid().ToString() + System.IO.Path.GetExtension(postedFile.FileName);


            uploadPath += diskFileName;


            


            postedFile.SaveAs(uploadPath);
exif = GetExif(contentType,uploadPath);


checkGuid = System.Guid.NewGuid().ToString();      
      最后增加3个属性,代码如下:




        /**//// <summary>


        /// 磁盘文件名(文件保存在硬盘上的物理文件名)


        /// 37AE8655-05F8-4ed9-A771-35B41F0222DE.ext


        /// </summary>


        public string DiskFileName




        

{


            get




            

{


                return diskFileName;


            }


            set




            

{


                diskFileName = value;


            }


        }






        /**//// <summary>


        /// 照片Exif信息


        /// </summary>


        public string Exif 




        

{


            get 




            

{


                return exif;


            }


            set 




            

{


                exif = value;


            }


        }






        /**//// <summary>


        /// 用于判断是否要以attachment形式让用户下载附件


        /// </summary>


        public string CheckGuid




        

{


            get




            

{


                return checkGuid;


            }


            set




            

{


                checkGuid = value;


            }


        }
5、下面要修改的是负责系统数据库操作的SqlDataProvider项目,用于完成对新增加字段的数据库操作,修改如下:
    找到public override void AddPostAttachment(Post post, PostAttachment attachment)方法:


//增加DiskFileName字段,用于附件在硬盘上的保存文件名,


//类似1990ffb3-3992-4438-b7e2-2bca963d969f.jpg


//该文件名不暴露给最终用户


myCommand.Parameters.Add("@DiskFileName", SqlDbType.NVarChar, 256).Value = attachment.DiskFileName;


//注释掉对Content的操作


//myCommand.Parameters.Add("@Content", SqlDbType.Image).Value = attachment.Content;




//增加照片Exif信息与用于验证的CheckGuid字段


myCommand.Parameters.Add("@Exif",SqlDbType.NVarChar,500).Value = attachment.Exif;


myCommand.Parameters.Add("@CheckGuid",SqlDbType.NVarChar,500).Value = attachment.CheckGuid;     注意:这里需要注释掉对Content字段的操作,因为虽然数据字段还在,但上面修改的存储过程中,我们已经删除了对Content字段的操作;

6、修改Components项目下的ForumsDataProvider类中的PopulatePostAttachmentFromIReader方法,完成从数据库到对象的转换,修改如下:


//删除Content字段,附件内容不再保存到数据库,而是直接以文件形式保存到硬盘


// attachment.Content      = (byte[]) reader["Content"];




//增加DiskFileName字段,用于附件在硬盘上的保存文件名,


//类似1990ffb3-3992-4438-b7e2-2bca963d969f.jpg


//该文件名不暴露给最终用户


attachment.DiskFileName = (string) reader["DiskFileName"].ToString();




//增加照片Exif信息与用于验证的CheckGuid字段


if(reader["Exif"] != DBNull.Value)






{


    attachment.Exif        = (string) reader["Exif"];


}


attachment.CheckGuid    = (string) reader["CheckGuid"].ToString();

7、到此数据的操作部分已经都完成了,下面要做的就是修改显示部分,系统最终显示帖子内容是通过Controls下的TextPost类完成的,我们要修改的代码当然也在这里了。
      找到InitializeSkin方法中的body.Text = post.FormattedBody;,在他下面增加如下代码:


            //判断附件的mime类型是否为图片,如果为图片,那么直接调用DisplayImage方法生成显示图片的HTML代码


            //此处可扩充直接显示附件为Flash等其他类型的文件


            string Attachment=post.AttachmentFilename;


            if (Attachment!="" && Attachment!=null)




            

{


                AspNetForums.Components.PostAttachment attachment = Posts.GetAttachment(post.PostID);


                string contentType = attachment.ContentType;


                if (contentType=="image/pjpeg" 


                    || contentType=="image/gif"


                    || contentType=="image/bmp" 


                    || contentType=="image/x-png" )




                

{


                    


                    body.Text += DisplayImage(Globals.GetSiteUrls().PostAttachment(post.PostID) + "&guid=" + attachment.CheckGuid);  

        


                


                    //显示Exif信息


                    if(attachment.Exif.Length>0)


                    {


                        body.Text += "<span class=exif>" + attachment.Exif + "</span>";


                    }


                }


            }      DisplayImage方法很简单,代码如下,自己可以修改该代码,给图片增加边框等




/**//// <summary>


/// 如果附件为图片类型,那么调用该方法,生成显示图片的HTML代码


/// </summary>


/// <param name="ImageFilePath">要显示的图片路径</param>


/// <returns></returns>


public string DisplayImage(string ImageFilePath)




    

{


                return "<a href='" + ImageFilePath + "' target='_blank'><img  src="" + ImageFilePath + "" border=0></a>";


        }
8、修改附件下载部分,Controls项目下的DownloadPostAttachment类,代码如下:
 


            System.Web.HttpContext.Current.Response.Clear();


            System.Web.HttpContext.Current.Response.ContentType = attachment.ContentType;


            




            //判断用户从QueryString提交的Guid值是否和数据库的CheckGuid是否相同


            //如果相同,那么不以attachment的形式输出,直接显示文件(通常提供该Guid值的情况都是为图片附件)


            //如果不同,那么以attachment形式输出,直接由用户下载


            if(forumContext.CheckGuid != attachment.CheckGuid)




            

{


                System.Web.HttpContext.Current.Response.AppendHeader("content-disposition", "attachment; filename="" + System.Web.HttpUtility.UrlEncode(attachment.FileName,System.Text.Encoding.UTF8) + """);


            }




            //System.Web.HttpContext.Current.Response.OutputStream.Write(attachment.Content, 0, attachment.Length);


                        


            string diskFileName = System.Web.HttpContext.Current.Server.MapPath("~/" + AspNetForums.Configuration.ForumConfiguration.GetConfig().UploadFilesPath + "/" + attachment.UserID.ToString() + "/" + attachment.DiskFileName);


            System.Web.HttpContext.Current.Response.WriteFile(diskFileName);


            System.Web.HttpContext.Current.Response.End();

9、最后要修改的是ForumContext类,要对该类增加一个属性,用于读取通过QueryString传递的Guid值,找到Components项目下的ForumContext类,
      首先增加一变量:


string checkGuid =  "";     在构造函数的最下面增加:


checkGuid = context.Request.QueryString["guid"];     在最下面增加属性:


//CheckGuid 判断是否合法的显示文件请求




public string CheckGuid 

{ get 

{ return checkGuid; } }

至此,我们的修改工作已经全部完成,下面要做的就是对原有的数据库进行升级,将Content字段中的数据保存到硬盘,下面的代码比较简单了,直接贴出代码


在web项目下增加一个页面,后台的操作代码如下,代码比较简单,都是直接操作数据库的。不要忘记增加对PhotoProperties的引用,


using System;


using System.Collections;


using System.ComponentModel;


using System.Data;


using System.Data.SqlClient;


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.IO;


using JSG.PhotoPropertiesLibrary;




namespace AspNetForums.Update






{




    /**//// <summary>


    /// update_20040807 的摘要说明。


    /// </summary>


    public class update_20040807 : System.Web.UI.Page




    

{


        protected System.Web.UI.WebControls.Button Button1;


    


        private void Page_Load(object sender, System.EventArgs e)




        

{


            // 在此处放置用户代码以初始化页面


        }






        Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码


        override protected void OnInit(EventArgs e)




        

{


            //


            // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。


            //


            InitializeComponent();


            base.OnInit(e);


        }


        




        /**//// <summary>


        /// 设计器支持所需的方法 - 不要使用代码编辑器修改


        /// 此方法的内容。


        /// </summary>


        private void InitializeComponent()




        

{    


            this.Button1.Click += new System.EventHandler(this.Button1_Click);


            this.Load += new System.EventHandler(this.Page_Load);




        }


        #endregion




        private void Button1_Click(object sender, System.EventArgs e)




        

{


            


            string ConnectionString = "database=forums;server=dbserver;User ID=sa;Password=;";




            SqlConnection myConn = new SqlConnection(ConnectionString);


            myConn.Open();




            


            


            string select="select * from forums_PostAttachments";


            SqlCommand myComm = new SqlCommand(select,myConn);




            SqlDataReader dr = myComm.ExecuteReader();


            string DiskFileName,CheckGuid,Exif;


            string UpdateString="Update forums_PostAttachments SET DiskFileName='{0}',Exif='{1}',CheckGuid='{2}' where PostID={3}";


            string UserID;


            byte[] fileContent;


            FileStream fs=null;
















            SqlConnection myConn2 = new SqlConnection(ConnectionString);


            myConn2.Open();








            while(dr.Read())




            

{


                UserID=dr["UserID"].ToString();


                fileContent = (byte[])dr["Content"];


                DiskFileName = Server.MapPath("~/" + AspNetForums.Configuration.ForumConfiguration.GetConfig().UploadFilesPath + "/" + UserID + "/" + System.Guid.NewGuid().ToString()) + System.IO.Path.GetExtension(dr["FileName"].ToString());


                


                CheckGuid = System.Guid.NewGuid().ToString();




                fs=new FileStream(DiskFileName ,FileMode.Create,FileAccess.Write, FileShare.ReadWrite);


                fs.Write(fileContent,0,fileContent.Length);


                fs.Close();


                Exif = GetExif(DiskFileName);




                SqlCommand myComm2 = new SqlCommand(string.Format(UpdateString,System.IO.Path.GetFileName(DiskFileName),Exif,CheckGuid,dr["PostID"].ToString()),myConn2);


                myComm2.ExecuteNonQuery();


                


            }


            dr.Close();        


        }






        private string GetExif(string diskFileName) 




        

{


            


            string imgFilePath = diskFileName;


            PhotoProperties pp = new PhotoProperties();




            string exif="";


            try




            

{


                pp.Initialize();


                pp.Analyze(imgFilePath);


            


                //Exif Version


                exif += "Exif版本:" +  pp.GetTagDatum(36864).PrettyPrintValue;




                //制造商


                exif += " 制造商:" + pp.GetTagDatum(271).PrettyPrintValue;




                //型号


                exif += " 型号:" + pp.GetTagDatum(272).PrettyPrintValue;




                //拍摄时间


                exif += " 拍摄时间:" + pp.GetTagDatum(36868).PrettyPrintValue;






                //暴光时间:


                exif += "<BR>暴光时间:" +  pp.GetTagDatum(33434).PrettyPrintValue + "秒";




                //光圈


                exif += " 光圈:" + pp.GetTagDatum(33437).PrettyPrintValue;




                //ISO


                exif += "  ISO:" + pp.GetTagDatum(34855).PrettyPrintValue;




                //分辨率


                exif += " 分辨率:" +  pp.GetTagDatum(282).PrettyPrintValue + "/" +  pp.GetTagDatum(283).PrettyPrintValue;


            }




            catch

{}




            return exif;


        }


    }


}



      别忘了最后一步工作,删除forums_PostAttachments表中的Content字段,因为我们不再需要他了。
      完工!    


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息