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的交互就实现了。
欢迎打描左侧二维码打赏。
转载请注明出处。