javascript - C# Web API 中的 JSON 数据无法正确解析

标签 javascript json web knockout.js asp.net-web-api

我目前正在在线学习使用 Web API 创建电话目录的教程。一切都工作正常,直到我开始使用 javascript 和 Knockout.js 来绑定(bind)我的 View 模型。现在没有数据加载到页面上。

当我尝试通过像 http://localhost:{port_no}/api/Data/1 这样的目录访问特定电话目录 ID 时,我的浏览器会尝试下载我正在存储的 JSON 数据我的数据。

有人可以解释一下为什么会发生这种情况以及为什么 JSON 数据没有被正确解析吗?

Controller 类:

namespace TelephoneDirectory.Controllers
{
    public class DataController : ApiController
    {
        public async Task<IEnumerable<TelephoneEntry>> Get()
        {
            using (var context = new DataContext())
            {
                return await context.TelephoneEntries.ToListAsync();
            }
        }

        public async Task<TelephoneEntry> Get(int id)
        {
            using (var context = new DataContext())
            {
                return await context.TelephoneEntries.FirstOrDefaultAsync(t => t.Id == id);
            }
        }


        public async Task<int> Post([FromBody] TelephoneEntry telephoneEntry)
        {
            using (var context = new DataContext())
            {
                if (telephoneEntry.Id == 0)
                {
                    context.Entry(telephoneEntry).State = EntityState.Added;
                }
                else
                {
                    context.Entry(telephoneEntry).State = EntityState.Modified;
                }

                await context.SaveChangesAsync();

                return telephoneEntry.Id;
            }
        }
    }
}

index.js(包含 ko 绑定(bind)的代码)

function TelephoneEntry(data) {
    var self = this;

    self.id = data.id;
    self.firstName = data.firstName;
    self.lastName = data.lastName;
    self.number = data.number;
}

function TelephoneViewModel() {
    var self = this;

    self.id = ko.observable(0);
    self.firstName = ko.observable('');
    self.lastName = ko.observable('');
    self.number = ko.observable('');

    self.addText = ko.observable('Add');
    self.resetText = ko.observable('Reset');
    self.selectedIndex = -1;

    self.add = function () {

        var entry = new TelephoneEntry({
            id: self.id(),
            firstName: self.firstName(),
            lastName: self.lastName(),
            number: self.number()
        });

        if (self.addText() == 'Add') {
            self.telephoneEntries.push(entry);
        }
        else {
            var oldTelephoneEntry = self.telephoneEntries()[self.selectedIndex];
            self.telephoneEntries.replace(oldTelephoneEntry, entry);
        }

        self.post(entry);
        self.reset();
    };

    self.reset = function () {
        self.id(0);
        self.firstName('');
        self.lastName('');
        self.number('');

        self.addText('Add');
        self.resetText('Reset');
        self.selectedIndex = -1;
    };

    self.load = function () {
        $.getJSON('http://localhost:16257/api/Data/', function (data) {
            $.each(data, function (index, item) {
                self.telephoneEntries.push(new TelephoneEntry({
                    id: item.id,
                    firstName: item.firstName,
                    lastName: item.lastName,
                    number: item.number
                }));
            });
        });
    };

    self.post = function (telephoneEntry) {
        $.post('http://localhost:16257/api/Data/', telephoneEntry, function (id) {
            telephoneEntry.id = id;
        });
    };

    self.telephoneEntries = ko.observableArray([]);
    self.load();
}

ko.applyBindings(new TelephoneViewModel());

WebApiConfig 类:

namespace TelephoneDirectory.App_Start
{
    public class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });

            JsonMediaTypeFormatter jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();

            jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        }
    }
}

全局.asax

public class Global : HttpApplication
    {

        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
            Database.SetInitializer(new Initializer());
        }
    }

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="Content/bootstrap.min.css" rel="stylesheet" />
    <link href="Content/site.css" rel="stylesheet" />
</head>
<body>
    <script src="Scripts/jquery-1.9.0.min.js"></script>
    <script src="Scripts/knockout-3.1.0.js"></script>
    <script src="Scripts/index.js"></script>

    <div class="container-narrow">
        <div class="row">
            <h1>Telephone Directory</h1>
        </div>
        <div class="row shaded padded">
            <div class="col-sm-3">
                <label for="firstName">First Name</label>
                <input id="firstName" name="firstName" type="text" class="form-control" data-bind="value: firstName" required="required" />
            </div>
            <div class="col-sm-3">
                <label for="lastName">Last Name</label>
                <input id="lastName" name="lastName" type="text" class="form-control" data-bind="value: lastName" required="required" />
            </div>
            <div class="col-sm-3">
                <label for="phoneNumber">Phone Number</label>
                <input id="phoneNumber" name="phoneNumber" type="text" class="form-control" data-bind="value: number" required="required" />
            </div>
            <div class="col-sm-12">
                <button id="add" name="add" type="submit" data-bind="click: add, text: addText">Add</button>
                <button id="reset" name="reset" type="reset" data-bind="click: reset, text: resetText">Reset</button>
            </div>
        </div>
    </div>
    <div class="container-narrow">
        <div class="row">
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>First Name</th>
                        <th>Last Name</th>
                        <th>Phone Number</th>
                        <th>&nbsp;</th>
                    </tr>
                </thead>
                <tbody data-bind="foreach: telephoneEntries">
                    <tr>
                        <td><span data-bind="text: firstName"></span></td>
                        <td><span data-bind="text: lastName"></span></td>
                        <td><span data-bind="text: number"></span></td>
                        <td>
                            <a href="#" data-bind="click: $parent.edit">Edit</a>&nbsp;<a href="#" data-bind="click: $parent.delete">Delete</a>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

</body>
</html>{"id":1,"firstName":"Jon","lastName":"Preece","number":"4444"}

最佳答案

要在文档就绪时设置绑定(bind),请执行以下操作。

改变这个

ko.applyBindings(new TelephoneViewModel());

到此

$(function(){ 
    ko.applyBindings(new TelephoneViewModel());
});

关于javascript - C# Web API 中的 JSON 数据无法正确解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23355239/

相关文章:

java - 如何将 JSONArray 转换为字符串/浮点值

audio - 具有同步播放功能的 mp3 网站播放器(非流式传输)

javascript - 无法理解为什么我的 Javascript 函数不起作用?

javascript - 验证特定表单的表单输入

javascript - 这个D3图怎么画呢?

json - 执行自定义过滤器 UsernamePasswordAuthenticationFilter 后如何以编程方式返回 json 响应?

javascript - 主干解析服务器对模型的响应

javascript - 尝试嵌套 React 组件

javascript - 在 Three.js 中旋转一个对象本身并围绕另一个中心对象

javascript - 如何选择没有定义任何属性的 HTML 元素?