热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ASP.NETMVC4微信公众平台开发测试二:微信Token获取

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_t

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效。由于获取access_token的api调用次数非常有限,建议开发者全局存储与更新access_token,频繁刷新access_token会导致api调用受限,影响自身业务。

     http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token

    按照官方给我们的说法,所有后续的操作,都要用到Access_Token,于是决定先解决这个问题。官方给的API如下:

   

   这个过程,只要一个返回值,所以,代码也先简单写一下。只为Get到代码嘛。

   继续在WxController中新建一个GetToken,返回值依然用String,便于测试。

   

        private bool CheckHTTPS(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        { 
            return true;
        }

        public string GetToken()
        {
            string strResult = "";
            string strAppId = "wxfb90abc********";
            string strAppsecret = "51b12f574e2c918571***********";

            string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
            url+= "&appid="+strAppId;
            url += "&secret=" + strAppsecret;

            ServicePointManager.ServerCertificateValidatiOnCallback= new RemoteCertificateValidationCallback(CheckHTTPS);

            HttpWebRequest req =  (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
            req.ServicePoint.Expect100COntinue= false;
            req.Method = "GET";
            req.KeepAlive = true;
            req.UserAgent = "Wxop4Net";
            req.Timeout = 100000;
            req.COntentType= "application/x-www-form-urlencoded;charset=utf-8";

            HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
            Encoding encoding = Encoding.UTF8;
            System.IO.Stream stream = null;
            StreamReader reader = null;

            try
            {
                // 以字符流的方式读取HTTP响应
                stream = rsp.GetResponseStream();
                reader = new StreamReader(stream, encoding);
                strResult = reader.ReadToEnd();
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (rsp != null) rsp.Close();
            }

            return strResult;
        }

  这里多了一个方法,因为鹅厂用的是HTTPS的协议,为了减少验证的麻烦,回调方法直接返回ture,方便使用。此时,发布一下代码,上传服务器,访问一下。

结果返回了一个Token,这样,验证的基础方法就获得了,但此时要考虑的问题好像该多了一些。

第一,获取Token需要保存数据,进行网络存储,以备调用接口时使用。

第二,请求过程中,请求代码过于复杂,没有结构,该梳理一下。

基于以上,先解决第二个,需要把请求代码,和数据格式进得重新整理,于是决定将微信请求的API方法提取出来,单独一个类库(注:网上有很多现成的类库,但个人喜欢能看到内部,所以自己尝试着写一写)。

项目由原有的一个MVC项目,增加一个类库项目,定名WxpSdk。

第一步,建立网络工具类,WebUtils.cs,这个,各种项目经常用到,直接分离出一个就可以。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

namespace Wxop.Api.Util
{
    /// 
    /// 网络工具类。
    /// 
    public sealed class WebUtils
    {
        private int _timeout = 100000;

        /// 
        /// 请求与响应的超时时间
        /// 
        public int Timeout
        {
            get { return this._timeout; }
            set { this._timeout = value; }
        }

        /// 
        /// 执行HTTP POST请求。
        /// 
        /// 请求地址
        /// 请求参数
        /// HTTP响应
        public string DoPost(string url, IDictionary parameters)
        {
            HttpWebRequest req = GetWebRequest(url, "POST");
            req.COntentType= "application/x-www-form-urlencoded;charset=utf-8";

            byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(parameters));
            System.IO.Stream reqStream = req.GetRequestStream();
            reqStream.Write(postData, 0, postData.Length);
            reqStream.Close();

            HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
            Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
            return GetResponseAsString(rsp, encoding);
        }

        /// 
        /// 执行HTTP GET请求。
        /// 
        /// 请求地址
        /// 请求参数
        /// HTTP响应
        public string DoGet(string url, IDictionary parameters)
        {
            if (parameters != null && parameters.Count > 0)
            {
                if (url.Contains("?"))
                {
                    url = url + "&" + BuildQuery(parameters);
                }
                else
                {
                    url = url + "?" + BuildQuery(parameters);
                }
            }

            HttpWebRequest req = GetWebRequest(url, "GET");
            req.COntentType= "application/x-www-form-urlencoded;charset=utf-8";

            HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
            Encoding encoding = Encoding.UTF8;
            return GetResponseAsString(rsp, encoding);
        }

        public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }

        public HttpWebRequest GetWebRequest(string url, string method)
        {
            HttpWebRequest req = null;
            if (url.Contains("https"))
            {
                ServicePointManager.ServerCertificateValidatiOnCallback= new RemoteCertificateValidationCallback(CheckValidationResult);
                req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(url);
            }

            req.ServicePoint.Expect100COntinue= false;
            req.Method = method;
            req.KeepAlive = true;
            req.UserAgent = "Wxop4Net";
            req.Timeout = this._timeout;

            return req;
        }

        /// 
        /// 把响应流转换为文本。
        /// 
        /// 响应流对象
        /// 编码方式
        /// 响应文本
        public string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
        {
            System.IO.Stream stream = null;
            StreamReader reader = null;

            try
            {
                // 以字符流的方式读取HTTP响应
                stream = rsp.GetResponseStream();
                reader = new StreamReader(stream, encoding);
                return reader.ReadToEnd();
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (rsp != null) rsp.Close();
            }
        }

        /// 
        /// 组装GET请求URL。
        /// 
        /// 请求地址
        /// 请求参数
        /// 带参数的GET请求URL
        public string BuildGetUrl(string url, IDictionary parameters)
        {
            if (parameters != null && parameters.Count > 0)
            {
                if (url.Contains("?"))
                {
                    url = url + "&" + BuildQuery(parameters);
                }
                else
                {
                    url = url + "?" + BuildQuery(parameters);
                }
            }
            return url;
        }

        /// 
        /// 组装普通文本请求参数。
        /// 
        /// Key-Value形式请求参数字典
        /// URL编码后的请求数据
        public static string BuildQuery(IDictionary parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            IEnumerator> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }
    }
}

  第二步,因为微信平台上,各种错误都会返回ErrCode,于是,先建立响应类的基类WxopResponse.cs

