在Silverlight里面调用WebServices和WCF是一件麻烦的事,在开发的时候,如果IP更改了,总是需要重配或者更新。虽然可以动态绑定,但是IP还是要配吧,而且性能比写死的要慢很多。而且,还得在根目录加上跨域XML。那么有什么解决方案呢?
比如有这么一个需求,当用户选择文件后,需要查询数据库获取是否可上传,以及上传的最大限制。由于以上原因,不愿意使用WebServices或者WCF来获取数据,于是首先想到的是写在initParams参数里面,但是不够理想,如果设置比较多,或者有更多自定义的条件的话,不太好处理。接下来就想到了利用ASP.NET里面的一般处理程序,具体操作如下:
1)在initParams配置参数“UploadHandlerName=Ajax/HttpUploadHandler.ashx”。
2)在Silverlight程序中的添加文件的方法中编写请求代码。这块值得注意的,一是路径,二是获取到数据后,要使用this.Dispatcher.BeginInvoke来更新界面(否则会出异常)。具体代码如下:
public class RequestStates { /// <summary> /// 当前请求 /// </summary> public HttpWebRequest CurrentWebRequest { get; set; } /// <summary> /// 当前用户文件 /// </summary> public UserFile CurrentUserFile { get; set; } }
private void AddFile(FileInfo file) { string fileName = file.Name; var userFile = new UserFile { FileName = file.Name, FileStream = file.OpenRead() }; if (!string.IsNullOrEmpty(Configuration.Instance.CheckExtensionsHandlerName)) { //获取处理的Handler类的路径 UriBuilder httpHandlerUrlBuilder = new UriBuilder(new CustomUri(Configuration.Instance.CheckExtensionsHandlerName)); //设置请求的参数 httpHandlerUrlBuilder.Query = string.Format("{2}file={0}&Extension={1}", HttpUtility.UrlEncode(userFile.FileName), HttpUtility.UrlEncode(Path.GetExtension(userFile.FileName)), string.IsNullOrEmpty(httpHandlerUrlBuilder.Query) ? string.Empty : httpHandlerUrlBuilder.Query.Remove(0, 1) + "&"); //创建请求 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpHandlerUrlBuilder.Uri); request.Method = "POST"; //设置自定义信息,用于异步请求 var requestStates = new RequestStates() { CurrentUserFile = userFile, CurrentWebRequest = request }; //开始异步请求 request.BeginGetRequestStream(new AsyncCallback(RequestReady), requestStates); } else { _files.Add(userFile); } }
private void RequestReady(IAsyncResult asynchronousResult) { var requestStates = (RequestStates)asynchronousResult.AsyncState; HttpWebRequest webRequest = requestStates.CurrentWebRequest; Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult); requestStream.Close(); webRequest.BeginGetResponse(new AsyncCallback(ResponseReady), requestStates); } void ResponseReady(IAsyncResult asyncResult) { var requestStates = (RequestStates)asyncResult.AsyncState; HttpWebRequest webRequest = requestStates.CurrentWebRequest; var userFile = requestStates.CurrentUserFile; var webResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult); var reader = new StreamReader(webResponse.GetResponseStream()); //获取Httphandler类返回的数据 string responsestring = reader.ReadToEnd(); reader.Close(); decimal maxSize = Convert.ToDecimal(responsestring); //Check for the file size limit (configurable) if (maxSize == 0 || (userFile.FileStream.Length / 1024) <= maxSize) { this.Dispatcher.BeginInvoke( () => _files.Add(userFile) ); } else if (maxSize < 0) { this.Dispatcher.BeginInvoke( delegate() { var messageWindow = new MessageChildWindow { Message = string.Format("不允许上传{0}类文件!", Path.GetExtension(userFile.FileName)) }; messageWindow.Show(); if (MaximumFileSizeReached != null) MaximumFileSizeReached(this, null); }); } else { this.Dispatcher.BeginInvoke( () => { var messageWindow = new MessageChildWindow { Message = string.Format("{0}{1}{2}KB.", Path.GetExtension(userFile.FileName), UserMessages.MaxFileSize, (maxSize).ToString()) }; messageWindow.Show(); if (MaximumFileSizeReached != null) MaximumFileSizeReached(this, null); }); } }
效果如下: