今天做程序的時候,因為要用SqlDatasource綁定存儲過程來實現添加數據。這個控件用過不下100遍了,今天才發現Image類型字段需要特別處理。
SqlDataSource控件如果是通過向導來做的話,會自動生成如下代碼:
<asp:SqlDataSource ID="studentDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:StdITBaseOAConnectionString %>" SelectCommand="SELECT Student.* FROM Student" InsertCommand="spStudentRecordAdd" InsertCommandType="StoredProcedure" > <InsertParameters> <asp:Parameter Name="StudentName" Type="String" /> <asp:Parameter Name="StudentID" Type="Int32" /> <asp:Parameter Name="Photo" Type="Object" /> </InsertParameters> </asp:SqlDataSource>
運行時會出現“sql_variant類型不能轉換為Image類型的異常”,一看就是類型不匹配的異常,可惜的是Parameter 沒有Image類型。這時,請手工去掉這行:
<asp:Parameter Name="Photo" Type="Object" />
在此,這個Type="Object"將會產生一個sql_variant類型的參數。然而,該sql_variants類型不能用來存儲圖像或varbinary(MAX)數據類型,因為該sql_variant的內在數據大小不能超過8,000個字節。(如果你試圖使用 Type="Object",然後試圖保存超過8,000字節大小的二進制數據,那麼,系統將拋出一個異常並顯示消息"Parameter '@ImageData' exceeds the size limit for the sql_variant datatype";如果你試圖添加不到8,000字節大小的二進制數據,那麼,該異常將顯示消息"Implicit conversion from data type sql_variant to varbinary(max) is not allowed")。
當然,我們肯定不能不管這個字段,下面是我試驗成功的一種做法,僅供有同樣疑惑的同學參考:
protected void studentDataSource_Inserting(object sender, SqlDataSourceCommandEventArgs e) { FileUpload fu = FormView1.FindControl("FileUpload1") as FileUpload; byte[] imageData = new byte[0]; if (fu != null && fu.HasFile) { imageData = fu.FileBytes; } System.Data.SqlClient.SqlParameter uploadData = new System.Data.SqlClient.SqlParameter("@Photo", System.Data.SqlDbType.Image); uploadData.Value = imageData; e.Command.Parameters.Add(uploadData); }
代碼中使用了FormView控件,同學組要根據實際情況來理解。這段代碼裡最核心的部分是構建一個SqlParameter,對應Photo,並加到Insert Command中。
另外上面的studentDataSource_Inserting方法是SqlDataSource控件的Inserting事件的實現。一開始我用FormView的Inserting事件,發現那裡面無法得到Command對象,只能對參數的DefaultValue進行賦值。所以才想到了SqlDataSource
問題雖然解決了,但是我還是建議不要將圖片保存到數據庫字段中。另外,可能還有其它的方法吧,歡迎各位討論。
本文出自 “王傑瑞的技術博客” 博客,請務必保留此出處http://wangjierui.blog.51cto.com/186879/109595