using System;
using System.Xml.Serialization;

namespace Wxop.Api
{
    [Serializable]
    public abstract class WxopResponse
    {
        /// 
        /// 错误码 {"errcode":40013,"errmsg":"invalid appid"}
        /// 
        [XmlElement("errcode")]
        public string ErrCode { get; set; }

        /// 
        /// 错误信息
        /// 
        [XmlElement("errmsg")]
        public string ErrMsg { get; set; }

        /// 
        /// 响应原始内容
        /// 
        public string Body { get; set; }

        /// 
        /// HTTP GET请求的URL
        /// 
        public string ReqUrl { get; set; }

        /// 
        /// 响应结果是否错误
        /// 
        public bool IsError
        {
            get
            {
                return !string.IsNullOrEmpty(this.ErrCode);
            }
        }
    }
}

  建立AccessToken的响应类AccessTokenGetResponse.cs

using System;
using System.Xml.Serialization;
using Wxop.Api.Domain;

namespace Wxop.Api.Response
{
    /// 
    /// UserBuyerGetResponse.
    /// 
    public class AccessTokenGetResponse : WxopResponse
    {
        [XmlElement("access_token")]
        public string AccessToken { get; set; }

        [XmlElement("expires_in")]
        public int ExpiresIn { get; set; } 
    }
}

接下来,建立一个请求类的接口 IWxopRequest.cs

using System.Collections.Generic;

namespace Wxop.Api.Request
{
    /// 
    /// WXOP请求接口。
    /// 
    public interface IWxopRequest where T : WxopResponse
    {
        /// 
        /// 获取所有的Key-Value形式的文本请求参数字典。其中:
        /// Key: 请求参数名
        /// Value: 请求参数文本值
        /// 
        /// 文本请求参数字典
        IDictionary GetParameters();
    }
}

  接下来,建立一个请求客户端的接口IWxopClient.css,一个默认客户端 DefaultWxopClient.cs

using System;
using Wxop.Api.Request;

namespace Wxop.Api
{
    /// 
    /// WXOP客户端。
    /// 
    public interface IWxopClient 
    {
        /// 
        /// 执行WXOP公开API请求。
        /// 
        /// 领域对象
        /// 具体的WXOP API请求
        /// 领域对象
        T Execute(IWxopRequest request) where T : WxopResponse;

    }
}

  

using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using Jayrock.Json.Conversion;
using Wxop.Api.Parser;
using Wxop.Api.Request;
using Wxop.Api.Util;

