C#开发微信小程序(三)
<div>导航:C#开发微信小程序系列</div><p> </p>
<p>关于小程序项目结构,框架介绍,组件说明等,请查看微信小程序官方文档,关于以下贴出来的代码部分我只是截取了一些片段,方便说明问题,如果需要查看完整源代码,可以在我的项目库中下载:</p>
<p>https://github.com/dwBurning/WeChatMiniProgram.git</p>
<p>继第二篇博文介绍的对微信小程序前端调整的过程中发现的一些问题,该篇继续介绍对后端Web Api调整的过程中发现的问题,虽然谈不上是bug,但是规范性同样很重要,当然如果仍有不足之处,欢迎在评论中指出来。</p>
<p> 第一:调整接口,最初的版本,为了方便都写在一个类文件里边,其次,不符合Api RESTful的风格,于是重新整理,针对每个资源,建一个类,里边只有针对资源的增删查改Get,Post,Put,Delete四个方法:</p>
<p><img src="https://img2018.cnblogs.com/blog/635258/201908/635258-20190831165047869-809280894.png"></p>
<div class="cnblogs_code">
<pre>public JsonResult<ResultData> Get(string sessionKey){}<br><br>public JsonResult<ResultData> Post(dynamic data){}<br><br>public void Put(int id, string value)<br><br>public JsonResult<ResultData> Delete(dynamic data)</pre>
</div>
<p>第二:登录,小程序开放给所有的微信用户的,所以每个人打开都需要获取到用户的唯一标识,叫做OpenId,这个是微信服务端分配给每个微信用户的唯一凭证,我们要拿这个凭证建立用户关系,下单,查询购物车之类的操作。通过官方文件的介绍,可以知道,调用如下这个接口,就可以获取到。但是同时官方是不建议将获取到的敏感数据直接返回小程序前端的,于是稍微调整了一下,在缓存中重新建立了映射关系,返回自己生成的sessionKey给前端。批注:目前整个应用都是基于缓存的,并没有实现真正的仓储。</p>
<p>另外补充说明一下,这里使用<span style="color: rgba(255, 102, 0, 1)">dynamic<span style="color: rgba(0, 0, 0, 1)">作为参数的数据类型,因为小程序前端发起的请求,提交参数都是JSON字符串,每次都解析的话,也挺麻烦的,用<span style="color: rgba(255, 102, 0, 1)">dynamic</span>省去了这个步骤。<br></span></span></p>
<div class="cnblogs_code">
<pre>GET https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">string</span> _appID = <span style="color: rgba(128, 0, 0, 1)">""</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">填写自己的AppId</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">string</span> _appSecret = <span style="color: rgba(128, 0, 0, 1)">""</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">填写自己的AppSecret</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 登录
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="data"></span><span style="color: rgba(0, 128, 0, 1)">dynamic接收{code:""}</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">sessionKey</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span> PostLogIn(<span style="color: rgba(0, 0, 255, 1)">dynamic</span><span style="color: rgba(0, 0, 0, 1)"> data)
{
</span><span style="color: rgba(0, 0, 255, 1)">string</span> code =<span style="color: rgba(0, 0, 0, 1)"> data.code;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> strUrl = <span style="color: rgba(0, 0, 255, 1)">string</span>.Format(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, _appID, _appSecret, code);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> appAuth = JsonConvert.DeserializeAnonymousType(HttpRequestHelper.HttpGet(strUrl), <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
session_key </span>= <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">,
openid </span>= <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">
});
</span><span style="color: rgba(0, 0, 255, 1)">string</span> sessionKey = Guid.NewGuid().ToString(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">N</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">string</span> sessionValue = appAuth.session_key + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">|</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> appAuth.openid;
LazyOrdersRepository.AppSession.AddOrUpdate(sessionKey, sessionValue, (key, value) </span>=><span style="color: rgba(0, 0, 0, 1)"> value);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sessionKey;
}</span></pre>
</div>
<p>第三,增加了统一的返回类型,直接返回JSON对象而不是JSON字符串。如果你看了我的第一篇文章,里边就讲到了如果直接返回String,前端需要将字符串转JSON对象,才可以解析。此次修改为直接返回JsonResult对象,前端收到后,就可以不用再次转换了。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 根据sessionKey获取购物车列表
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="sessionKey"></span><span style="color: rgba(0, 128, 0, 1)">会话Key</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">ResultData通用结果返回类型</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> JsonResult<ResultData> Get(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> sessionKey)
{
</span><span style="color: rgba(0, 0, 255, 1)">string</span> sessionValue = <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (LazyOrdersRepository.AppSession.TryGetValue(sessionKey, <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> sessionValue))
{
</span><span style="color: rgba(0, 0, 255, 1)">string</span> openId = sessionValue.Split(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">|</span><span style="color: rgba(128, 0, 0, 1)">'</span>)[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">var</span> carts = <span style="color: rgba(0, 0, 255, 1)">from</span> cart <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> LazyOrdersRepository.Carts
</span><span style="color: rgba(0, 0, 255, 1)">where</span> cart.OpenId == openId && cart.IsPaid == <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
group cart by cart.MenuId into c
</span><span style="color: rgba(0, 0, 255, 1)">select</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
c.Key,
menu </span>= LazyOrdersRepository.GetMenuList().FirstOrDefault(x => x.MenuId ==<span style="color: rgba(0, 0, 0, 1)"> c.Key),
count </span>=<span style="color: rgba(0, 0, 0, 1)"> c.Count(),
selected </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 0, 255, 1)">return</span> Json<ResultData>(<span style="color: rgba(0, 0, 255, 1)">new</span> ResultData() { Code = ResponseResult.Success, Context =<span style="color: rgba(0, 0, 0, 1)"> carts.ToList() });
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> Json(<span style="color: rgba(0, 0, 255, 1)">new</span> ResultData() { Code =<span style="color: rgba(0, 0, 0, 1)"> ResponseResult.Falied });
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">onShow() {
const self </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;
wx.getStorage({
key: </span>'sessionKey'<span style="color: rgba(0, 0, 0, 1)">,
success: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res) {
self.setData({
sessionKey: res.data
})
wx.request({
url: <span style="color: rgba(255, 102, 0, 1)">app.globalData.urlCarts </span></span><span style="color: rgba(255, 102, 0, 1)">+ '?sessionKey=' +</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 102, 0, 1)"> self.data.sessionKey</span>,
success: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.data.Context && res.data.Context.length > 0<span style="color: rgba(0, 0, 0, 1)">) {
self.setData({
hasList: </span><span style="color: rgba(0, 0, 255, 1)">true</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 既然有数据了,那设为true吧</span>
<span style="color: rgba(0, 0, 0, 1)"> carts: <span style="color: rgba(255, 102, 0, 1)">res.data.Context</span>
});
}
},
complete: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res) {
self.getTotalPrice()
}
});
},
fail: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(res) {
util.checkSession()
},
})
},</span></pre>
</div>
<p> 第四:增加了swagger生成Api文档,具体怎么配置swagger,可以移步之前写的博文Asp.Net Web Api中使用Swagger</p>
<p><img src="https://img2018.cnblogs.com/blog/635258/201908/635258-20190831212507834-459592702.png"></p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
牛人之所以是牛人,是因为你现在在踩的坑,他曾经都已经踩过了。<br><br>
来源:https://www.cnblogs.com/dwBurning/p/wechatminiprogramwithwebapi3.html
頁:
[1]