Подтвердить что ты не робот

URL-адрес REST URL-адреса Backbone.js с ASP.NET MVC 3

В последнее время я искал Backbone.js, и теперь я пытаюсь подключить его к серверной стороне asp.net mvc 3.

Это когда я обнаружил проблему. ASP.NET прослушивает разные действия, Ex: POST /Users/Create, а не только POST /users/. Из-за этого метод Model.Save() в backbone.js не будет работать.

Как мы должны решить эту проблему? Нужно ли переписывать Backbone.Sync?

4b9b3361

Ответ 1

Ответ не на переопределение Backbone.sync. Вы редко захотите это сделать. Вместо этого вам нужно использовать только свойство url модели, где вы можете назначить функцию, которая возвращает нужный URL. Например,

Forum = Backbone.Model.extend({

  url: function() {
    return this.isNew() ? '/Users/Create' : '/Users/' + this.get('id');
  }

});

где URL-адрес, используемый для модели, зависит от того, является ли модель новой. Если я правильно прочитаю ваш вопрос, это все, что вам нужно сделать.

Ответ 2

Вам либо нужно указать ASP.NET MVC для маршрутизации правильных URL-адресов REST, либо исправить Backbone.sync, чтобы он отправлял запросы GET/POST на соответствующие URL-адреса.

Магистраль работает с REST не с URL RESTful. Возможно, существует реализация ОС Backbone.sync, которая соответствует вашим URL.

Рекомендуйте URL-адреса, которые лучше сочетаются с Backbone:

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

Ответ 3

Я написал сообщение в блоге, в котором недавно описывалось, как привязать .NET MVC к уровню службы Backbone по умолчанию.

Как и предыдущие плакаты, есть несколько подходов, которые вы могли бы предпринять. Я предпочитаю этот подход, потому что он требует небольшой конфигурации.

Контроллер:

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'

});

Ответ 4

я нашел следующий код в https://github.com/sgentile/BackboneContacts

    /// <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);
};