namespace Wxop.Api
{
    /// 
    /// 基于REST的WXOP客户端。
    /// 
    public class DefaultWxopClient : IWxopClient
    {
        public const string FORMAT_XML = "xml";
        public const string GRANT_TYPE="grant_type";
        public const string APP_ID="appid";
        public const string APP_SECRET="secret";

        private string serverUrl;
        private string appKey;
        private string appSecret;
        private string format = FORMAT_XML;
        
        private WebUtils webUtils;
        private bool disableParser = false; // 禁用响应结果解释

        #region DefaultWxopClient Constructors

        public DefaultWxopClient(string serverUrl, string appKey, string appSecret)
        {
            this.appKey = appKey;
            this.appSecret = appSecret;
            this.serverUrl = serverUrl;
            this.webUtils = new WebUtils();
        }

        public DefaultWxopClient(string serverUrl, string appKey, string appSecret, string format)
            : this(serverUrl, appKey, appSecret)
        {
            this.format = format;
        }

        #endregion

        #region IWxopClient Members

        public T Execute(IWxopRequest request) where T : WxopResponse
        {
            try
            {
                return DoExecute(request);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        #endregion

        private T DoExecute(IWxopRequest request) where T : WxopResponse
        {
            // 添加协议级请求参数
            WxopDictionary txtParams = new WxopDictionary(request.GetParameters());
            txtParams.Add(GRANT_TYPE, "client_credential");
            txtParams.Add(APP_ID, appKey);
            txtParams.Add(APP_SECRET, appSecret);

            string body = webUtils.DoGet(this.serverUrl, txtParams);

            // 解释响应结果
            T rsp;
            if (disableParser)
            {
                rsp = Activator.CreateInstance();
                rsp.Body = body;
            }
            else
            {
                if (FORMAT_XML.Equals(format))
                {
                    IWxopParser tp = new WxopXmlParser();
                    rsp = tp.Parse(body);
                }
                else
                {
                    IWxopParser tp = new WxopJsonParser();
                    rsp = tp.Parse(body);
                }
            }

            return rsp;
        }
    }
}

  这里边用到了Json解析,直接使用的Jayrock.Json组件。建立了一个JSON通用解释器。IWxopParser.cs IWxopReader.cs WxopJsonParser.cs

using System;

namespace Wxop.Api.Parser
{
    /// 
    /// WXOP API响应解释器接口。响应格式可以是XML, JSON等等。
    /// 
    public interface IWxopParser
    {
        /// 
        /// 把响应字符串解释成相应的领域对象。
        /// 
        /// 领域对象
        /// 响应字符串
        /// 领域对象
        T Parse(string body) where T : WxopResponse;
    }
}

  

using System;
using System.Collections;

namespace Wxop.Api.Parser
{
    public delegate object DWxopConvert(IWxopReader reader, Type type);

    /// 
    /// WXOP API响应读取器接口。响应格式可以是XML, JSON等等。
    /// 
    public interface IWxopReader
    {
        /// 
        /// 判断响应中是否包含指定的属性。
        /// 
        /// 属性名称
        /// true/false
        bool HasReturnField(object name);

        /// 
        /// 获取值类型属性的值。
        /// 
        /// 属性名称
        /// 值对象
        object GetPrimitiveObject(object name);

        /// 
        /// 获取引用类型的值。
        /// 
        /// 属性名称
        /// 引用类型
        /// 转换器
        /// 引用对象
        object GetReferenceObject(object name, Type type, DWxopConvert convert);

        /// 
        /// 获取列表类型的值。
        /// 
        /// 列表属性名称
        /// 列表项名称
        /// 引用类型
        /// 转换器
        /// 列表对象
        IList GetListObjects(string listName, string itemName, Type type, DWxopConvert convert);
    }
}

  

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Xml.Serialization;
using Jayrock.Json.Conversion;

namespace Wxop.Api.Parser
{
    /// 
    /// WXOP JSON响应通用解释器。
    /// 
    public class WxopJsonParser : IWxopParser
    {
        private static readonly Dictionary> attrs = new Dictionary>();

        #region IWxopParser Members

        public T Parse(string body) where T : WxopResponse
        {
            return Parse(body, false);
        }

