Files
FileServices/Html5Uploader/Controls/Html5UploaderClient.cs
2019-08-19 19:00:14 +08:00

411 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Helper;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.HtmlControls;
namespace Html5Uploader.Controls
{
[ParseChildren(true)]
[PersistChildren(false)]
[ToolboxData("<{0}:Html5UploaderClient runat=server></{0}:Html5UploaderClient>")]
public class Html5UploaderClient : Control, INamingContainer
{
Dictionary<SettingsNames, object> settings;
public Html5UploaderClient()
{
settings = new Dictionary<SettingsNames, object>();
RegisterScript = true;
}
private ITemplate _viewTemplate;
[DefaultValue("视图模板")]
[TemplateContainer(typeof(ViewTemplate))]
[PersistenceMode(PersistenceMode.InnerProperty)]
[Browsable(false)]
public ITemplate ViewTemplate
{
get { return _viewTemplate; }
set { _viewTemplate = value; }
}
[Description("客户端事件")]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ClientEventsCollection ClientEvents
{ get; set; }
[Description("随文件一起提交的参数列表")]
[PersistenceMode(PersistenceMode.InnerProperty)]
public PostParametersCollection PostParameters
{ get; set; }
[Description("服务端处理程序")]
[UrlProperty]
public string Url
{
get
{
return settings.ContainsKey(SettingsNames.url) ? settings[SettingsNames.url] as string : null;
}
set
{
settings[SettingsNames.url] = value;
}
}
string _token;
public string Token {
get { return _token; }
set {
if (value == null || value.Length <= 50)
{ _token = value; }
else { throw new Exception("Token的长度不能超过50个字符。"); }
}
}
public string Placeholder
{
get
{
return settings.ContainsKey(SettingsNames.placeholder) ? settings[SettingsNames.placeholder] as string : null;
}
set
{
settings[SettingsNames.placeholder] = value;
}
}
public bool Multiple
{
get
{
return settings.ContainsKey(SettingsNames.multiple) ? (bool)settings[SettingsNames.multiple] : true;
}
set
{
settings[SettingsNames.multiple] = value;
}
}
public string Accept
{
get
{
return settings.ContainsKey(SettingsNames.accept) ? settings[SettingsNames.accept] as string : null;
}
set
{
settings[SettingsNames.accept] = value;
}
}
public string Types
{
get
{
return settings.ContainsKey(SettingsNames.types) ? settings[SettingsNames.types] as string : null;
}
set
{
settings[SettingsNames.types] = value;
}
}
public string Timeout
{
get
{
return settings.ContainsKey(SettingsNames.timeout) ? settings[SettingsNames.timeout] as string : null;
}
set
{
settings[SettingsNames.timeout] = value;
}
}
public int MaxQueue
{
get
{
return settings.ContainsKey(SettingsNames.maxQueue) ? (int)settings[SettingsNames.maxQueue] : 2;
}
set
{
settings[SettingsNames.maxQueue] = value;
}
}
public bool Dragable
{
get
{
return settings.ContainsKey(SettingsNames.dragable) ? (bool)settings[SettingsNames.dragable] : true;
}
set
{
settings[SettingsNames.dragable] = value;
}
}
public string DragContainer
{
get
{
return settings.ContainsKey(SettingsNames.dragContainer) ? settings[SettingsNames.dragContainer] as string : null;
}
set
{
settings[SettingsNames.dragContainer] = value;
}
}
public string Progress
{
get
{
return settings.ContainsKey(SettingsNames.progress) ? settings[SettingsNames.progress] as string : null;
}
set
{
settings[SettingsNames.progress] = value;
}
}
public string BlobSize
{
get
{
return settings.ContainsKey(SettingsNames.blobSize) ? settings[SettingsNames.blobSize] as string : null;
}
set
{
settings[SettingsNames.blobSize] = value;
}
}
public UploaderSliceds Sliced
{
get
{
return settings.ContainsKey(SettingsNames.sliced) ? (UploaderSliceds)settings[SettingsNames.sliced] : UploaderSliceds.Auto;
}
set
{
settings[SettingsNames.sliced] = value;
}
}
public string LimitSize
{
get
{
return settings.ContainsKey(SettingsNames.limitSize) ? settings[SettingsNames.limitSize] as string : null;
}
set
{
settings[SettingsNames.limitSize] = value;
}
}
public string ParseResult
{
get
{
return settings.ContainsKey(SettingsNames.parseResult) ? settings[SettingsNames.parseResult] as string : null;
}
set
{
settings[SettingsNames.parseResult] = value;
}
}
public bool RegisterScript { get; set; }
int ParseTimeout(string v)
{
string[] units = new string[] { "ms", "ss", "mm", "hh" };
Func<string, int> fn = u =>
{
for (int i = 0; i < units.Length; i++) { if (units[i] == u)return i; }
return 0;
};
Regex rgx = new Regex(@"^\s*(\d+)\s*(ms|(ss)|(mm)|(hh))?\s*$", RegexOptions.IgnoreCase);
var m = rgx.Match(v);
if (m == null || !m.Success)
{ throw new ArgumentException("“" + v + "”无效的表达式,如二十四小时“24hh”的格式"); }
int time;
int.TryParse(m.Groups[1].Value, out time);
int index = fn(m.Groups[2].Success ? m.Groups[2].Value.ToLower() : "ss");
while (index-- > 0)
{
time *= (index == 1 ? 1000 : 60);
}
return time;
}
long ParseSize(string v)
{
string[] units = new string[] { "B", "KB", "MB", "GB", "TB" };
Func<string, int> fn = u =>
{
for (int i = 0; i < units.Length; i++) { if (units[i] == u)return i; }
return 0;
};
Regex rgx = new Regex(@"^\s*(\d+)\s*(B|(KB)|(MB)|(GB)|(TB))?\s*$", RegexOptions.IgnoreCase);
var m = rgx.Match(v);
if (m == null || !m.Success)
{ throw new ArgumentException("“"+v+"”无效的表达式请参照“232MB”的格式"); }
long size;
long.TryParse(m.Groups[1].Value, out size);
int index = fn(m.Groups[2].Success ? m.Groups[2].Value.ToUpper() : "MB");
while (index-- > 0)
{
size *= 1024;
}
return size;
}
string ParseSetting(SettingsNames key,object v)
{
if (!settings.ContainsKey(key)) return null;
string s;
long size;
switch (key)
{
case SettingsNames.url:
s= v as string;
if (!string.IsNullOrWhiteSpace(s))
{ s = "\"" + ConvertHelper.ConvertToClientString(ResolveUrl(s)) + "\""; }
return s;
case SettingsNames.maxQueue:
return v == null ? null : v.ToString();
case SettingsNames.blobSize:
size = ParseSize(v as string);
long max=(((HttpRuntimeSection)WebConfigurationManager.OpenWebConfiguration("/").GetSection("system.web/httpRuntime")).MaxRequestLength-2)*1024;
return (size > max ? max : size).ToString();
case SettingsNames.limitSize:
size = ParseSize(v as string);
return size.ToString();
case SettingsNames.timeout:
return ParseTimeout(v as string).ToString();
case SettingsNames.dragable:
case SettingsNames.multiple:
return ((bool)v) ? "true" : "false";
case SettingsNames.sliced:
return ((UploaderSliceds)v) != UploaderSliceds.Auto ? ((UploaderSliceds)v).GetHashCode().ToString() : null;
case SettingsNames.dragContainer:
case SettingsNames.placeholder:
case SettingsNames.progress:
s = (v + "").Trim();
if (s.StartsWith("$:"))
{ s = s.Substring(2); }
else { s = "\"" + ConvertHelper.ConvertToClientString(s) + "\""; }
return s;
case SettingsNames.parseResult:
s = (v + "").Trim();
if (s.StartsWith("javascript:", StringComparison.CurrentCultureIgnoreCase))
{ s = "function(serverData){\n" + s.Substring(11) + "\n}"; }
return s;
default:
s= v as string;
if (!string.IsNullOrWhiteSpace(s))
{ s = "\"" + ConvertHelper.ConvertToClientString(s) + "\""; }
return s;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (RegisterScript) { RegisterClientScript(); }
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
Dictionary<string, object> AddedKey;
bool flag;
StringBuilder sb = new StringBuilder();
foreach (var s in settings)
{
string v = ParseSetting(s.Key, s.Value);
if (!string.IsNullOrWhiteSpace(v))
{ sb.AppendFormat("{0}{1}:{2}", sb.Length > 0 ? "," : null, s.Key, v); }
}
if (!string.IsNullOrWhiteSpace(_token))
{
if (PostParameters == null) { PostParameters = new PostParametersCollection(); }
PostParameters.Insert(0, new PostParameter("token", _token));
}
if (PostParameters != null && PostParameters.Count > 0)
{
AddedKey = new Dictionary<string, object>();
flag = false;
sb.AppendFormat("{0}params:{{", sb.Length > 0 ? "," : null);
foreach (var s in PostParameters)
{
AddedKey.Add(s.Key, null);
sb.AppendFormat("{0}\"{1}\":\"{2}\"", flag ? "," : null
, ConvertHelper.ConvertToClientString(s.Key).Trim()
, ConvertHelper.ConvertToClientString(s.Value).Trim());
flag = true;
}
sb.Append("}");
AddedKey = null;
}
if (sb.Length > 0)
{
sb.Insert(0, "{\n");
sb.Append("\n}");
}
if (ClientEvents != null && ClientEvents.Count > 0)
{
flag = false;
AddedKey = new Dictionary<string, object>();
foreach (var s in ClientEvents)
{
string k = s.EventName.ToString(), v = s.Handle;
if (string.IsNullOrWhiteSpace(v)) continue;
AddedKey.Add(k, null);
if (v.StartsWith("javascript:", StringComparison.CurrentCultureIgnoreCase))
{ v = "function(file,args){\n" + v.Substring(11) + "\n}"; }
sb.AppendFormat("{0}\"{1}\":{2}", flag ? "," : ",\n{\n", k, v);
flag = true;
}
if (flag)
{
sb.Append("\n}");
}
}
string js = "var " + this.ClientID + "=new Uploader(" + sb.ToString() + ")";
writer.Write("<script>\n"+js+"\n</script>");
}
protected override void CreateChildControls()
{
base.CreateChildControls();
if (ViewTemplate != null)
{
ViewTemplate item = new ViewTemplate();
ViewTemplate.InstantiateIn(item);
this.Controls.Add(item);
}
}
string GetWebResourceUrl(string rn)
{
return Page.ClientScript.GetWebResourceUrl(this.GetType(), rn);
}
void RegisterClientScript()
{
if (this.Page.Header != null)
{
string id = "Uploader.release.min.js";
if (this.Page.Header.FindControl(id) == null)
{
Control container = new Control();
container.ID = id;
HtmlGenericControl js = new HtmlGenericControl("script");
js.Attributes.Add("src", GetWebResourceUrl("Html5Uploader.Controls.Uploader.release.min.js"));
js.InnerHtml = " ";
container.Controls.Add(js);
Page.Header.Controls.Add(js);
}
}
}
}
}