2014年7月22日星期二

初试jquery


同事送我一本jquery的书,之前一直想学javascript可是看了半天完全无感,正好借着这个机会学学jquery也是不错的,周末在家啃了20多页,其实只是看了看选择器和部分包装集内容,转过天来上班之前做的页面有bug,心想正好拿来练练jquery吧,于是硬逼着自己上阵,在垂头丧气沉睡了半个小时后,突然开窍完成了页面功能,并做了改进。

页面是一个评价页面,功能包括加载数据,并提交表单,加载数据部分没什么问题,主要是交互部分,需要做到字数检查提示,按钮效果,星星打分效果与取值。处理逻辑是打开页面后,在textarea中输入文字,点击提交按钮时检查字数,如果不满足条件则提示,并将按钮变灰。

之后我做了修改,加载完页面按钮是灰色,在输入文字时keyup事件中检测字数,如果满足条件则按钮变亮,可以点击提交,叫来测试同事问这种交互方式可不可以,回答挺好。

<script type="text/javascript">

$("#CommentContent").keyup(function () {
    var commentContent = $("#CommentContent");
    if (commentContent.val().length >= 5 && commentContent.val().length <= 200) {
        $("div.Btn input").removeClass("btn3").addClass("btn9").removeAttr("disabled");
        $("span.rem-txt").text("");
    }
    else {
        $("span.rem-txt").text(commentContent.attr("data-val-length"));
    }
})

$("li>div.eva-star>span.star").click(function () {
    var nexts = $(this).nextAll().removeClass("star-y");
    var prevs = $(this).addClass("star-y").prevAll().addClass("star-y");
    var len = $(this).prevAll("span").length + 1;
    $("input#Score").val(len);
});

</script>

总结

  • jquery的选择器太强大,以至于有时候不知道用哪种方式好
  • 有点开窍了,还需要加强学习
  • this没用成功,等提高了再找原因吧
  • 今天才知道原来后端是敏感词,男人要做就做前端,出发

2014年7月17日星期四

中国式融资


家里小区的电梯里挂上了同程网的广告,说实话我是个不容易被广告吸引的人,但这个广告做的的确很吸引人眼球,硕大的1元购让人无法抗拒,之后我在手机上装了同程的客户端,操作了几下我就不想用了,真心的。

  1. app启动时的引导页卡出翔
  2. 点击1元购进入的居然是网页,而且在此卡出翔
  3. 还没看到具体1元购的内容就要求用户登录
  4. 买火车票选择站点时点击没有任何反色效果

用到这我已经对这个app没有任何兴趣了,用户体验达到了令人发指的傻逼化。此番如此大规模的铺广告,估计是看携程那边并购的正火,去哪也成功傍上了干爹,自己再不造点声势早晚得死,还是学学阿里博点眼球,没准金主顺声而来成功融资,估值翻个几番再找下家。

老董昨天说了几家不知名的app,说是几轮融资下来估值1亿、10亿美元的,看得出他又想往app方向上靠了。其实目前国内的app市场就像上世纪末的互联网,随便投点钱然后找科技网站写点长篇体验软文就可以在投的钱后面加个0直接卖给下家,paypul那么牛逼的一个团队,做出来的超10亿美元市值的公司也不过就3家,在美国已经算是个非常了不起的成就了,你在中国这么一个人人不皆知的小app就敢叫价10亿,还是美金,无论从技术还是创新还是改变人们生活方式上都排不上号,真腆着脸这么自夸。

而目前国内的所谓天使投资人,绝大部分是不靠谱的,具体内容请参见这篇《我所知道的黑暗创投圈》,最近听说黄教主伙同李冰冰任泉也搞了个什么star投资公司,专门投资高科技,大哥大姐们,你们放IT圈吧,不要把IT人也娱乐化了,你们最近没什么博眼球的就来这个,专门做倒爷卖这种你们都不知道是什么东西的app好意思吗。


2014年7月1日星期二

C#调用json.net执行json的相关操作


微信的access_token每次获取有效期为7200秒,也就是两个小时,在这两个小时内,再重复获取access_token不仅浪费带宽和速度,也增加了出错的几率,而且由于微信对于每日获取次数做了限制,所以每次操作都要获取一遍肯定不是一个好的办法,于是需要我们将获取到的access_token保存在本地,有效期内使用我们本地的数据。