        /// 
        /// JSON解释器,将JSON结果转为相关类 本方法为添加重载方法 Lasko 2013.11.22
        /// 
        /// 
        /// 
        /// 
        /// 
        public T Parse(string body, bool removeRoot) where T : WxopResponse
        {
            T rsp = null;

            IDictionary json = JsonConvert.Import(body) as IDictionary;
            if (json != null)
            {
                IDictionary data = null;
                if (removeRoot)
                {
                    //忽略根节点的名称 
                    foreach (object key in json.Keys)
                    {
                        data = json[key] as IDictionary;
                        break;
                    }
                }
                else
                {
                    data = json;
                }

                if (data != null)
                {
                    IWxopReader reader = new WxopJsonReader(data);
                    if (removeRoot){
                        rsp = (T)FromJson(reader, typeof(T));
                    }
                    else {
                        rsp = (T)FromJson(reader, typeof(T));
                    }
                }
            }

            if (rsp == null)
            {
                rsp = Activator.CreateInstance();
            }

            if (rsp != null)
            {
                rsp.Body = body;
            }

            return rsp;
        }
        #endregion

        private Dictionary GetWxopAttributes(Type type)
        {
            Dictionary tas = null;
            bool inc = attrs.TryGetValue(type.FullName, out tas);

            if (inc && tas != null) // 从缓存中获取类属性元数据
            {
                return tas;
            }
            else // 创建新的类属性元数据缓存
            {
                tas = new Dictionary();
            }

            PropertyInfo[] pis = type.GetProperties();
            foreach (PropertyInfo pi in pis)
            {
                WxopAttribute ta = new WxopAttribute();
                ta.Method = pi.GetSetMethod();

                // 获取对象属性名称
                XmlElementAttribute[] xeas = pi.GetCustomAttributes(typeof(XmlElementAttribute), true) as XmlElementAttribute[];
                if (xeas != null && xeas.Length > 0)
                {
                    ta.ItemName = xeas[0].ElementName;
                }

                // 获取列表属性名称
                if (ta.ItemName == null)
                {
                    XmlArrayItemAttribute[] xaias = pi.GetCustomAttributes(typeof(XmlArrayItemAttribute), true) as XmlArrayItemAttribute[];
                    if (xaias != null && xaias.Length > 0)
                    {
                        ta.ItemName = xaias[0].ElementName;
                    }
                    XmlArrayAttribute[] xaas = pi.GetCustomAttributes(typeof(XmlArrayAttribute), true) as XmlArrayAttribute[];
                    if (xaas != null && xaas.Length > 0)
                    {
                        ta.ListName = xaas[0].ElementName;
                    }
                    if (ta.ListName == null)
                    {
                        continue;
                    }
                }

                // 获取属性类型
                if (pi.PropertyType.IsGenericType)
                {
                    Type[] types = pi.PropertyType.GetGenericArguments();
                    ta.ListType = types[0];
                }
                else
                {
                    ta.ItemType = pi.PropertyType;
                }

                tas.Add(pi.Name, ta);
            }

            attrs[type.FullName] = tas;
            return tas;
        }

        public object FromJson(IWxopReader reader, Type type)
        {
            object rsp = null;
            Dictionary pas = GetWxopAttributes(type);

            Dictionary.Enumerator em = pas.GetEnumerator();
            while (em.MoveNext())
            {
                KeyValuePair kvp = em.Current;
                WxopAttribute ta = kvp.Value;
                string itemName = ta.ItemName;
                string listName = ta.ListName;

                if (!reader.HasReturnField(itemName) && (string.IsNullOrEmpty(listName) || !reader.HasReturnField(listName)))
                {
                    continue;
                }

                object value = null;
                if (ta.ListType != null)
                {
                    value = reader.GetListObjects(listName, itemName, ta.ListType, FromJson);
                }
                else
                {
                    if (typeof(string) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = tmp.ToString();
                        }
                    }
                    else if (typeof(long) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = ((IConvertible)tmp).ToInt64(null);
                        }
                    }
                    else if (typeof(int) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = ((IConvertible)tmp).ToInt32(null);
                        }
                    }
                    else if (typeof(bool) == ta.ItemType)
                    {
                        value = reader.GetPrimitiveObject(itemName);
                    }
                    else
                    {
                        value = reader.GetReferenceObject(itemName, ta.ItemType, FromJson);
                    }
                }

                if (value != null)
                {
                    if (rsp == null)
                    {
                        rsp = Activator.CreateInstance(type);
                    }
                    ta.Method.Invoke(rsp, new object[] { value });
                }
            }

            return rsp;
        }

