Backbonejs更新Model,idAttribute设置为Id

时间:2012-03-26 20:53:48

标签: asp.net-mvc backbone.js

我正在尝试更新骨干模型,服务器端是asp.net mvc 4.我得到了:

  

“System.ArgumentException:已添加具有相同键的项目”异常。

原因是因为骨干网将Id和id作为属性发送到服务器, JsonValueProvider 尝试将其添加到字典中。

这是我的模特:

 var Task = Backbone.Model.extend({
        url: "/tasks/task",
        idAttribute: "Id"
 });

这是通过Put请求发送到服务器:

{"Id":294912,"Task":"test","DueDate":"2012-03-24T02:00:00.000Z", "id":294912}

有没有办法阻止骨干发送“id”属性?

2 个答案:

答案 0 :(得分:3)

这里的问题是因为C#中的约定与JavaScript中的约定不同。在C#中,类具有以大写字母开头的属性(Pascal Case),它是JavaScript中以小写字母(Camel Case)启动属性的标准。​​

因此,在序列化视图模型时,JSON.NET序列化程序的默认行为是使用相同的属性大小来完全序列化对象。我可以将视图模型上的属性重命名为驼峰大小写,但是在JavaScript对象中使用pascal大小写属性会“奇怪”。

因此,为了强制Backbone成为非常规方式,我改变了对象的序列化,通过利用JSON.NET's Contract Resolver功能将Pascal案例属性转换为Camel案例属性。

var settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
JsonSerializer serializer = JsonSerializer.Create(settings);

JsonConvert.SerializeObject(object, Formatting.None, settings);

现在,这会在我的代码和所有酷库中创建客户端的一致性。

答案 1 :(得分:0)

听起来像我的服务器端代码中的问题,而不是来自Backbone的调用。 PUT是服务器上的编辑操作,因此您正在更新现有实体。您需要ID属性来标识服务器上的模型并更新已更改的属性。

如果ASP.NET MVC抱怨模型已存在于数据库中,那么您正尝试执行INSERT而不是UPDATE。我们需要查看控制器和数据访问代码,以查看出错的地方。

更新:如果您取消idAttribute财产会怎样?来自Backbone文档:

A special property of models, the id is an arbitrary string (integer id or UUID). 
If you set the id in the attributes hash, it will be copied onto the model as a 
direct property.

默认情况下应发送id属性;看起来你强迫它第二次加入。

在文档中的idAttribute下:

A model's unique identifier is stored under the id attribute. If you're directly communicating 
with a backend (CouchDB, MongoDB) that uses a different unique key, you may set a Model's 
idAttribute to transparently map from that key to id.

ASP.NET MVC的模型绑定应该能够应对idId的对比。

更新:找到一个好的blog post,它描述了使用视图模型来帮助将C#对象序列化为Backbone期望的格式。这似乎是一个合理的,如果有点烦人的解决方案。