【问题标题】:JSON data not parsing correctly in C# Web APIJSON 数据在 C# Web API 中未正确解析
【发布时间】:2014-06-14 20:02:07
【问题描述】:

我目前正在学习使用 Web API 创建电话目录的在线教程。一切正常,直到我开始使用带有 knockout.js 的 javascript 来绑定我的视图模型。现在没有数据被加载到页面上。

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

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

控制器类:

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 绑定的代码)

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"}

【问题讨论】:

  • 没有错误,只是页面上没有加载数据,点击添加、编辑和删除按钮似乎什么也没做
  • 在准备好的文档中应用数据绑定。
  • 在 chrome 或 firebug 中打开网络选项卡和控制台选项卡并检查发送到浏览器的内容
  • 嗨@MatthewPigram,您可以查看使用浏览器请求服务时返回的 JSON 数据的内容。如果这是您所期望的,那么问题出在您的绑定上。
  • 另一方面,您的问题有 很多 代码需要处理,其中大部分与问题无关。你能把它删减到只剩下相关的部分,把它变成一个minimal repro吗?让我们更容易(或至少:邀请)为您提供帮助。

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


【解决方案1】:

要在准备好的文档上设置绑定,请执行以下操作。

改变这个

ko.applyBindings(new TelephoneViewModel());

到这里

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2013-04-18
    相关资源
    最近更新 更多