[fix]Config创建默认配置文件的开关Runtime.CreateConfigOnMissing,仅需对自动创建生效,而不应该阻止用户主动Save
智能大石头 authored at 2024-08-09 00:30:41 石头 committed at 2024-08-10 14:22:24
6.28 KiB
X
using System;
using System.Web;
using XCode.Configuration;
using XCode.Exceptions;

namespace XCode.Accessors
{
    /// <summary>Http实体访问器,只读不写。</summary>
    public class HttpEntityAccessor : EntityAccessorBase
    {
        #region 属性
        /// <summary>种类</summary>
        public override EntityAccessorTypes Kind { get { return EntityAccessorTypes.Http; } }

        private HttpRequest _Request;
        /// <summary>请求</summary>
        public HttpRequest Request
        {
            get { return _Request ?? (_Request = HttpContext.Current.Request); }
        }

        private String _ItemPrefix = "frm";
        /// <summary>前缀,只用于Form</summary>
        public String ItemPrefix
        {
            get { return _ItemPrefix; }
            set { _ItemPrefix = value; }
        }

        private Int64 _MaxLength = 10 * 1024 * 1024;
        /// <summary>最大文件大小,默认10M</summary>
        public Int64 MaxLength
        {
            get { return _MaxLength; }
            set { _MaxLength = value; }
        }
        #endregion

        #region IEntityAccessor 成员
        /// <summary>设置参数。返回自身,方便链式写法。</summary>
        /// <param name="name">参数名</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public override IEntityAccessor SetConfig(string name, object value)
        {
            if (name.EqualIgnoreCase(EntityAccessorOptions.MaxLength))
                MaxLength = (Int64)value;
            else if (name.EqualIgnoreCase(EntityAccessorOptions.ItemPrefix))
                ItemPrefix = (String)value;

            return base.SetConfig(name, value);
        }

        /// <summary>是否支持把信息写入到外部</summary>
        public override bool CanWrite { get { return false; } }

        /// <summary>外部=>实体,从外部读取指定实体字段的信息</summary>
        /// <param name="entity">实体对象</param>
        /// <param name="item">实体字段</param>
        protected override void ReadItem(IEntity entity, FieldItem item)
        {
            Object v = GetRequestItem(item);
            if (v == null) return;

            if (v is String)
            {
                ////如果是主键或者不是实体中的字段脏数据不改变
                //if (item.PrimaryKey || !item.IsDataObjectField) return;

                #region 检查数据类型是否满足目标类型,如果不满足则跳过,以免内部赋值异常导致程序处理出错
                TypeCode code = Type.GetTypeCode(item.Type);
                if (code >= TypeCode.Int16 && code <= TypeCode.UInt64)
                {
                    Int64 n = 0;
                    if (!Int64.TryParse((String)v, out n)) return;
                    v = n;
                }
                else if (code == TypeCode.Single || code == TypeCode.Double)
                {
                    Double d = 0;
                    if (!Double.TryParse((String)v, out d)) return;
                    v = d;
                }
                else if (code == TypeCode.Decimal)
                {
                    Decimal d = 0;
                    if (!Decimal.TryParse((String)v, out d)) return;
                    v = d;
                }
                else if (code == TypeCode.Boolean)
                {
                    Boolean b;
                    if (!Boolean.TryParse((String)v, out b)) return;
                    v = b;
                }
                else if (code == TypeCode.DateTime)
                {
                    DateTime d;
                    if (!DateTime.TryParse((String)v, out d)) return;
                    v = d;
                }
                #endregion

                entity.SetItem(item.Name, v);
            }
            else
            {
                // 处理上传的文件
                HttpPostedFile file = v as HttpPostedFile;

                if (file != null)
                {
                    // 把文件内容读出来
                    if (file.ContentLength > MaxLength) throw new XCodeException("文件大小{0}超过了最大限制{1}!", file.ContentLength, MaxLength);
                    Byte[] bts = new Byte[file.ContentLength];
                    file.InputStream.Read(bts, 0, bts.Length);

                    if (item.Type == typeof(Byte[]))
                        entity.SetItem(item.Name, bts);
                    else if (item.Type == typeof(String))
                        entity.SetItem(item.Name, Convert.ToBase64String(bts));
                }
            }
        }

        /// <summary>从请求中获取指定字段的值</summary>
        /// <param name="item"></param>
        /// <returns></returns>
        protected virtual Object GetRequestItem(FieldItem item)
        {
            if (item == null) return null;

            String value = GetRequest(item.Name);
            if (value == null && item.Name != item.ColumnName) value = GetRequest(item.ColumnName);

            if (value != null) return value;

            // 处理上传的文件
            HttpPostedFile file = Request.Files[item.Name];
            if (file == null && item.Name != item.ColumnName) file = Request.Files[item.ColumnName];

            return file;
        }

        /// <summary>采用该方法而不再用Request[name],主要是后者还处理服务器变量ServerVar,这是不需要的,还有可能得到错误的数据</summary>
        /// <param name="name">名称</param>
        /// <returns></returns>
        String GetRequest(String name)
        {
            String value = Request.QueryString[name];
            if (!String.IsNullOrEmpty(value)) return value;

            value = Request.Form[name];
            if (!String.IsNullOrEmpty(value)) return value;

            // 加上前缀再试试
            value = Request.Form[ItemPrefix + name];
            if (!String.IsNullOrEmpty(value)) return value;

            HttpCookie cookie = Request.Cookies[name];
            if (cookie != null) value = cookie.Value;
            if (!String.IsNullOrEmpty(value)) return value;

            return null;
        }
        #endregion
    }
}