随笔-127  评论-2647  文章-26  trackbacks-67
     在之前的一篇文章中,谈到了使用文件对话框选取并预览本地文件。当时就有一个想法,将这个
DEMO扩展成为支持图片上传。所以今天本文会以上个DEMO中的部分代码为原型,在其基础上稍加
变动,使其支持图片上传功能。如下图所示:

 

     首先,我们需要建立一个silverlight application ,名称为:UploadFileWeb
   
     然后在该WEB项目中新建一个Generic Handler,名称为:Handler.ashx
   
     下面就是它的代码:
   
using System;
using System.Web;
using System.IO;

public class Handler : System.Web.IHttpHandler {

    
public void ProcessRequest (HttpContext context)
    {    
//获取上传的数据流
         Stream sr = context.Request.InputStream;
         
try
         {
            
//生成随机的文件名(本DEMO中的上传图片名称也可用参数方法传递过来)
            string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            Random rnd 
= new Random();
            
string filename = "";
            
for (int i = 1; i <= 32; i++)
            {
                filename 
+= chars.Substring(rnd.Next(chars.Length), 1);
            }
           
            
byte[] buffer = new byte[4096];
            
int bytesRead = 0;
            
//将当前数据流写入服务器端文件夹ClientBin下
            using (FileStream fs = File.Create(context.Server.MapPath("ClientBin/" + filename + ".jpg"), 4096))
            {
                
while ((bytesRead = sr.Read(buffer, 0, buffer.Length)) > 0)
                {
                    
//向文件中写信息
                    fs.Write(buffer, 0, bytesRead);
                }
            }
           
            context.Response.ContentType 
= "text/plain";
            context.Response.Write(
"上传成功");
         }
         
catch (Exception e)
         {
            context.Response.ContentType 
= "text/plain";
            context.Response.Write(
"上传失败, 错误信息:" + e.Message);
         }
         
finally
         {
             sr.Dispose();
         }
        
    }
  
    
public bool IsReusable {
    
get {
            
return false;
        }
    } 
}

     因为要加入上传图片按钮,所以将page.xaml内容修改如下:
   
<Grid x:Name="LayoutRoot" Background="Black" ShowGridLines="False" Margin="8">
        
<Grid.ColumnDefinitions>
            
<ColumnDefinition Width="196" />
            
<ColumnDefinition Width="*" />
        
</Grid.ColumnDefinitions>
        
<Grid.RowDefinitions>
            
<RowDefinition Height="*" />
            
<RowDefinition Height="48" />
        
</Grid.RowDefinitions>
        
<ListBox  x:Name="myList" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
              ItemsSource
="{Binding}"
              Grid.Row
="0"
              Grid.Column
="0"
              Grid.RowSpan
="2"
              SelectionChanged
="OnSelectionChanged" >
            
<ListBox.ItemTemplate>
                
<DataTemplate>
                    
<TextBlock Text="{Binding Name}" />
            
</DataTemplate>
            
</ListBox.ItemTemplate>
        
</ListBox>
        
<my:GridSplitter Width="1" HorizontalAlignment="Left" VerticalAlignment="Stretch" Grid.Column="1"></my:GridSplitter>

        
<Image  x:Name="myImage" Grid.Column="1" />
        
<StackPanel Grid.Row="1" Background="white" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Stretch">
        
<Button Grid.Row="1"
          Grid.Column
="0"
          Content
="选择图片"
          Margin
="8" Click="OnClick" FontSize="16"  Width="100"/>
        
<Button Grid.Row="1"
          Grid.Column
="2"
          Content
="上传该图片"
          Margin
="8" Click="OnUpLoadClick" FontSize="16" Width="100"/>
        
</StackPanel>  
</Grid>


     而相应的page.xmal.cs代码也做了修改(相关内容见注释):
    
public partial class Page : UserControl
{       
    
public Page()
    {
        InitializeComponent();
    }

    
void OnClick(object sender, EventArgs args)
    {
        OpenFileDialog openFileDialog 
= new OpenFileDialog()
        {
            Filter 
= "Jpeg Files (*.jpg)|*.jpg|All Files(*.*)|*.*",
            Multiselect 
= true
        };

        
if (openFileDialog.ShowDialog() == true)//.DialogResult.OK)
        {
            myList.DataContext 
= openFileDialog.SelectedFiles;
        }
    }

    
void OnUpLoadClick(object sender, EventArgs args)
    {
        
if (fi != null)
        {
            WebClient webclient 
= new WebClient();
           
            webclient.OpenWriteCompleted 
+= new OpenWriteCompletedEventHandler(webclient_OpenWriteCompleted);
            webclient.OpenWriteAsync(
new Uri("http://localhost:5840/UploadFileWeb/Handler.ashx", UriKind.Absolute), "POST", fi.OpenRead());
        }
        
else
        {
            HtmlPage.Window.Alert(
"请选取相应图片!!!");
        }
    }

    
void webclient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
    {
        
//将图片数据流发送到服务器上
        Stream inputStream = e.UserState as Stream;
        Stream outputStream 
= e.Result;

        
byte[] buffer = new byte[4096];
        
int bytesRead = 0;

        
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            outputStream.Write(buffer, 
0, bytesRead);
        }
        outputStream.Close();
        inputStream.Close(); HtmlPage.Window.Alert(
"图片上传成功!!!");
    }

 
    FileDialogFileInfo fi ;