由于我的场景是多用户,所以将AppId、Secret保存下来定时获取的方式肯定不合适。而由于没有太频繁的调用,所以我暂时选择使用json文件将用户的id、access_token、获取时间保存在本地json文件内,正好数据上也是键值对的组合,如果调用频繁那么可以试试键值对的数据库,比如redis之类的。

流程图:

【待加】

操作json我比较习惯使用json.net的库,即Newtonsoft.Json,引用之后便可以使用了。而json.net的网站文档还是非常简单不健全的,我搜了很多中文的个人博客,总觉得很混淆,概念理不清,直到我打开了stackoverflow上这个问题的页面,才终于理清了思路,之后再看官方文档就简单多了。

A JToken is a generic representation of a JSON value of any kind. It could be a string, object, array, property, etc.
A JProperty is a single JToken value paired with a name. It can only be added to a JObject, and its value cannot be another JProperty.
A JObject is a collection of JProperties. It cannot hold any other kind of JToken directly.

好了,以下是具体代码:

  • 没有文件,创建

  1. 函数System.AppDomain.CurrentDomain.BaseDirectory曾经突然抽了,得到的路径没有反斜杠,过了个周末又莫名其妙的好了,具体原因不明;
  2. File.Create(mem_access_token)后面一定要跟Close(),否则文件没有释放,其他进程无法操作
  3. 初始化Jobject对象不能用字符串"{}"转换,而是直接JObject AllAccToken = new JObject();
string access_token = "";
JObject AllAccToken = new JObject();

string mem_access_token = System.AppDomain.CurrentDomain.BaseDirectory + @"\Resource\js\MemAccessToken.json";
if(!File.Exists(mem_access_token))
{
    File.Create(mem_access_token).Close();
    using(StreamWriter sw = new StreamWriter(mem_access_token, false))
    {
        sw.Write(AllAccToken);
    }
}
  • 读取文件

using (FileStream fs = new FileStream(mem_access_token, FileMode.Open))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        all_access_token = sr.ReadToEnd();
    }
}
  • 查询key

    如果存在,则查询对应的token是否已经过期,如果没过期则取值,否则调用微信接口获取并修改保存文件;如果不存在直接调用微信接口获取并添加保存文件
    调用的方法getAccessTokenFromWeiXin如果有access_token则返回access_token,否则返回errcode,因为errcode是5位,所以判断时长度写的6
if(AllAccToken[key] != null)
    {
        DateTime token_time = DateTime.Parse((string)AllAccToken.SelectToken(key).SelectToken("token_time"));
        //token未过期,读取
        if (token_time.AddSeconds(7200) > DateTime.Now)
        {
            return (string)AllAccToken.SelectToken(key).SelectToken("access_token");
        }
        //token已过期,重新获取并保存
        else
        {
            access_token = getAccessTokenFromWeiXin(Data);
            if ((access_token + "").Length > 6)
            {
                AllAccToken[key]["access_token"] = access_token;
                AllAccToken[key]["token_time"] = DateTime.Now;
                using (StreamWriter sw = new StreamWriter(mem_access_token, false))
                {
                    sw.Write(AllAccToken.ToString());
                }
            }
        }
    }
    //文件中没有token,获取并插入文件
