钉钉开发系列(十)SaltUI与WebApi交互
Asp.net中常用的数据交互是WebApi的方式,对于请求者只是向一个url发起请求。对于SaltUI,官方推荐使用salt-fetch.js来进行数据交互,当然直接使用zepto.js或者jquery.js以ajax来交互也是可以的。
接上一篇《钉钉开发系列(九)SaltUI在VS中的开发》,我们在项目SaltUIDemo中构造WebApi端,在项目中添加一个Global.asax和WebApiConfig.cs,具体代码如下
Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.SessionState;
namespace SaltUIDemo
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}需要添加System.Web.Http、System.Web.Http.WebHost、System.Web.Mvc的引用,我们采用4.0版本的。
WebApiConfig.cs
using System.Web.Http;
namespace SaltUIDemo
{
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//注册路由映射
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",//action表示按方法路由
defaults: new { id = RouteParameter.Optional }
);
}
}
}
在项目中添加Controllers文件夹,并在其下增加SystemController.cs的文件,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace SaltUIDemo.Controllers
{
public class SystemController:ApiController
{
#region Get Function
[HttpGet]
public String Get()
{
return Guid.NewGuid().ToString();
}
#endregion
}
}重新编译,启动项目,然后测试api,结果如下
可以看到我们以api/system/get访问时,得到了一串guid,这样WebApi端已经可以了,现在需要的是在SaltUI端向其发起请求。
在SaltUIDemoSrc项目下的scr/app下有一个db.js文件,我们找到后,在里面配置要发起的请求,代码如下
// See https://github.com/Jias/natty-fetch for more details.
const context = salt.fetch.context({
mockUrlPrefix: '/mock/api/',
urlPrefix: '/api/',
mock: false,
// jsonp: true,
withCredentials: false,
traditional: true,
data: {
_tb_token_: ''
},
timeout: 5000,
fit: function(response) {
return {
success: response.success,
content: response.content,
error: {
errorMsg: response.errorMsg,
errorCode: response.errorCode,
errorLevel: response.errorLevel
}
}
}
});
context.create('SomeModuleAPI', {
getSomeInfo: {
mockUrl: 'query/getSomeInfo.json',
url: 'query/getSomeInfo.json'
}
});
context.create('System', {
Get: {
mockUrl: 'System/Get',
url: 'System/Get'
}
});
module.exports = context.api;
其中mock改成了false,mockUrlPrefix和urlPrefix也作了修改,之后在后面添加了context.create('System',...)。
请求配置设定好之后,我们在src/pages/system的action.js中添加一个action为get,代码如下
action.js
module.exports = Reflux.createActions([
'fetch',
'get'
]);然后在store.js中响应action的get,即设定onGet方法,代码如下
const Actions = require('./actions');
const DB = require('../../app/db');
module.exports = Reflux.createStore({
listenables: [Actions],
data: {
loaded: false
},
onFetch: function(params, cb) {
let t = this;
t.data.loaded = true;
t.updateComponent();
cb && cb(t.data);
},
onGet: function(params, cb) {
let t = this;
DB.System.Get(params)
.then(function (content) {
t.data.loaded = true;
t.data.content = content;
t.data.error = false;
if (cb != undefined) {
cb(t.data);
}
})
.catch(function (error) {
t.data.error = error;
if (cb != undefined) {
cb(t.data);
}
});
},
updateComponent: function() {
this.trigger(this.data);
},
getInitialState: function() {
return this.data;
}
});
onGet中DB.System.Get就是发起请求的,以promise的方式来调用。
现在我们在PageSystem.js中触发请求,修改其中的handleClick和render的代码,具体如下
render() {
let t=this;
return (
<div className="system">
page system-{t.state.guid}
<Button type='primary' onClick={t.handleClick.bind(t)}>测试</Button>
</div>
);
}
handleClick()
{ let t=this;
Actions.get({}, function(data) {
t.setState({guid:data.content});
});
}其中handleClick中的t.setState是修改状态保存数据,同时触发render。render中的{t.state.guid}是动态获取state中的guid
但是执行后会发现,数据并没有更新到界面中。
为什么呢?原因在于db.js中我们需要对返回的数据进行一个预处理,即fit函数,修改后的代码如下
fit: function(response) {
return {
success: true,//response.success,
content:response,// response.content,
error: {
errorMsg: response.errorMsg,
errorCode: response.errorCode,
errorLevel: response.errorLevel
}
}
}再编译运行后,结果如下图
界面中已经得到了guid的数据。
现在我们回过头来看fit函数,需要将success设置为true时,数据才会正确响应,否则以错误的方式来处理。其实这样做是为了将数据的响应统一,为了配合这样的处理,我们可以将WebApi返回的数据也做成这样的格式,所以我们修改SystemController的代码,修改后的代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace SaltUIDemo.Controllers
{
public class SystemController:ApiController
{
#region Get Function
[HttpGet]
public ResponseResult<String> Get()
{
var result = new ResponseResult<String>
{
success = true,
content = Guid.NewGuid().ToString(),
errorMsg = "OK",
errorCode = 10000,
errorLevel =0
};
return result;
}
#endregion
}
public class ResponseResult<T>
{
public bool success { get; set; }
public T content { get; set; }
public String errorMsg { get; set; }
public int errorCode { get; set; }
public int errorLevel { get; set; }
}
}我们测试一下api/system/get,结果如下图
可以看到我们已经经得到了新的结构数据,这样我们再修改db.js的fit函数,其代码如下
fit: function(response) {
return {
success: response.success,
content:response.content,
error: {
errorMsg: response.errorMsg,
errorCode: response.errorCode,
errorLevel: response.errorLevel
}
}
}重新编译运行后,结果如下图这样一来,如果在SystemController中处理数据,得到了错误的,就可以直接将success置为false,然后设置errorMsg、errorCode、errorLevel,之后界面上就可以进行相应的处理了。
除了发起Get请求之外,我们还会发起POST请求,这时在db.js的配置请求时,就需要指定post方法,同时指定header,示例如下
context.create('System', {
Get: {
mockUrl: 'System/Get',
url: 'System/Get'
},
Update: {
mockUrl: 'System/Update',
url: 'System/Update',
method: 'POST',
useOriginalData: true,
header: {
'Content-Type': 'application/json; charset=utf-8',
}
},
});我们在Action.post的时候传输的是JSON.stringfy(param),在SystemController中是以[FromBody]的方式来接收数据,示例如下
PageSystem.js的触发请求
let t=this;
let systemConfig=t.state.systemConfig;
Actions.get(JSON.stringify(systemConfig), function(data) {
//相应的处理
}); SystemController.cs
#region Update Function
[HttpPost]
public void Update([FromBody]SystemConfig config)
{
//
}
#endregion
在salt-fetch.js中的defaultGlobalConfig中增useOriginalData
salt-fetch.js中的makeVars进行修改
对salt-fetch.js的sendajax作修改
salt-fetch.js的ajax的defaultOptions进行修改
salt-fetch.js中的ajax方法修改
修改salt-fetch.js是一个不是很恰当的处理方案,只能暂且用之。
至此SaltUI与WebApi的交互就实现了。
欢迎打描左侧二维码打赏。
转载请注明出处。

浙公网安备 33010602011771号