c# - knockout : Posting complex type to MVC controller query

标签 c# asp.net-mvc knockout.js

我已经为此奋斗了 3 天。 基本上,我有一个发布到 MVC Controller 的 javascript 对象。检查 Request.Form.AllKeys namevalueCollection 中的属性键名称后,我注意到我的子属性被 [] 包围并且 MVC 模型绑定(bind)器不绑定(bind)这些值。

The values coming through on the controller look like this:

[6]: "Metadata[ScreenResolution]"
[7]: "Metadata[AudioCodec]"
[8]: "Metadata[VideoCodec]"
[9]: "Metadata[Format]"

My question is why is this happening. 
Edit: The "first-level properties are binding successfully, In the javascript, when the javascript object is being created, all the properties are being set correctly from KO"

MVC Model:

public class Movie
    {
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        public string Directors { get; set; }

        public string Description { get; set; }

        public int GenreId { get; set; }

        public int YearId { get; set; }

        public MovieMetadata Metadata { get; set; }

        public int RatingId { get; set; }

        public string MovieUrl { get; set; }        

        public string Stars { get; set; }

        public string Duration { get; set; }       
    }

 public class MovieMetadata
    {

        public int Id { get; set; }

        public string ScreenResolution { get; set; }

        public string VideoCodec { get; set; }

        public string AudioCodec { get; set; }

        public int FormatId { get; set; }
    }

Knockout Js file:

var SimpleModelLoading = function (data) { //data: this is JSON result coming back form the action method
    var self = this;
    self.MovieModel = {};

    self.MovieName = ko.observable(data.Name);
    self.Description = ko.observable(data.Description);
    self.Directors = ko.observable(data.Directors);
    self.MovieUrl = ko.observable(data.MovieUrl);
    self.Stars = ko.observable(data.Stars);
    self.Duration = ko.observable(data.Duration);

    self.ScreenResolution = ko.observable(data.Metadata.ScreenResolution);
    self.AudioCodec = ko.observable(data.Metadata.AudioCodec);
    self.VideoCodec = ko.observable(data.Metadata.VideoCodec);    

    self.selectedGenre = ko.observable();
    self.selectedYear = ko.observable();
    self.selectedRating = ko.observable();
    self.selectedFormat = ko.observable();

    self.MovieModel = ko.computed(function () {
        var movieModel =
        {
            Name: self.MovieName(),
            Description: self.Description(),
            GenreId: self.selectedGenre() == undefined ? undefined : self.selectedGenre().Key,
            YearId: self.selectedYear() == undefined ? undefined : self.selectedYear().Key,
            RatingId: self.selectedRating() == undefined ? undefined : self.selectedRating().Key,
            Directors: self.Directors(),
            Stars: self.Stars(),
            MovieUrl: self.MovieUrl(),
            Duration: self.Duration(),    
        };

        movieModel.Metadata =
        {
            ScreenResolution: self.ScreenResolution(),
            AudioCodec: self.AudioCodec(),
            VideoCodec: self.VideoCodec(),
            Format: self.selectedFormat() == undefined ? undefined : self.selectedFormat().Key
        };

        return movieModel;
    }, self);

    self.Genres = data.LookupData.Genre;
    self.Year = data.LookupData.Year;
    self.Rating = data.LookupData.Rating;
    self.Format = data.LookupData.Format;

    self.saveMovie = function () {
        var url = "/Movie/SaveMovie";

        $.ajax(
            {
                url: url,
                data: self.MovieModel(),
                type: "POST",
                success: function () {
                    alert('save successful');
                },
                error: function (xhr) {
                    alert(xhr.responseText);
                }
            });
    };
};

Movie View:

<div>
    <form method="POST">
        <div data-role="collapsible" data-collapsed="false" id="movieInfoContainer">
            <h2>Add New Video</h2>
            @* <div data-role="collapsible" data-collapsed="false">
                <h3>Movie Details</h3>
                   <div id="movieInfo">
                @Html.Partial("MovieDetails")
            </div>
            </div>*@

            <div data-role="collapsible" data-collapsed="true" id="movieMetadataContainer">
                <h3>Technical Specifications</h3>
                <div id="movieMetadata">
                    @Html.Partial("MovieMetadataDetails")
                </div>
            </div>
        </div>

        <p>
            <button data-bind="click: saveMovie">Save</button>
        </p>
    </form>
</div>

Movie Metadata View:

<p>
    Audio Encoding:<input data-bind="value: AudioCodec" />
</p>
<p>
    Video Encoding:<input data-bind="value: VideoCodec" />
</p>

<p>
    Screen Resolution:<input data-bind="value: ScreenResolution" />
</p>

<div class="clearSpaceLine"><span>Format:</span></div>
<select data-bind="options: Format, value: selectedFormat, optionsText: 'Value'"></select>
<br />

最佳答案

您直接发布了可观察对象,但嵌套在其中的可观察对象是函数,而不是数据。

尝试替换这个

data: self.MovieModel(),

有了这个

data: ko.toJSON(self.MovieModel()),

关于此的更多信息 here

关于c# - knockout : Posting complex type to MVC controller query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20871953/

相关文章:

c# - Parallel.ForEach 错误 HttpContext.Current

javascript - Knockout Js绑定(bind)列表选项选择与选项组

javascript - Knockout中绑定(bind)数据后获取数据

javascript - 使用 Knockout JS 进行数据绑定(bind)

c# - 在 asp.net-mvc 中,让 Base ViewModel 在 Site.Master 页面上显示动态内容的最佳方式是什么

c# - 你如何从 GAC 获得不同的版本

C# 获取 SQL 查询返回的数据大小

c# - 将类型转换为我的自定义枚举

c# - 操作无法完成,因为 DbContext 已被释放

asp.net-mvc - 我可以对单个 RESTful Url 的 POST 和 GET 使用两种不同的模型吗?