Asp.net mvc 3 带有ASP.NET MVC 3的Backbone.js REST URL
我最近一直在研究,现在我正试图将它与我的服务器端asp.net mvc 3连接起来 这就是我发现问题的时候。ASP.NET侦听不同的操作,例如:Asp.net mvc 3 带有ASP.NET MVC 3的Backbone.js REST URL,asp.net-mvc-3,rest,backbone.js,Asp.net Mvc 3,Rest,Backbone.js,我最近一直在研究,现在我正试图将它与我的服务器端asp.net mvc 3连接起来 这就是我发现问题的时候。ASP.NET侦听不同的操作,例如:POST/Users/Create,而不仅仅是POST/Users/。因此,backbone.js中的Model.Save()方法将无法工作 我们应该如何解决这个问题?我必须重写主干网.Sync吗?你要么告诉ASP.NET MVC路由正确的REST URL,要么修复主干网.Sync,以便它在正确的URL发送GET/POST请求 主干网使用REST而不是R
POST/Users/Create
,而不仅仅是POST/Users/
。因此,backbone.js中的Model.Save()
方法将无法工作
我们应该如何解决这个问题?我必须重写主干网.Sync吗?你要么告诉ASP.NET MVC路由正确的REST URL,要么修复主干网.Sync,以便它在正确的URL发送GET/POST请求 主干网使用REST而不是RESTful URL。不过,可能存在与URL匹配的Backbone.sync的操作系统实现 推荐更适合主干网的URL:
GET /forums -> index
GET /forums/new -> new
POST /forums -> create
GET /forums/:forum -> show
GET /forums/:forum/edit -> edit
PUT /forums/:forum -> update
DELETE /forums/:forum -> destroy
答案是不要覆盖Backbone.sync。你很少会想这样做。相反,您只需要利用模型的url属性,在该属性中可以分配一个返回所需url的函数。比如说,
Forum = Backbone.Model.extend({
url: function() {
return this.isNew() ? '/Users/Create' : '/Users/' + this.get('id');
}
});
其中,用于模型的url根据模型是否为新的而变化。如果我没看错你的问题,这就是你所需要做的 我最近写了一篇文章,描述了如何将.NET MVC绑定到默认主干服务层
正如前面的海报所提到的,你可以采取很多方法。我更喜欢这种方法,因为它只需要很少的配置
控制员:
骨干
我在中找到了以下代码
//
ModelBase=Backbone.Model.extend({
默认值:{
id:null
},
url:函数(类型){
//服务器上应具有以下约定:
//urlRoot应该是控制器:controller/
//创造→ 员额/行动
//阅读→ 获取/操作[/id]
//更新→ PUT/action/id
//删除→ 删除/action/id
var fqUrl=this.urlRoot;
开关(类型){
案例“职位”:
fqUrl+=“创建”;
打破
案例“付诸表决”:
fqUrl+=“更新”;
打破
案例“删除”:
fqUrl+=“delete/”+this.get('id');
打破
案例“GET”:
fqUrl+=“read/”+this.get('id');
打破
}
返回fqUrl;
}
});
var methodMap={
“创建”:“发布”,
'update':'PUT',
'删除':'删除',
“读取”:“获取”
};
//Helper函数从模型或集合中获取URL作为属性
//或者作为一种功能。
var getUrl=函数(对象){
if(!(object&&object.url))返回null;
返回u.isFunction(object.url)?object.url():object.url;
};
//当需要URL但未提供URL时引发错误。
var urlError=函数(){
抛出新错误(“必须指定“url”属性或函数”);
};
Backbone.sync=函数(方法、模型、选项){
var type=methodMap[method];
options.url=\ uu.isString(this.url)?this.url:this.url(type);
//默认JSON请求选项。
变量参数=389;.extend({
类型:类型,
数据类型:“json”
},选项);
//确保我们有一个URL。
如果(!params.url){
params.url=getUrl(模型)| | urlError();
}
//确保我们拥有适当的请求数据。
如果(!params.data&&model&&(method='create'| | method==''update')){
params.contentType='application/json';
params.data=JSON.stringify(model.toJSON());
}
//对于较旧的服务器,通过将请求编码为HTML表单来模拟JSON。
if(主干网仿真EJSON){
params.contentType='application/x-www-form-urlencoded';
params.data=params.data?{model:params.data}:{};
}
//对于较旧的服务器,通过使用`\u方法模拟HTTP方法来模拟HTTP`
//和“X-HTTP-Method-Override”头。
if(主干网仿真EHTTP){
如果(类型=='PUT'| |类型=='DELETE'){
if(Backbone.emulateJSON)params.data.\u method=type;
params.type='POST';
params.beforeSend=函数(xhr){
setRequestHeader('X-HTTP-Method-Override',类型);
};
}
}
//不要处理非GET请求上的数据。
if(params.type!=“GET”&&&!Backbone.emulateJSON){
params.processData=false;
}
//提出请求。
返回$.ajax(参数);
};
我一直认为ASP.NET MVC对RESTful URL的实现非常可靠?有人以前做过这件事吗?我应该怎么做,改变主干网同步还是MVC路由?@Anders这是你必须做出的选择。取决于你想要什么网址。(更新答案)。@Anders Raynos是对的。。。“标准”REST是使用映射到对象/名词的路由,让您的“操作”通过用于访问它们的HTTP谓词隐式应用<代码>/users/create则不是REST。。。它试图是“REST-like”或“RESTful”,但不是因为POST
是唯一适用的动词。GET被用来获取一个表单来创建一个用户,而不是获取一个用户对象,PUT和DELETE没有任何意义。创建一个可以使用的RESTAPI,并按照预期的方式使用主干网。这是重写服务器端内容的一个很好的替代方案。谢谢这仍然有点像是一种黑客/变通方法。雷诺斯在下面有一个更合适的答案。同意。更喜欢兼容的URL,但是,如果您没有控制权,那么上面的方法就是您剩下的。当我回答这个问题时,我意识到了这种僵化。为什么不仅仅是POST/users/?ASP.NETMVC不会阻止你。虽然可以做到这一点,但标准的方法是发布到你所在的同一个url。Som如果我正在创建一个用户,我将打开/user/create。但是正如您所说,如果您也需要的话,这可能会起作用。这在新的MVC4WebAPI中处理得更好。我会建议其他人看看这看起来是一个很好的处理方式!还有人有经验吗
public class ZocController : Controller
{
public ActionResult Docs()
{
return Json(GetDocs(), JsonRequestBehavior.AllowGet);
}
[ActionName("Docs")]
[HttpPost]
public ActionResult HandlePostDoc(Doctor doc)
{
doc.id = Guid.NewGuid();
CreateDoc(doc);
return Json(doc);
}
[ActionName("Docs")]
[HttpPut]
public ActionResult HandlePutDoc(Doctor doc)
{
UpdateDoc(doc);
return new EmptyResult();
}
[ActionName("Docs")]
[HttpDelete]
public ActionResult HandleDeleteDoc(Guid id)
{
DeleteDoc(id);
return new EmptyResult();
}
}
window.Doctor = Backbone.Model;
window.Doctors = Backbone.Collection.extend({
model: Doctor,
url: '/zoc/docs'
});
/// <reference path="backbone.js" />
ModelBase = Backbone.Model.extend({
defaults: {
id: null
},
url: function (type) {
//expecting the following conventions on the server:
//urlRoot should be the controller : controller/
//create → POST /action
//read → GET /action[/id]
//update → PUT /action/id
//delete → DELETE /action/id
var fqUrl = this.urlRoot;
switch (type) {
case "POST":
fqUrl += "create";
break;
case "PUT":
fqUrl += "update";
break;
case "DELETE":
fqUrl += "delete/" + this.get('id');
break;
case "GET":
fqUrl += "read/" + this.get('id');
break;
}
return fqUrl;
}
});
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read': 'GET'
};
// Helper function to get a URL from a Model or Collection as a property
// or as a function.
var getUrl = function (object) {
if (!(object && object.url)) return null;
return _.isFunction(object.url) ? object.url() : object.url;
};
// Throw an error when a URL is needed, and none is supplied.
var urlError = function () {
throw new Error('A "url" property or function must be specified');
};
Backbone.sync = function (method, model, options) {
var type = methodMap[method];
options.url = _.isString(this.url) ? this.url : this.url(type);
// Default JSON-request options.
var params = _.extend({
type: type,
dataType: 'json'
}, options);
// Ensure that we have a URL.
if (!params.url) {
params.url = getUrl(model) || urlError();
}
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (Backbone.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? { model: params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (Backbone.emulateHTTP) {
if (type === 'PUT' || type === 'DELETE') {
if (Backbone.emulateJSON) params.data._method = type;
params.type = 'POST';
params.beforeSend = function (xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
};
}
}
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !Backbone.emulateJSON) {
params.processData = false;
}
// Make the request.
return $.ajax(params);
};