【问题标题】:Passing complex knockout observable array to Web Api将复杂的淘汰赛可观察数组传递给 Web Api
【发布时间】:2014-06-13 00:57:11
【问题描述】:

我有一个使用淘汰赛和 Web Api 2 的 MVC 5 项目。

我已经实现了分页,我的淘汰模型最初由第一页和底部的分页填充。允许用户导航到结果集中的其他页面。

代码如下:

选中复选框时将照片 ID 推送到可观察数组的 HTML 标记:

<span>Add</span><input type="checkbox" class="photo" name="selected-photos" id="selected-photos" data-bind="checked:$root.selectedPhotos, checkedValue: $data.PhotoId" />

淘汰视图模型

function FlickrPhotosViewModel() {

    var self = this;

    self.photos = ko.observableArray([]);
    self.noOfPages = ko.observable();

    self.selectedPhotos = ko.observableArray([]);

    self.pageNumber = ko.observable(1);
    self.selectPage = function(pageNumber) {

        jQuery.support.cors = true;
        $.ajax({
            url: '@Url.RouteUrl("DefaultApi", new {httproute = "", controller = "PhotosFromFlickr"})',
            type: 'GET',
            data: { pageNumber: ko.toJSON(pageNumber), selectedPhotos: ko.toJSON(self.selectedPhotos()) },
            dataType: 'json',
            success: function(data) {
                self.photos(ko.mapping.fromJS(data.Photos));
                self.noOfPages(data.NoOfPages);
                self.selectedPhotos(data.SelectedPhotos);
            },
            error: function(x, y, z) {
                alert(x + '\n' + y + '\n' + z);
            }
        });
    };

    jQuery.support.cors = true;

    $.ajax({
        url: '@Url.RouteUrl("DefaultApi", new {httproute = "", controller = "PhotosFromFlickr"})',
        type: 'GET',
        data: { pageNumber: ko.toJSON(self.pageNumber()), selectedPhotos: ko.toJSON(self.selectedPhotos()) },
        dataType: 'json',
        success: function (data) {
            self.photos(ko.mapping.fromJS(data.Photos));
            self.noOfPages(data.NoOfPages);
        },
        error: function (x, y, z) {
            alert(x + '\n' + y + '\n' + z);
        }
    });
};

$(document).ready(function () {
    ko.applyBindings(new FlickrPhotosViewModel());
});

Web API 获取方法 这目前有两个参数,第一个是我要提供的页码,第二个是选定的照片 ID,当前作为字符串传递。

public PhotoCollectionModel Get(int pageNumber, string selectedPhotos )
    {}

我遇到的问题是我希望第二个参数是强类型的。或者至少列出选定的照片。目前我不得不在 Web Api Get 方法中反序列化 json 字符串(selectedPhotos)...

这是可能的还是我错过了重点?

更新

这是它创建的请求 url -

http://localhost/Mvc/api/PhotosFromFlickr?pageNumber=3&selectedPhotos=%5B%228060459369%22%2C%227895411674%22%2C%227067757145%22%5D

标题是:

Request Headers :

Accept:application/json, text/javascript, */*; q=0.01
Referer:http://localhost/Mvc/Profile?username=MarkHBrown
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36
X-Requested-With:XMLHttpRequest

【问题讨论】:

    标签: asp.net-mvc knockout.js asp.net-web-api asp.net-web-api2 knockout-3.0


    【解决方案1】:

    Web API 应该可以与您的代码一起正常工作,但您也应该更改操作参数..

    public PhotoCollectionModel Get([FromUri]int pageNumber, [FromUri]IEnumerable<Photo> selectedPhotos )
        {}
    

    其中 photo 是与 javascript 中类型的结构相匹配的类型...或者如果您只是发送照片的 ID,那么类似以下的内容应该没问题...

    public PhotoCollectionModel Get([FromUri]int pageNumber, [FromUri]IEnumerable<int> selectedPhotos)
        {}
    

    【讨论】:

    • 由于某种原因这不起作用。 selectedPhotos 的值为空...我认为完全一样,它会工作。
    • 你能发布获取请求的内容吗?在发送到服务器时查看 JSON 的结构会很有用。
    • 更新添加了请求 url 和请求标头。
    • 如果数据来自 URL,则需要用 [FromUrl] 修饰参数
    • 啊,是的,从请求中可以明显看出这一点!编辑了我的答案!
    【解决方案2】:

    如前所述,您必须使用[FromUri] 属性来装饰方法参数。此外,您可以在查询字符串中传递数组,如下所示:?selectedPhotos=[1,2,3]

    正确的方法是?selectedPhotos=1&amp;selectedPhotos=2&amp;selectedPhotos=3

    【讨论】:

    • 谢谢。我是否必须遍历我的 observableArray 才能手动为 url 建立 selectedPhotos 参数?
    • 你可以使用jQuery.param(arr, true)函数。 api.jquery.com/jquery.param
    【解决方案3】:

    我已经设法让它按照我最初的要求工作。

    我希望能够传递我提交时已选择的复杂照片对象。为此,我不得不不使用 GET(因为它使用查询字符串)而使用 POST。

    我将 pageNumber 保留在 url 中,并通过我的 jQuery ajax 调用的 data 参数在请求正文中传递 observableArray。

    代码如下:

    Web API 发布方法

    public PhotoCollectionModel Post([FromUri]int pageNumber, [FromBody]Photo[] selectedPhotos)
        {}
    

    jQuery ajax Post - 通过附加到 html 元素上的点击事件的敲除函数调用

    self.selectedPhotos 在本例中是一个对象 (Photo) 类型的数组。

    jQuery.support.cors = true;
                    $.ajax({
                        url: '@Url.RouteUrl("DefaultApi", new {httproute = "", controller = "PhotosFromFlickr"})/?pageNumber=' + pageNumber,
                        type: 'POST',
                        data: ko.toJSON(self.selectedPhotos),
                        dataType: 'json',
                        contentType: 'application/json; charset=utf-8',
                        success: function (data) {
                            self.photos(ko.mapping.fromJS(data.Photos));
                            self.noOfPages(data.NoOfPages);
                        },
                        error: function (x, y, z) {
                            alert(x + '\n' + y + '\n' + z);
                        }
                    });
    

    我的复选框标记

    <span>Add</span><input type="checkbox" class="photo" name="selected-photos" id="selected-photos" data-bind="data-bind="checkedValue: $data, checked: $root.selectedPhotos" />" />
    

    我现在遇到的问题是,在分页时,它不会在返回到前一页时保持选中状态...但是如果我将照片 ID 存储在可观察数组中,则此方法有效。

    话虽如此 - 如果您没有分页,这是一个很好的解决方案......

    【讨论】:

      猜你喜欢
      • 2012-09-08
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 2014-11-05
      相关资源
      最近更新 更多