        public object FromJson(IWxopReader reader, Type type, bool haveChildNode)
        {
            object rsp = null;
            Dictionary pas = GetWxopAttributes(type);

            Dictionary.Enumerator em = pas.GetEnumerator();
            while (em.MoveNext())
            {
                KeyValuePair kvp = em.Current;
                WxopAttribute ta = kvp.Value;
                string itemName = ta.ItemName;
                string listName = ta.ListName;

                if (!reader.HasReturnField(itemName) && (string.IsNullOrEmpty(listName) || !reader.HasReturnField(listName)))
                {
                    continue;
                }

                object value = null;
                if (ta.ListType != null)
                {
                    value = reader.GetListObjects(listName, itemName, ta.ListType, FromJson);
                }
                else
                {
                    if (typeof(string) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = tmp.ToString();
                        }
                    }
                    else if (typeof(long) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = ((IConvertible)tmp).ToInt64(null);
                        }
                    }
                    else if (typeof(int) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = ((IConvertible)tmp).ToInt32(null);
                        }
                    }
                    else if (typeof(bool) == ta.ItemType)
                    {
                        value = reader.GetPrimitiveObject(itemName);
                    }
                    else
                    {
                        value = reader.GetReferenceObject(itemName, ta.ItemType, FromJson);
                    }
                }

                if (value != null)
                {
                    if (rsp == null)
                    {
                        rsp = Activator.CreateInstance(type);
                    }
                    ta.Method.Invoke(rsp, new object[] { value });
                }
            }

            return rsp;
        }
    }
}

  建立AccessToken 请求类  AccessTokenGetRequest.css

 

using System;
using System.Collections.Generic;
using Wxop.Api.Response;
using Wxop.Api.Util;

namespace Wxop.Api.Request
{
    /// 
    /// WXOP API: Get Access Token
    /// 
    public class AccessTokenGetRequest : IWxopRequest
    {
        private IDictionary otherParameters;

        #region IWxopRequest Members

        public IDictionary GetParameters()
        {
            WxopDictionary parameters = new WxopDictionary();
            //parameters.Add("fields", this.Fields);
            parameters.AddAll(this.otherParameters);
            return parameters;
        }
        #endregion

        public void AddOtherParameter(string key, string value)
        {
            if (this.otherParameters == null)
            {
                this.otherParameters = new WxopDictionary();
            }
            this.otherParameters.Add(key, value);
        }
    }
}

  好了 ,准备工作都做好了,在原有的MVC项目里,引入刚整理好的类库。 GetToken的方法,得写为如下代码:

        public string GetToken()
        {
            string strResult = String.Empty;
            string url = "https://api.weixin.qq.com/cgi-bin/token";
            string appkey = "wxfb90abc********";
            string appsecret = "51b12f574e2c9185********";

            IWxopClient client = new DefaultWxopClient(url, appkey, appsecret, "json");
            AccessTokenGetRequest req = new AccessTokenGetRequest();
            AccessTokenGetResponse respOnse= client.Execute(req);

            if (!String.IsNullOrEmpty(response.AccessToken)) {
                strResult = response.AccessToken;
            }

            return strResult;
        }

  再次执行,返回的就只有一个Token了。

至此,还需要解决的一个问题就是Token的储存了。我先想想解决方案。

 


推荐阅读
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
  • 本文介绍了ASP.NET Core MVC的入门及基础使用教程,根据微软的文档学习,建议阅读英文文档以便更好理解,微软的工具化使用方便且开发速度快。通过vs2017新建项目,可以创建一个基础的ASP.NET网站,也可以实现动态网站开发。ASP.NET MVC框架及其工具简化了开发过程,包括建立业务的数据模型和控制器等步骤。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • 本文讨论了在ASP中创建RazorFunctions.cshtml文件时出现的问题,即ASP.global_asax不存在于命名空间ASP中。文章提供了解决该问题的代码示例,并详细解释了代码中涉及的关键概念,如HttpContext、Request和RouteData等。通过阅读本文,读者可以了解如何解决该问题并理解相关的ASP概念。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了Windows Vista操作系统中的用户账户保护功能,该功能是为了增强系统的安全性而设计的。通过对Vista测试版的体验,可以看到系统在安全性方面的进步。该功能的引入,为用户的账户安全提供了更好的保障。 ... [详细]
author-avatar
莺妈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有