else
    {
        access_token = getAccessTokenFromWeiXin(Data);
        if((access_token + "").Length > 6)
        {
            string new_access_token = @"{""access_token"":""" + access_token + @""",""token_time"":""" + DateTime.Now.ToString() + @"""}";
            AllAccToken.Add(memberPKId.ToString(), JToken.Parse(new_access_token));
            using (StreamWriter sw = new StreamWriter(mem_access_token, false))
            {
                sw.Write(AllAccToken.ToString());
            }
        }
    }

另外两个方法代码

调用微信接口获取access_token

public static string getAccessTokenFromWeiXin(ShpWeiXinShopAppData Data)
{
    Uri uri = new Uri(String.Format(@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", Data.WxAppId_NULL, Data.WxSecret_NULL));
    HttpWebRequest wxReq = HttpWebRequest.Create(uri) as HttpWebRequest;
    string wxJson = "";
    using (HttpWebResponse wxTokenRes = wxReq.GetResponse() as HttpWebResponse)
    {
        StreamReader reader = new StreamReader(wxTokenRes.GetResponseStream());
        wxJson = reader.ReadToEnd();
    }
    JObject jo = JObject.Parse(wxJson);
    string access_token = jo["access_token"] == null ? (string)jo["errcode"] : (string)jo["access_token"];
    return access_token;
}

根据微信错误号获取微信错误信息

微信的所有返回码我也保存成了json文件,方便用户提示,而且这个文件可以做成只读的。

public static string WeiXinError(string key)
{
    using (FileStream fs = new FileStream(System.AppDomain.CurrentDomain.BaseDirectory + @"\Resource\XML\WeiXinErrcode.json", FileMode.Open))
    {
        using(StreamReader sr = new StreamReader(fs))
        {
            string error = sr.ReadToEnd();
            JObject wxErr = JObject.Parse(error);
            return wxErr[key].ToString();
        }
    }
}

小结

经过这次改进,程序优化不少,而且明确了改进方向;
json操作方法很多,找到自己习惯的就好,而这种键值对的方式其实还是很有用的,如果操作频繁的话可以考虑读入内存中操作、数据库中操作等方式。

%23%20C%23%u8C03%u7528json.net%u6267%u884Cjson%u7684%u76F8%u5173%u64CD%u4F5C%0A%0A@%28My%20Blogger%29%5BC%23%7Cjson%7Cjson.net%7C%u5FAE%u4FE1%7C%u6587%u4EF6%u64CD%u4F5C%5D%0A%0A%20%20%20%20%u5FAE%u4FE1%u7684access_token%u6BCF%u6B21%u83B7%u53D6%u6709%u6548%u671F%u4E3A7200%u79D2%uFF0C%u4E5F%u5C31%u662F%u4E24%u4E2A%u5C0F%u65F6%uFF0C%u5728%u8FD9%u4E24%u4E2A%u5C0F%u65F6%u5185%uFF0C%u518D%u91CD%u590D%u83B7%u53D6access_token%u4E0D%u4EC5%u6D6A%u8D39%u5E26%u5BBD%u548C%u901F%u5EA6%uFF0C%u4E5F%u589E%u52A0%u4E86%u51FA%u9519%u7684%u51E0%u7387%uFF0C%u800C%u4E14%u7531%u4E8E%u5FAE%u4FE1%u5BF9%u4E8E%u6BCF%u65E5%u83B7%u53D6%u6B21%u6570%u505A%u4E86%u9650%u5236%uFF0C%u6240%u4EE5%u6BCF%u6B21%u64CD%u4F5C%u90FD%u8981%u83B7%u53D6%u4E00%u904D%u80AF%u5B9A%u4E0D%u662F%u4E00%u4E2A%u597D%u7684%u529E%u6CD5%uFF0C%u4E8E%u662F%u9700%u8981%u6211%u4EEC%u5C06%u83B7%u53D6%u5230%u7684access_token%u4FDD%u5B58%u5728%u672C%u5730%uFF0C%u6709%u6548%u671F%u5185%u4F7F%u7528%u6211%u4EEC%u672C%u5730%u7684%u6570%u636E%u3002%0A---------------------%0A%0A%u7531%u4E8E%u6211%u7684%u573A%u666F%u662F%u591A%u7528%u6237%uFF0C%u6240%u4EE5%u5C06AppId%u3001Secret%u4FDD%u5B58%u4E0B%u6765%u5B9A%u65F6%u83B7%u53D6%u7684%u65B9%u5F0F%u80AF%u5B9A%u4E0D%u5408%u9002%u3002%u800C%u7531%u4E8E%u6CA1%u6709%u592A%u9891%u7E41%u7684%u8C03%u7528%uFF0C%u6240%u4EE5%u6211%u6682%u65F6%u9009%u62E9%u4F7F%u7528json%u6587%u4EF6%u5C06%u7528%u6237%u7684id%u3001access_token%u3001%u83B7%u53D6%u65F6%u95F4%u4FDD%u5B58%u5728%u672C%u5730json%u6587%u4EF6%u5185%uFF0C%u6B63%u597D%u6570%u636E%u4E0A%u4E5F%u662F%u952E%u503C%u5BF9%u7684%u7EC4%u5408%uFF0C%u5982%u679C%u8C03%u7528%u9891%u7E41%u90A3%u4E48%u53EF%u4EE5%u8BD5%u8BD5%u952E%u503C%u5BF9%u7684%u6570%u636E%u5E93%uFF0C%u6BD4%u5982redis%u4E4B%u7C7B%u7684%u3002%0A%23%23%23%23%u6D41%u7A0B%u56FE%uFF1A%0A%u3010%u5F85%u52A0%u3011%0A%0A%u64CD%u4F5Cjson%u6211%u6BD4%u8F83%u4E60%u60EF%u4F7F%u7528json.net%u7684%u5E93%uFF0C%u5373Newtonsoft.Json%uFF0C%u5F15%u7528%u4E4B%u540E%u4FBF%u53EF%u4EE5%u4F7F%u7528%u4E86%u3002%u800Cjson.net%u7684%u7F51%u7AD9%u6587%u6863%u8FD8%u662F%u975E%u5E38%u7B80%u5355%u4E0D%u5065%u5168%u7684%uFF0C%u6211%u641C%u4E86%u5F88%u591A%u4E2D%u6587%u7684%u4E2A%u4EBA%u535A%u5BA2%uFF0C%u603B%u89C9%u5F97%u5F88%u6DF7%u6DC6%uFF0C%u6982%u5FF5%u7406%u4E0D%u6E05%uFF0C%u76F4%u5230%u6211%u6253%u5F00%u4E86stackoverflow%u4E0A%5B%u8FD9%u4E2A%u95EE%u9898%u7684%u9875%u9762%5D%28http%3A//stackoverflow.com/questions/15413825/how-do-you-add-a-jtoken-to-an-jobject%29%uFF0C%u624D%u7EC8%u4E8E%u7406%u6E05%u4E86%u601D%u8DEF%uFF0C%u4E4B%u540E%u518D%u770B%u5B98%u65B9%u6587%u6863%u5C31%u7B80%u5355%u591A%u4E86%u3002%0A%0A%3EA%20JToken%20is%20a%20generic%20representation%20of%20a%20JSON%20value%20of%20any%20kind.%20It%20could%20be%20a%20string%2C%20object%2C%20array%2C%20property%2C%20etc.%0AA%20JProperty%20is%20a%20single%20JToken%20value%20paired%20with%20a%20name.%20It%20can%20only%20be%20added%20to%20a%20JObject%2C%20and%20its%20value%20cannot%20be%20another%20JProperty.%0AA%20JObject%20is%20a%20collection%20of%20JProperties.%20It%20cannot%20hold%20any%20other%20kind%20of%20JToken%20directly.%0A%0A%u597D%u4E86%uFF0C%u4EE5%u4E0B%u662F%u5177%u4F53%u4EE3%u7801%uFF1A%0A-%20%23%23%23%23%u6CA1%u6709%u6587%u4EF6%uFF0C%u521B%u5EFA%0A1.%20%u51FD%u6570%60System.AppDomain.CurrentDomain.BaseDirectory%60%u66FE%u7ECF%u7A81%u7136%u62BD%u4E86%uFF0C%u5F97%u5230%u7684%u8DEF%u5F84%u6CA1%u6709%u53CD%u659C%u6760%uFF0C%u8FC7%u4E86%u4E2A%u5468%u672B%u53C8%u83AB%u540D%u5176%u5999%u7684%u597D%u4E86%uFF0C%u5177%u4F53%u539F%u56E0%u4E0D%u660E%uFF1B%0A2.%20%60File.Create%28mem_access_token%29%60%u540E%u9762%u4E00%u5B9A%u8981%u8DDF%60Close%28%29%60%2C%u5426%u5219%u6587%u4EF6%u6CA1%u6709%u91CA%u653E%uFF0C%u5176%u4ED6%u8FDB%u7A0B%u65E0%u6CD5%u64CD%u4F5C%0A3.%20%u521D%u59CB%u5316Jobject%u5BF9%u8C61%u4E0D%u80FD%u7528%u5B57%u7B26%u4E32%22%7B%7D%22%u8F6C%u6362%uFF0C%u800C%u662F%u76F4%u63A5%60JObject%20AllAccToken%20%3D%20new%20JObject%28%29%3B%60%0A%0A%60%60%60%20C%23%0Astring%20access_token%20%3D%20%22%22%3B%0AJObject%20AllAccToken%20%3D%20new%20JObject%28%29%3B%0A%0Astring%20mem_access_token%20%3D%20System.AppDomain.CurrentDomain.BaseDirectory%20+%20@%22%5CResource%5Cjs%5CMemAccessToken.json%22%3B%0Aif%28%21File.Exists%28mem_access_token%29%29%0A%7B%0A%20%20%20%20File.Create%28mem_access_token%29.Close%28%29%3B%0A%20%20%20%20using%28StreamWriter%20sw%20%3D%20new%20StreamWriter%28mem_access_token%2C%20false%29%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20sw.Write%28AllAccToken%29%3B%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%0A-%20%23%23%23%23%u8BFB%u53D6%u6587%u4EF6%0A%0A%60%60%60%20C%23%0Ausing%20%28FileStream%20fs%20%3D%20new%20FileStream%28mem_access_token%2C%20FileMode.Open%29%29%0A%7B%0A%20%20%20%20using%20%28StreamReader%20sr%20%3D%20new%20StreamReader%28fs%29%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20all_access_token%20%3D%20sr.ReadToEnd%28%29%3B%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%0A-%20%23%23%23%23%u67E5%u8BE2key%0A%u5982%u679C%u5B58%u5728%uFF0C%u5219%u67E5%u8BE2%u5BF9%u5E94%u7684token%u662F%u5426%u5DF2%u7ECF%u8FC7%u671F%uFF0C%u5982%u679C%u6CA1%u8FC7%u671F%u5219%u53D6%u503C%uFF0C%u5426%u5219%u8C03%u7528%u5FAE%u4FE1%u63A5%u53E3%u83B7%u53D6%u5E76%u4FEE%u6539%u4FDD%u5B58%u6587%u4EF6%uFF1B%u5982%u679C%u4E0D%u5B58%u5728%u76F4%u63A5%u8C03%u7528%u5FAE%u4FE1%u63A5%u53E3%u83B7%u53D6%u5E76%u6DFB%u52A0%u4FDD%u5B58%u6587%u4EF6%0A%u8C03%u7528%u7684%u65B9%u6CD5%60getAccessTokenFromWeiXin%60%u5982%u679C%u6709access_token%u5219%u8FD4%u56DEaccess_token%uFF0C%u5426%u5219%u8FD4%u56DEerrcode%uFF0C%u56E0%u4E3Aerrcode%u662F5%u4F4D%uFF0C%u6240%u4EE5%u5224%u65AD%u65F6%u957F%u5EA6%u5199%u76846%0A%0A%60%60%60%20C%23%0Aif%28AllAccToken%5Bkey%5D%20%21%3D%20null%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20DateTime%20token_time%20%3D%20DateTime.Parse%28%28string%29AllAccToken.SelectToken%28key%29.SelectToken%28%22token_time%22%29%29%3B%0A%20%20%20%20%20%20%20%20//token%u672A%u8FC7%u671F%uFF0C%u8BFB%u53D6%0A%20%20%20%20%20%20%20%20if%20%28token_time.AddSeconds%287200%29%20%3E%20DateTime.Now%29%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%28string%29AllAccToken.SelectToken%28key%29.SelectToken%28%22access_token%22%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20//token%u5DF2%u8FC7%u671F%uFF0C%u91CD%u65B0%u83B7%u53D6%u5E76%u4FDD%u5B58%0A%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20access_token%20%3D%20getAccessTokenFromWeiXin%28Data%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%28access_token%20+%20%22%22%29.Length%20%3E%206%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20AllAccToken%5Bkey%5D%5B%22access_token%22%5D%20%3D%20access_token%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20AllAccToken%5Bkey%5D%5B%22token_time%22%5D%20%3D%20DateTime.Now%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20using%20%28StreamWriter%20sw%20%3D%20new%20StreamWriter%28mem_access_token%2C%20false%29%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sw.Write%28AllAccToken.ToString%28%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20//%u6587%u4EF6%u4E2D%u6CA1%u6709token%uFF0C%u83B7%u53D6%u5E76%u63D2%u5165%u6587%u4EF6%0Aelse%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20access_token%20%3D%20getAccessTokenFromWeiXin%28Data%29%3B%0A%20%20%20%20%20%20%20%20if%28%28access_token%20+%20%22%22%29.Length%20%3E%206%29%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20string%20new_access_token%20%3D%20@%22%7B%22%22access_token%22%22%3A%22%22%22%20+%20access_token%20+%20@%22%22%22%2C%22%22token_time%22%22%3A%22%22%22%20+%20DateTime.Now.ToString%28%29%20+%20@%22%22%22%7D%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20AllAccToken.Add%28memberPKId.ToString%28%29%2C%20JToken.Parse%28new_access_token%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20using%20%28StreamWriter%20sw%20%3D%20new%20StreamWriter%28mem_access_token%2C%20false%29%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sw.Write%28AllAccToken.ToString%28%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%60%60%60%0A%0A%u53E6%u5916%u4E24%u4E2A%u65B9%u6CD5%u4EE3%u7801%0A%23%23%23%23%u8C03%u7528%u5FAE%u4FE1%u63A5%u53E3%u83B7%u53D6access_token%0A%60%60%60%20C%23%0Apublic%20static%20string%20getAccessTokenFromWeiXin%28ShpWeiXinShopAppData%20Data%29%0A%7B%0A%20%20%20%20Uri%20uri%20%3D%20new%20Uri%28String.Format%28@%22https%3A//api.weixin.qq.com/cgi-bin/token%3Fgrant_type%3Dclient_credential%26appid%3D%7B0%7D%26secret%3D%7B1%7D%22%2C%20Data.WxAppId_NULL%2C%20Data.WxSecret_NULL%29%29%3B%0A%20%20%20%20HttpWebRequest%20wxReq%20%3D%20HttpWebRequest.Create%28uri%29%20as%20HttpWebRequest%3B%0A%20%20%20%20string%20wxJson%20%3D%20%22%22%3B%0A%20%20%20%20using%20%28HttpWebResponse%20wxTokenRes%20%3D%20wxReq.GetResponse%28%29%20as%20HttpWebResponse%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20StreamReader%20reader%20%3D%20new%20StreamReader%28wxTokenRes.GetResponseStream%28%29%29%3B%0A%20%20%20%20%20%20%20%20wxJson%20%3D%20reader.ReadToEnd%28%29%3B%0A%20%20%20%20%7D%0A%20%20%20%20JObject%20jo%20%3D%20JObject.Parse%28wxJson%29%3B%0A%20%20%20%20string%20access_token%20%3D%20jo%5B%22access_token%22%5D%20%3D%3D%20null%20%3F%20%28string%29jo%5B%22errcode%22%5D%20%3A%20%28string%29jo%5B%22access_token%22%5D%3B%0A%20%20%20%20return%20access_token%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%u6839%u636E%u5FAE%u4FE1%u9519%u8BEF%u53F7%u83B7%u53D6%u5FAE%u4FE1%u9519%u8BEF%u4FE1%u606F%0A%u5FAE%u4FE1%u7684%u6240%u6709%u8FD4%u56DE%u7801%u6211%u4E5F%u4FDD%u5B58%u6210%u4E86json%u6587%u4EF6%uFF0C%u65B9%u4FBF%u7528%u6237%u63D0%u793A%uFF0C%u800C%u4E14%u8FD9%u4E2A%u6587%u4EF6%u53EF%u4EE5%u505A%u6210%u53EA%u8BFB%u7684%u3002%0A%60%60%60%20C%23%0Apublic%20static%20string%20WeiXinError%28string%20key%29%0A%7B%0A%20%20%20%20using%20%28FileStream%20fs%20%3D%20new%20FileStream%28System.AppDomain.CurrentDomain.BaseDirectory%20+%20@%22%5CResource%5CXML%5CWeiXinErrcode.json%22%2C%20FileMode.Open%29%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20using%28StreamReader%20sr%20%3D%20new%20StreamReader%28fs%29%29%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20string%20error%20%3D%20sr.ReadToEnd%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20JObject%20wxErr%20%3D%20JObject.Parse%28error%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20wxErr%5Bkey%5D.ToString%28%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0A%0A--------------------------%0A%23%23%23%23%u5C0F%u7ED3%0A%u7ECF%u8FC7%u8FD9%u6B21%u6539%u8FDB%uFF0C%u7A0B%u5E8F%u4F18%u5316%u4E0D%u5C11%uFF0C%u800C%u4E14%u660E%u786E%u4E86%u6539%u8FDB%u65B9%u5411%uFF1B%0Ajson%u64CD%u4F5C%u65B9%u6CD5%u5F88%u591A%uFF0C%u627E%u5230%u81EA%u5DF1%u4E60%u60EF%u7684%u5C31%u597D%uFF0C%u800C%u8FD9%u79CD%u952E%u503C%u5BF9%u7684%u65B9%u5F0F%u5176%u5B9E%u8FD8%u662F%u5F88%u6709%u7528%u7684%uFF0C%u5982%u679C%u64CD%u4F5C%u9891%u7E41%u7684%u8BDD%u53EF%u4EE5%u8003%u8651%u8BFB%u5165%u5185%u5B58%u4E2D%u64CD%u4F5C%u3001%u6570%u636E%u5E93%u4E2D%u64CD%u4F5C%u7B49%u65B9%u5F0F%u3002