Jacky sun

Good Good Study, Day Day Up!!!

 

ASP.NET Forums 2.0 本地化修改(二)

今天我们要说的是“如何将论坛附件直接以文件形式保存,并读取照片文件的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 窗体设计器生成的代码

        
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字段,因为我们不再需要他了。
      完工!    

posted on 2004-08-07 17:29  jacky  阅读(3434)  评论(10编辑  收藏  举报

导航