TP5怎么利用Restwebapi 找不到控制器器实现web和api共享返回数据

使用 Ember.js、REST API 和 SignalIR 实现实时的 Web 应用 - 技术翻译 - 开源中国社区
当前访客身份:游客 [
已有文章 2352 篇
当前位置:
使用 Ember.js、REST API 和 SignalIR 实现实时的 Web 应用
英文原文:
0人收藏此文章,
推荐于 4年前 (共 15 段, 翻译完成于 01-24) ()
参与翻译(7人):
, , , , , ,
本文涉及的源码下载:
Ember是一个强大的JavaScript MVC框架,可以用来创建复杂的web应用程序,消除了样板,并提供了一个标准的应用程序架构。支持绑定UI,视图组成,Web表示层, 和其它插件兼容性也很好。为了建立一个实时交互的web应用程序,我添加了一个SignalR中心和带有REST service的ASP.NET MVC。
&翻译的不错哦!
MVC模式的意义在于分离对视图(view),模型(model)以及控制器(Controller)的注意。模型是保持数据的部分,视图描述应用的表现(外观),而控制器起连接前二者的作用。
这是Ember.js客户端(client)部分的MVC具体实现
在Ember.js中还有另一个重要的概念:路由(Router),或者叫状态管理器(StateManager),它的作用很像ASP.NET的MVC路由,不过它是客户端的。在这篇文章中,一个路由的职责是连接主控制器与主视图。为了更简单地生成、维护视图,Ember.js使用完整的Handlebars模板。
&翻译的不错哦!
开始一个设置项目
& & 首先,我们需要新建一个空的ASP.NET MVC项目,我使用带有Razor模版引擎的ASP.NET MVC4。以下是_Layout.cshtml.
&!DOCTYPE html&
&meta charset="utf-8" /&
&meta name="viewport" content="width=device-width" /&
&title&@ViewBag.Title&/title&
&link href="../../Content/Site.css" rel="stylesheet" type="text/css" /&
&script src="../../Scripts/libs/jquery-1.7.2.min.js" type="text/javascript"&&/script&
&script src="../../Scripts/libs/json3.min.js" type="text/javascript"&&/script&
&script src="../../Scripts/libs/handlebars.min.js" type="text/javascript"&&/script&
&script src="../../Scripts/libs/ember-1.0.0-pre.2.min.js" type="text/javascript"&&/script&
@RenderBody()
&/html& 还有
Index.cshtml:
ViewBag.Title = "Ember.n.SignalR";
&div id="app"&&/div&
&script src="../../Scripts/u.js" type="text/javascript"&&/script&
&script src="../../Scripts/app.js" type="text/javascript"&&/script&
u.js 包含两个JS的方法,主要生成随机字符串和随机数
app.js 包含整个项目所以的JS文件。
&翻译的不错哦!
服务器端的模型
我们创建一个包含基础信息和用于REST方法的简单结果集的顾客 DTO (在这个例子里我们使用 DTO 作为模型) 。
Customer.cs:
[Serializable]
public class Customer
public Guid? Id { }
public string FirstName { }
public string LastName { }
public string Email { }
public string Phone { }
public bool Active { }
} Result.cs
public class Result
public int ErrorCode { }
public object ErrorMessage { }
public object Data { }
&翻译的不错哦!
REST 服务 我们已经定义了DTO,现在我们需要创建CustomerController.cs,这是customer的一个简易的由 /customer/ 来提供JSON格式数据的转换的REST 服务 。 为保证C#和JavaScript 两种语言之间Json 对象的命名一致性,我使用了 Newtonsoft.Json.Serialization和CamelCasePropertyNamesContractResolver。
public class CustomerController : Controller
[AcceptVerbs(HttpVerbs.Post)]
public string Read(Guid? id)
[AcceptVerbs(HttpVerbs.Delete)]
public string Delete(Guid id)
[AcceptVerbs(HttpVerbs.Put)]
public string Update(Customer customer)
[AcceptVerbs(HttpVerbs.Post)]
public string Create(Customer customer)
} 至于customers的数据存储,我简单实现了CustomerDS.cs将数据以二进制格式保存在
~/App_Data/Customers.em 文件中。至此服务器端需编写的代码已经完成。接下来我们将关注Ember的应用架构
&翻译的不错哦!
Ember应用 先大致了解一下Ember,创建一个ember应用对象先。
var app = Ember.Application.create({
name: "ManageCustomerApp",
rootElement: '#app',
// Extend to inherit outlet support
ApplicationController: Ember.Controller.extend(),
ready: function () {
this.initialize();
getView: function (name) {
var template = '';
url: '/Templates/' + name + '.htm',
async: false,
success: function (text) {
template =
return pile(template);
rootElement元素定义了应用出口 是Index.cshtml中该id标识的主div 这要通过扩展ApplicationController 来获得outlet支持 ready:事件,可选,需要增加额外代码时可以定义 getView:方法,这个方法通过Ajax异步的获取模板(template),然后由Handlebars将其编译为视图view
&翻译的不错哦!
Ember的模型
我们需要在客户端创建一个数据存储对象来和/customer/ REST服务交互。
// Data store
app.Store = Ember.Object.extend({
update: function (customer) {
var message =
var xhr = $.ajax(
url: '/customer/update/',
dataType: 'json',
contentType: 'application/ charset=utf-8',
data: JSON.stringify(customer),
type: 'PUT',
async: false,
success: function (data) {
if (xhr.status != 200) { // error
message = { errorCode: xhr.status, errorMessage: xhr.statusText };
read: function (id) // !id read all
var message =
var xhr = $.ajax(
url: '/customer/read/',
dataType: 'json',
contentType: 'application/ charset=utf-8',
data: JSON.stringify({ 'id': id }),
type: 'POST',
async: false,
success: function (data) {
if (xhr.status != 200) { // error
message = { errorCode: xhr.status, errorMessage: xhr.statusText };
remove: function (id) // !id delete all
var message =
var xhr = $.ajax(
url: '/customer/delete/',
dataType: 'json',
contentType: 'application/ charset=utf-8',
data: JSON.stringify({ 'id': id }),
type: 'DELETE',
async: false,
success: function (data) {
if (xhr.status != 200) { // error
message = { errorCode: xhr.status, errorMessage: xhr.statusText };
create: function (customer) {
var message =
var xhr = $.ajax(
url: '/customer/create/',
dataType: 'json',
contentType: 'application/ charset=utf-8',
data: JSON.stringify(customer),
type: 'POST',
async: false,
success: function (data) {
if (xhr.status != 200) { // error
message = { errorCode: xhr.status, errorMessage: xhr.statusText };
}); 前一部分我们已经在服务器端定义了模型,这个REST 服务仅返回JSON格式的对象,为了将其和视图绑定,我们需要定义Ember模型:
app.CustomerModel = Ember.Object.extend({
firstName: null,
lastName: null,
email: null,
phone: null,
active: false,
quiet: false,
random: function () {
this.setProperties({ firstName: String.random(), lastName: String.random(),
email: String.random().toLowerCase() + '@', phone: '(097) ' + Number.random(3) + '-' + Number.random(4) });
plain: function () {
return this.getProperties("id", "firstName", "lastName", "email", "phone", "active");
app.ResultModel = Ember.Object.extend({
errorCode: 0,
errorMessage: null
random: 使用u.js中的两个随机方法来产生随机的customer数据.
plain:& 在发送到 REST 服务之前获取JSON 对象以提升性能&(Ember.Object的附加属性则没有必要).
&翻译的不错哦!
Ember的控制器
app.CustomerController = Ember.Controller.extend({
store: app.Store.create(),
currentResult: null,
currentCustomer: null,
random: function () {
var customer = app.CustomerModel.create().random();
if (this.get('currentCustomer')) {
this.get('currentCustomer')
.set('active', false)
.setProperties(this.get('currentResult').data);
this.set('currentCustomer', customer);
create: function (customer) {
this.set('currentResult', this.get('store').create(customer.plain()));
if (!this.currentResult.errorCode) {
this.set('currentCustomer', app.CustomerModel.create());
var newCustomer = app.CustomerModel.create(this.get('currentResult').data);
this.get('customers').pushObject(newCustomer);
remove: function (id) {
var customer = this.get('customers').findProperty('id', id);
if (!customer)
this.set('currentResult', this.store.remove(customer.id));
if (!this.currentResult.errorCode) {
if (this.get('currentCustomer').id === id) {
this.set('currentCustomer', app.CustomerModel.create());
this.get('customers').removeObject(customer);
read: function (id) {
this.set('currentResult', this.store.read(id));
if (!this.currentResult.errorCode) {
if (Ember.isArray(this.currentResult.data)) { // Read all
var array = Ember.ArrayController.create({ content: [] });
this.currentResult.data.forEach(function (item, index) {
array.pushObject(app.CustomerModel.create(item));
else { // An object
var customer = this.get('customers').findProperty('id', this.currentResult.data.id)
customer && customer.setProperties(this.currentResult.data);
else { // Empty result
return id ? null : Ember.ArrayController.create({ content: [] });
update: function (customer) {
this.set('currentResult', this.store.update(customer.plain()));
if (!this.currentResult.errorCode) {
save: function (customer) {
var customer = this.get('currentCustomer');
if (!customer.id) { // create
this.create(customer);
else { // edit
this.update(customer);
edit: function (id) {
if (this.get('currentCustomer').id != id) { // Rollback
this.get('currentCustomer')
.setProperties({ active: false })
.setProperties(this.get('currentResult').data);
var customer = this.read(id);
this.set('currentCustomer', customer.set('active', true));
this.set('currentResult',
app.ResultModel.create({
errorMessage: 'Click Submit to save current customer.',
data: customer.getProperties("firstName", "lastName", "email", "phone") // Keep copy
customers: Ember.ArrayController.create({ content: [] }),
initialize: function () {
var array = this.read();
this.set('customers', array);
this.random();
this.set('currentResult', app.ResultModel.create({ errorMessage: 'Click Submit to create new customer.' }));
app.customerController = app.CustomerController.create(); 我们的customerController控制着创建,更新或者删除一个customer的逻辑,它会把每次操作的结果存入currentResult属性中,把正在编辑/正在创建的customer存入currentCustomer属性中。customers阵列模型就是我们的customers的存储,它通过app.Store与服务器一直保持同步,并用来约束我们的视图。当我们的控制器初始化的时候,我们在服务器端调用this.read()来检索所有的customers。你知道我们在这儿为什么要用set或者get方法吗?这是JavaScript中应对操纵属性变化的方式。事实上,在C#中,get/set属性会被编译成CLR中的get/set方法。
&翻译的不错哦!
Ember的视图
我们看到视图连接着控制器和模型,现在我们就来研究一下视图。视图通过控制器锚来显示/约束出入于模型的的值。我在相互分离的htm文件中定义视图模板,通过AJAX来加载它,使用Ember.Handlebars来编译响应文本,相比于把视图模板放置于脚本标签中,这种方式更易于修改,我们可以使用任何html编辑器来编辑视图模板,例如MS Visual Studio,Notepad++...。让我们来看看create_edit_customer模板,它在create_edit_customer.htm被定义了。
&div id="mainForm"&
&label for="firstName"&
First name&/label&&br /&
{{view Ember.TextField valueBinding="content.currentCustomer.firstName"}}
&a href="#" {{action "random"
on="click" target="this" }}&Random new customer&/a&
&label for="lastName"&
Last name&/label&&br /&
{{view Ember.TextField valueBinding="content.currentCustomer.lastName"}}
&label for="email"&
Email&/label&&br /&
{{view Ember.TextField valueBinding="content.currentCustomer.email"}}
&label for="phone"&
Phone&/label&&br /&
{{view Ember.TextField valueBinding="content.currentCustomer.phone"}}
&button id="submit" {{action "save"
on="click" target="this" }} &Submit&/button&
&/div& CreateEditCustomerView
app.CreateEditCustomerView = Ember.View.extend({
template: app.getView('create_edit_customer'),
contentBinding: 'controller.namespace.customerController',
name: "create_edit_customer",
save: function (event) {
this.get('content').save();
random: function () {
this.get('content').random();
&翻译的不错哦!
正如你在模板中所见,有一些Handlebars的语法存在其中,First name文本框定义为{{view Ember.TextField valueBinding="content.currentCustomer.firstName"}}。根目录约束对象,而内容则是由我们的customer控制器通过Ember的语法“contentBinding”限制的。这时候,你也许会问“它是怎么限制的?”。这就是Ember的奇妙的语法所在,我们用content+“Binding”的方式告诉Ember controller.namespace.customerController是受CreateEditCustomerView的内容属性限制的。这个视图中有两个操作,第一个就是随机生成一个新的customer,第二个就是保存一个customer,在模板中,你可以很容易的找到这两行,{{action "random" on="click" target="this" }}和{{action "save" on="click" target="this" }}。这两个操作都是单击事件。
为了显示一个customers的列表,我们需要一个模板。
&div id="customerListHeader"&
List of customers
&div id="customerListContent"&
{{#unless view.customers.length}}
&th& First name &/th&
&th& Last name &/th&
&th& Email &/th&
&th& Phone &/th&
&th& #Action &/th&
&td colspan="4" align="center"&
There is no customer yet
&th& First name &/th&
&th& Last name &/th&
&th& Email &/th&
&th& Phone &/th&
&th& #Action &/th&
{{#each view.customers}}
&tr {{bindAttr class="this.active:active:normal"}} {{bindAttr id="this.id"}}&
{{this.firstName}}
{{this.lastName}}
{{this.email}}
{{this.phone}}
&td align="center"&
&a href="#" class="edit" {{action "edit"
on="click" target="this" }} {{bindAttr value="this.id"}}&Edit&/a&
&a href="#" class="delete" {{action "remove"
on="click" target="this" }} {{bindAttr value="this.id"}}&Delete&/a&
{{/unless}}
CustomerListView
app.CustomerListView = Ember.View.extend({
contentBinding: 'controller.namespace.customerController',
customersBinding: 'controller.namespace.customerController.customers',
template: app.getView('customer_list'),
name: "customer_list",
edit: function (event) {
var id = $(event.target).attr('value');
var controller = this.get('content').edit(id);
remove: function (event) {
var id = $(event.target).attr('value');
var controller = this.get('content');
this.animateItem(id, function () {
controller.remove(id);
}, controller);
animateItem: function (id, callback, target) {
$('#' + id).animate({ opacity: 0 }, 200, "linear", function () {
$(this).animate({ opacity: 1 }, 200);
if (typeof callback == 'function') {
target = target |
callback.call(target);
}); 对于每个创建/编辑/删除customer的操作,我们都需要显示消息结果,以下就是MessageView中的消息模板。
{{#unless content.currentResult.errorCode}}
&div id='message'&
{{content.currentResult.errorMessage}} &
&div id='error'&
{{content.currentResult.errorMessage}} &
{{/unless}} 这个视图不进行任何操作。
app.MessageView = Ember.View.extend({
template: app.getView('message'),
name: "message"
}); CreateEditCustomerView,CustomerListView和MessageVieware共同组成ApplicationView,main.htm中定义了模板。
&h3&{{view.Title}}&/h3&
&div id="message"&
{{view App.MessageView}}
&div id="createEditCustomer"&
{{view App.CreateEditCustomerView}}
&div id="customerList"&
{{view App.CustomerListView}}
&div id="footer"&
app.ApplicationView = Ember.View.extend({
Title: "Example of Ember.js application",
template: app.getView('main'),
name: "ApplicationView"
&翻译的不错哦!
Ember的路由
我们已经创建了应用的控制器、视图和模型,但还需要路由类让应用运行起来。路由负责连接应用的控制器到视图,按顺序初始化应用控制器,应用视图被绑定或渲染到页面。现在,用户就可以浏览和操作视图并从控制器返回对应结果。
// Router, this need to connect view and controller
app.Router = Ember.Router.extend({
root: Ember.Route.extend({
defaults: Ember.Route.transitionTo('index'),
index: Ember.Route.extend({
route: '/',
connectOutlets: function (router) {
var controller = router.get('applicationController');
var context = app.customerC
context.initialize();
controller.connectOutlet('application', context); // connectOutlet(nameOfView without suffix *view, controller)
&翻译的不错哦!
嵌入 SignalIR
VS可以使用(VS的第三方库类安装工具)安装SignalIR:
Install-Package Microsoft.AspNet.SignalR -pre RegisterHubs.cs已经自动添加到目录App_Start中。
using System.W
using System.Web.R
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hosting.AspN
[assembly: PreApplicationStartMethod(typeof(Ember.n.SignalR.RegisterHubs), "Start")]
namespace Ember.n.SignalR
public static class RegisterHubs
public static void Start()
// Register the default hubs route: ~/signalr/hubs
RouteTable.Routes.MapHubs();
} 我们使用Hub类(Microsoft.AspNet.SignalR.Hubs)代替永久连接,使所有客户更容易与服务端创建连接。
namespace Ember.n.SignalR.Hubs
using Ember.n.SignalR.DTOs;
using Microsoft.AspNet.SignalR.H
using Newtonsoft.J
using Newtonsoft.Json.S
using Microsoft.AspNet.SignalR;
public class CustomerHub : Hub
public static IHubContext Instance
return GlobalHost.ConnectionManager.GetHubContext&customerhub&();
JsonSerializerSettings _settings = new JsonSerializerSettings
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore
public void Add(Customer customer)
Clients.All.add(JsonConvert.SerializeObject(customer, _settings));
public void Update(Customer customer)
Clients.All.update(JsonConvert.SerializeObject(customer, _settings));
public void Remove(Customer customer)
Clients.All.remove(JsonConvert.SerializeObject(customer, _settings));
} 为了让客户端连接到SignalIR通道。我们需要引入Hub类,并在客户端实现customHub类。
&script src="/signalr/hubs " type="text/javascript"&&/script&
(function (app) {
var hub = $.connection.customerH
function findCustomer(id) {
var c = app.customerController.get('customers').findProperty('id', id);
hub.client.add = function (message) {
var customer = JSON.parse(message);
var c = findCustomer(customer.id);
!c && app.customerController.get('customers').pushObject(app.CustomerModel.create(customer));
hub.client.update = function (message) {
var customer = JSON.parse(message);
var c = findCustomer(customer.id);
c && c.set('quiet', true) && c.setProperties(customer) && c.set('quiet', false);
hub.client.remove = function (message) {
var customer = JSON.parse(message);
var c = findCustomer(customer.id);
if (c.id === app.customerController.get('currentCustomer').id) {
app.customerController.set('currentCustomer', null);
app.customerController.random();
app.customerController.get('customers').removeObject(c);
$.connection.hub.start();
})(window.App);
我们可以更简便的通过customerController操作models。Ember.js binding(数据绑定)会自动处理Rest连接,并保持UI及时反应models的修改。
&翻译的不错哦!
Ember的观察者
之前的内容里,用户可以通过SignalIR实时与服务端交互。更有趣的是,我们使用Ember的观察者侦听用户键入后的属性值变化,并通过customerHub反馈服务端。之后服务端广播所有用户修改的内容。为CustomerModel添加几行代码实现上述功能:
propertyChanged: function () {
if (!this.get('quiet') && this.get('id')) {
app.hub.server.update(this.plain());
catch (e) {
} .observes('firstName', 'lastName', 'email', 'phone', 'active'),
现在我们只是反馈服务端存在用户的firstName、lastName、email、phone和一些有效属性。静默检测防止服务端和客户端之间反复重复反馈,即当从服务端获取到修改,客户端不会(因为有修改)反馈到服务端。
&翻译的不错哦!
现在可以运行Web应用了。随机创建一个customer提交。如果界面UI自动更新,没有任何手动DOM操作。点击edit链接就可以修改first name等。下表的文本框和可编辑行会立即反应我们写入的内容。
为了体验Ember.js如何与SignalIR交互,复制窗口的URL到另一个浏览器窗口。并排摆好窗口,在其中一个里创建/编辑/删除customer,另一个窗口也会立刻变化,就像镜像。这真酷!
&翻译的不错哦!
Ember.js 中的控制器,视图,模型和路由器其实跟ASP.NET MVC非常相似, 所以那些用过ASP.NET MCV的人可能很容易的理解和从中受益. 这篇文章仅仅只是对Ember.js的一个大概介绍, 如果想要开发一个复杂和实时的web应用程序, 我们就必须更深入地去研究Ember对象, 这个例子中的SignalR就像一个桥接器, 它很好的保证了模型在客户端和服务器保持同步.
这篇文章,还有其中涉及到的代码和文件,全部都遵循
&翻译的不错哦!
不错,正常在找相关学习资料如何使用 Web API 来对 MVC 应用程序进行身份验证_百度知道
如何使用 Web API 来对 MVC 应用程序进行身份验证
提问者采纳
&3FFA12388DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA213F22AD27E8FAD77DCFEE908D193A17C1FC8DCE51B71A4AE54920&quot.IndexOf(&true&quot、密码是否正确; decryptionKey=& validation=&quot.R&lt、WebApi服务端W&#47.UserDLogin&quot, Version=4; validation=&;//return true:&machineKey validationKey=&public class BasicAuthenticationAauthentication&gt.AppSettings[&if (isRquired){/system.Any(a =&}}}//4.AuthCookie&&lt.D);/ECB6A3AF9ABBF3F16E8B0B13CCEE538EBBA97D0BB& 检查用户是否有该Action执行的操作权限&#47,并校验用户名密码是否匹配var encryptTicket = actionC//ECB6A3AF9ABBF3F16E8B0B13CCEE538EBBA97D0BB&&lt. 其它配置说明1);private bool ValidateUserTicket(string encryptTicket){var userTicket = FormsAuthentication.GetCustomAttributes().Unauthorized);bool isAnonymous =检查用户名; &#47.A&#47.5&forms&gt.config配置是否要求权限校验bool isRquired = (WebConfigurationM&//&/&Forms&quot.Unauthorized).Decrypt(encryptTicket);AES&if (ValidateUserTicket(encryptTicket))&#47.Config 配置[html] view plaincopy&/SPAN&gt.OfType();&/ 基本验证A/// /&//httpRuntime targetFramework=&/WebApiAuthenticatedFlag&) + 1);SPAN&/elseactionC&#47, password):&SPAN&/如果请求Header不包含SPAN&gt.Http,用户ticket信息来自调用发起方if (actionCSPAN&/add assembly=&quot.Response = new HttpResponseMessage(HttpStatusCode: ActionFilterAttribute{&#47.HSPAN&/id3 not found&public override void OnActionExecuting(HttpActionContext actionContext){/,则继续执行; timeout=&quot.Authorization , userTicketDif (p == null){throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.5&authentication mode=&&#47.0;&~//machineKey validationKey=&&#47.W检查&&#47.web&&elseactionC&// Controller的基类;/&#47.Response = new HttpResponseMessage(HttpStatusC//&}/SPAN& a is AllowAnonymousAttribute);SPAN&gt,验证是合法用户/var p = ProductServiceI/ GET api/true&&&SPAN&assemblies&system, ReasonPhrase = &&lt.BadRequest)Content = new StringContent(&machineKey节点配置; 校验用户ticket信息/&&lt.ActionD&#47,用于实现适合业务场景的基础功能/&lt.R5[HttpGet][AllowAnonymous]public Product Get(string id){var headers = R&gt.H&#47, PublicKeyToken=31bf&)。2);var userTicketData = userT&#47.IndexOf(&&var isQuilified = CheckUser(userN&#47.Substring(0;/product/All&&/&//));}}4;//&#47.web&gt.0;/Account/&/4: ApiControllerBase{[HttpGet]public object Find(string id){return ProductServiceI decryption=&是匿名用户;/SPAN&/&lt.ToString() == &product id not exist;非匿名用户; decryption=&quot.GetById(long.P targetFramework=&SPAN&gt!= null){&#47.&&#47.web&gt.0;[BasicAuthentication]public abstract class ApiControllerB~/compilation debug=& });SPAN&/ decryptionKey=&assemblies&gt: ApiController{}2 权限属性BaseAuthenticationAttribute[csharp] view plaincopy&#471 控制器基类ApiControllerBase[csharp] view plaincopy/machineKey节点配置; protection=&Index&quot、 Mvc前端Web.Config配置[html] view plaincopy&/&#47.Substring(userTicketD&/forms loginUrl=&//string password = userTicketD&#47, Culture= &#47,则判断是否是匿名调用var attr = actionCSPAN&&}}3 api服务Controller实例[csharp] view plaincopypublic class ProductController ,抛出“未授权访问”信息if (isAnonymous)/AES&//SHA1&&Home&#47,是应用于对用户ticket数据加密和解密;}&/SPAN&&}else{SPAN&gt.web&gt.OnActionExecuting(actionContext);SPAN&; name=&3FF112388DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA213F22AD27E8FAD77DCFEE908D193A17C1FC8DCE51B71A4AE54920&}else{/&/// defaultUrl=&&#47.OnActionExecuting(actionContext); /string userName = userTicketDSHA1&quot,是应用于对用户ticket数据加密和解密;/&S/&#47.Parse(id));90&&&compilation&检验用户ticket信息;].OnActionExecuting(actionContext).H&lt.Find(2);解密用户&lt.H&#47,用以Action的权限处理/&#47
中国移动互联网研发培训领导品...
主营:iOS、Android、HTML5、UI、PHP、Java培训
其他类似问题
为您推荐:
mvc的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 tplink无线控制器设置 的文章

 

随机推荐