//获取选定图片信息
   
    
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        
if ((e.AddedItems != null&& (e.AddedItems.Count > 0))
        {
            fi 
= e.AddedItems[0as FileDialogFileInfo;
          
            
if (fi != null)
            {
                
using (Stream stream = fi.OpenRead())
                {
                    BitmapImage image 
= new BitmapImage();
                    image.SetSource(stream);
                    myImage.Source 
= image;
                    myImage.Visibility 
= Visibility.Visible;
                    stream.Close();
                }
            }
        }
    }

}

    好了,今天的内容就到这里了。
   
    源码下载链接,请点击这里:)  
   
    TAG: silverlight, upload image, 上传, daizhj,代震军
posted on 2008-06-16 09:37 代震军 阅读(2257) 评论(23)  编辑 收藏 所属分类: silverlight

评论:
#1楼  2008-06-16 10:11 | Faster [未注册用户]
这不是和aspx传文件差不多?
如果分段调用wcf来传输,就能很好的支持 断点续传合进度条了
  回复  引用    
#2楼  2008-06-16 10:13 | Ants      
很强
  回复  引用  查看    
#3楼 [楼主] 2008-06-16 10:24 | 代震军      
@Faster
的确是这样,开发出这个功能也是大家所希望的:)
  回复  引用  查看    
#4楼  2008-06-16 11:43 | 平静中的疯狂      
--引用--------------------------------------------------
代震军: @Faster
的确是这样,开发出这个功能也是大家所希望的:)
--------------------------------------------------------
这个功能强,力顶
  回复  引用  查看    
#5楼  2008-06-16 11:46 | 李永京      
这文章是代码型的了,加上解释就挺好了,例如上传的原理,为什么这么做.....
  回复  引用  查看    
#6楼  2008-06-16 11:50 | dada7357      
想问一吓,在Beta 2 中,不是有Isolated Storage,为什么不用,而用FileStream fs = File.Create(context.Server.MapPath("ClientBin/" + filename + ".jpg")。
  回复  引用  查看    
#7楼  2008-06-16 11:55 | Gray Zhang      
Isolated Storage是在客户端的,这里的路径是服务器端的存放路径
  回复  引用  查看    
#8楼 [楼主] 2008-06-16 12:13 | 代震军      
@李永京
@平静中的疯狂
谢谢关注:)
  回复  引用  查看    
#9楼  2008-06-16 13:01 | Windie Chai(笑煞天)      
可以直接写一个SL的支持缩略图的多文件上传控件!
  回复  引用  查看    
#10楼 [楼主] 2008-06-16 13:38 | 代震军      
@Windie Chai(笑煞天)
:)
  回复  引用  查看    
#11楼  2008-06-17 02:51 | 编织套管 [未注册用户]
一个敷换楬湥�的问题。
  回复  引用    
#12楼  2008-07-08 14:37 | 张晓飞2008 [未注册用户]
我想知道图片上传到哪里了
  回复  引用    
#13楼 [楼主] 2008-07-08 15:27 | 代震军      
@张晓飞2008
代码中有这样一行context.Server.MapPath("ClientBin/" + filename + ".jpg")
它会传到ClientBin/目录下:)
  回复  引用  查看    
#14楼  2008-07-09 10:59 | 张晓飞2008 [未注册用户]
我按照你的代码在我电脑上运行,是不正确的。你能把源代码发到我邮箱里面吗?谢谢。我想把照片保存到image的文件夹下。怎么修改、
  回复  引用    
#15楼  2008-07-09 11:14 | 张晓飞2008 [未注册用户]
上面说错了。我是说我下载你的源码,在我机器上环境是beta2。运行下载你的代码。"图片上传成功!!!,可是我在ClientBin/目录下:)
找不到我上传的图片。
  回复  引用    
#16楼  2008-07-09 18:35 | 郑州-袁金辉      
listbox在绑定数据的 时候能触发什么事件吗?

我想在listbox中显示以后所选择的那个照片,请问该如何去做
  回复  引用  查看    
#17楼  2008-07-13 19:04 | leanco      
很感谢楼主的这篇文章,不过我在创建网站时用的位置是“http”,而不是"文件系统"就会报System.Security.SecurityException的异常,不知道楼主试过这样的创建没有。怎么解决?希望楼主赐教!先谢谢啦……
  回复  引用  查看    
#18楼 [楼主] 2008-07-14 10:12 | 代震军      
@leanco
这个我倒没试过,有时间看一下:)
不知道是不是域策略的问题
  回复  引用  查看    
#19楼  2008-07-15 16:18 | leanco      
@代震军
嗯,谢谢。
我试了一下,应该是权限问题。创建网站时如果是位置是"系统文件",权限要比是“http”大一些,所以"http"的就出现问题。但是我用系统XP就是好的,用系统windows 2003就出现异常。我想可能windows 2003 默认的权限配置和xp不一样吧,唉……搞不清具体是哪里的权限,IIS我都设过还是没用,还有待楼主有时间看一下了,呵呵……
  回复  引用  查看    
#20楼  2008-07-27 12:50 | liti [未注册用户]
我也是beta2版本,但为什么我的命名空间里找不到System.Web???谢谢
  回复  引用    
#21楼 [楼主] 2008-07-28 09:54 | 代震军      
@liti
先在引用中加入对system.web的引用
  回复  引用  查看    
#22楼  2008-09-03 00:18 | BlueWhale [未注册用户]
请教:SilverLight2 beta2 的WebRequest不支持Delete和Put方法吗?
运行如下代码:

Uri uri = new Uri("http://localhost:3000/people/1");
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
// 设置请求类型为Delete,不支持该方法???
request.Method = "DELETE";//运行到这里报不支持该方法,get和post可以
。。。
  回复  引用    
#23楼 [楼主] 2008-09-03 10:16 | 代震军      
@BlueWhale
这块我没太仔细研究过,不太好说:)
  回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-06-26 16:07 编辑过


相关链接: