用SL4上传文件的几个问题,请教一下jv9或其他高手

蓝色_冰点 2011-04-22 10:30:07
我的要求是,用webclient上传文件,同时能够马上获得服务器上传页面输出的结果
效果就跟直接用一个web页面POST上传一个文件,然后得到上传结果一样
而服务页面就是一个普通的页面,比如一个PHP页面,可以直接通过move_uploaded_file()方法保存文件一样
我没办法用wcf之类的通信,因为服务器都是unix的,所以网上流行的东西不一定就适合我

仔细看了webclient的参考,确定如果是OpenWriteAsync的话,无法获得服务页面输出的结果
webclient提供有protected的方法,可以获得response,于是想扩展webclient。但问题来了,webclient扩展成功了,但是一但实例化webclient的子类就会发生错误即使最简单的扩展
public class MyClass:WebClient{ }
即使这样,实例化的时候也会出错。编译时,是通过的,new MyClass()就会出错

没办法从WebClient入手,于是自己写了个类,直接使用HttpWebRequest类来实现,并封装了multipart/form-data的数据格式,以及实现自定义Header,成功上传文件,并直接获取上传页面传回来的结果。就跟直接用HTML上传一样,后台通过POST接收文件,以及表单值,不需要特殊的WCF服务之类。但还是有一个问题无法解决,也就是一个HttpWebRequest无法重复使用,每次都要通过WebRequest.CreateHttp来初始化。看了参考,意思似乎又说是可以重复使用的。AJAX的xmlhttprequest就是可以重复使用的。

总结一下:
问题一:WebClient是否是可以扩展的(它不是密封类),如果可以,怎么扩展,还要加些什么东西,可以给个成功的简单例子吗?

问题二:一个HttpWebRequest实例,在完成一次请求后,是否可以重新再次发送请求?如果可以也给个例子。

问题三:WebRequest.CreateHttp和WebRequest.Create有什么区别?我试过替换,貌似都可以用。
...全文
141 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jane_sl 2011-08-01
  • 打赏
  • 举报
回复
来学习下
jv9 2011-07-27
  • 打赏
  • 举报
回复
这个问题曾经在Silverlight官网讨论过,作为异步而言,HttpWebRequest允许多次调用,但是由于服务请求格式或者数据包的问题,会造成进程堵塞而返回结果失败。在下面代码中,可以多次调用请求。
而在实际的项目中,如果异步请求较大的数据包或者集合,则会造成WCF服务超时错误。随后被一些开发人员修改为同步请求,相对而言解决了这个问题。

try
{

System.Uri uri = new Uri("http://www.google.com");
// Create a HttpWebrequest object to the desired URL.
HttpWebRequest myHttpWebRequest1= (HttpWebRequest)WebRequest.Create(uri);

// Create an instance of the RequestState and assign the previous myHttpWebRequest1
// object to it's request field.
RequestState myRequestState = new RequestState();
myRequestState.request = myHttpWebRequest1;


// Start the asynchronous request.
IAsyncResult result=
(IAsyncResult) myHttpWebRequest1.BeginGetResponse(new AsyncCallback(RespCallback),myRequestState);

allDone.WaitOne();

// Release the HttpWebResponse resource.
myRequestState.response.Close();
}
catch(WebException e)
{
outputBlock.Text += "\nException raised!\n";
outputBlock.Text += "Message: ";
outputBlock.Text += e.Message;
outputBlock.Text += "\nStatus: ";
outputBlock.Text += e.Status;
outputBlock.Text += "\n";
}
catch(Exception e)
{
outputBlock.Text += "\nException raised!\n";
outputBlock.Text += "\nMessage: ";
outputBlock.Text += e.Message;
outputBlock.Text += "\n";
}
}
private static void RespCallback(IAsyncResult asynchronousResult)
{
try
{
// State of request is asynchronous.
RequestState myRequestState=(RequestState) asynchronousResult.AsyncState;
HttpWebRequest myHttpWebRequest2=myRequestState.request;
myRequestState.response = (HttpWebResponse) myHttpWebRequest2.EndGetResponse(asynchronousResult);

// Read the response into a Stream object.
Stream responseStream = myRequestState.response.GetResponseStream();
myRequestState.streamResponse=responseStream;

// Begin the Reading of the contents of the HTML page and print it to the console.
IAsyncResult asynchronousInputRead = responseStream.BeginRead(myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
}
catch(WebException e)
{
// Need to handle the exception
}
}
private static void ReadCallBack(IAsyncResult asyncResult)
{
try
{

RequestState myRequestState = (RequestState)asyncResult.AsyncState;
Stream responseStream = myRequestState.streamResponse;
int read = responseStream.EndRead( asyncResult );
// Read the HTML page and then do something with it
if (read > 0)
{
myRequestState.requestData.Append(Encoding.UTF8.GetString(myRequestState.BufferRead, 0, read));
IAsyncResult asynchronousResult = responseStream.BeginRead( myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
}
else
{
if(myRequestState.requestData.Length>1)
{
string stringContent;
stringContent = myRequestState.requestData.ToString();
// do something with the response stream here
}

responseStream.Close();
allDone.Set();

}

}
catch(WebException e)
{
// Need to handle the exception
}

}

蓝色_冰点 2011-07-26
  • 打赏
  • 举报
回复
谢了jv9,问题一、三已经清楚了

对于问题二,还是有点疑问,为什么HttpWebRequest在异步多次调用的时候,不能获取到返回结果?不知道这算不算牛角尖,xmlhttprequest的异步请求,多次调用是可以得到结果的,这方面SL倒是不如ajax了?
jv9 2011-07-26
  • 打赏
  • 举报
回复
问题1: WebClient不是密封类允许继承,其构造函数结构如下:

public class MyWebClient : WebClient
{
[System.Security.SecuritySafeCritical]
public MyWebClient()
: base()
{
}
}


简单使用方法可以参考:

public class WebClientWithCookies : WebClient
{
private readonly CookieContainer _cookies = new CookieContainer();
public CookieContainer Cookies { get { return _cookies; } }

[SecuritySafeCritical]
public WebClientWithCookies()
: base()
{
}

protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);

if (request.GetType() == typeof(HttpWebRequest))
((HttpWebRequest)request).CookieContainer = _cookies;

return request;

}
}

WebClient的使用权限问题要求严格,所以,在测试期间,最好赋完全权限存取目录和文件。


问题2: HttpWebRequest可以多次调用,但是对于异步进程而言,多次调用没有获取到返回结果,将造成进程堵塞,降低应用效率,所以不推荐使用。


问题3: WebRequest.CreateHttp和WebRequest.Create区别,主要在于cookies的传递。使用CreateHttp创建WebRequest无法传递cookies到服务器端,详细请参考这篇教程:
http://www.silverlightchina.net/html/developer/silverlight/2011/0725/9246.html
蓝色_冰点 2011-07-22
  • 打赏
  • 举报
回复
自个顶一下。。。。。

8,738

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