Я работаю над книгой «ASP.NET MVC 5 с Bootstrap и Knockout.js» Джейми Мунро. Я опытный программист, но любитель ранга с MVC и веб-разработкой. Это попытка научиться делать это.Как отлаживать приложение MVC 5, которое использует knockout.js?
Как я работал над книгой, я допустил ошибку где-то в своем приложении, поэтому теперь я не могу сохранить отправки или изменения в моей базе данных. И я не знаю, как понять, что такое ошибка.
Код примера дает общую ошибку. Было бы полезно знать, как вывести внутреннее исключение или сообщение об ошибке. Фрагмент кода, который генерирует этот общий флаг ошибки заключается в следующем:
self.errorSave = function() {
$('.body-content').prepend('<div class="alert alert-danger"><strong>Error!</strong> There was an error saving the author.</div>');
}
У меня есть два вопроса, один конкретный и один общий.
В частности: Как я могу получить более подробное сообщение об ошибке в своем веб-браузере?
Generic: Как отлаживать веб-приложения? Я знаю, как отлаживать в Visual Studio, когда это не веб-приложение, но я не могу получить эту ошибку в ловушке. Точки останова в моем контроллере или модели или даже в моих формах не дают мне никакой полезной информации. Я также пробовал отладчик в Chrome и Internet Explorer, но не нашел, как получить что-нибудь более полезное, чем «Внутренняя ошибка сервера: 500», которая не говорит мне об этом.
Пример кода для этой книги можно найти здесь: https://github.com/oreillymedia/ASP_NET-MVC-5-with-Bootstrap-and-Knockout_js
Этот пример работает, насколько я знаю. Я не запускал его, так как у меня нет локального SQL Server, но если я действительно отчаянный, мне придется настроить его только для запуска двух наборов кода рядом. Сравнение моего кода с ним не указывало на мою ошибку. Конечно, это полностью обработанный пример, и мой код только обновляется около 1/3 книги.
В моем методе действий первая проверка - это ModelState.IsValid, которая возвращает false. Следовательно, никакой экономии.
public ActionResult Create([Bind(Include = "Id,FirstName,LastName,Biography")] Author author)
{
if (ModelState.IsValid)
{
db.Authors.Add(author);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(author);
}
похоже, что привязка модели работает неправильно.
В форме, вот как поле Имя устанавливается:
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" }, data_bind = "value: author.firstName" })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>
В модели, Author.cs:
public class Author
{
[JsonProperty(PropertyName ="id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "firstName")]
[Display(Name = "First Name")]
[Required]
public string FirstName { get; set; }
[JsonProperty(PropertyName = "lastName")]
[Display(Name = "Last Name")]
[Required]
public string LastName { get; set; }
[JsonProperty(PropertyName = "biography")]
public string Biography { get; set; }
[JsonProperty(PropertyName = "books")]
public virtual ICollection<Book> Books { get; set; }
}
AuthorFormViewModel.js выглядит следующим образом:
function AuthorFormViewModel(author) {
var self = this;
//variables to track state during saving
self.saveCompleted = ko.observable(false);
self.sending = ko.observable(false);
self.isCreating = author.id == 0;
//variable to track changes to model
self.author = {
id: author.id,
firstName: ko.observable(),
lastName: ko.observable(),
biography: ko.observable(),
};
self.validateAndSave = function (form) {
if (!$(form).valid())
return false;
self.sending(true);
//include anti forgery token
self.author.__RequestVerificationToken = form[0].value;
$.ajax({
url: (self.isCreating) ? 'Create' : 'Edit',
type: 'post',
contentType: 'application/x-www-form-urlencoded',
data: ko.toJS(self.author)
})
.success(self.successfulSave)
.error(self.errorSave)
.complete(function() { self.sending(false) });
};
self.successfulSave = function() {
self.saveCompleted(true);
$('.body-content').prepend('<div class="alert alert-success"><strong>Success!</strong> The author has been saved.</div>');
setTimeout(function() {
if (self.isCreating)
location.href = './'
else
location.href = '../'
}, 1000);
}
self.errorSave = function() {
$('.body-content').prepend('<div class="alert alert-danger"><strong>Error!</strong> There was an error saving the author.</div>');
}
Наконец, раздел сценария в нижней части Create/Edit форме пытается связать все вместе таким образом:
@section Scripts {
@Scripts.Render("~/bundles/jqueryval", "/Scripts/ViewModels/AuthorFormViewModel.js")
<script>
var viewModel = new AuthorFormViewModel(@Html.HtmlConvertToJson(Model));
ko.applyBindings(viewModel);
</script>
}
Кроме того, строка, возвращенная из @ Html.HtmlConvertToJson (модель) появляется хорошо отформатирован. Это то, что создание попытка возвращения: + ул { "ID": 0, "FirstName": нулевой, "LastName": нулевой, "биографией": нулевой, "книги": нулевая } системы. Web.HtmlString
При отладке, похоже, что ko.ApplyBindings (viewModel); заявление полностью пропущено. Возможно, при построении viewModel возникает ошибка (оператор @ Html.HtmlConvertToJson (Model) выглядит успешным), но это разочаровывает, что эта ошибка недоступна мне, и я не могу понять, как получить исключение/точку останова/вызов стек/что-то, что я могу исследовать.
Поместите визуальный студийный контрольный пункт в свой метод действий, который сохраняет данные. Проверьте значение переменной и убедитесь, что они соответствуют вашим ожидаемым значениям. – Shyju
@Shyju Спасибо за предложение. См. Мое редактирование выше с дополнительной информацией. – user2316154
Итак, какова реальная проблема сейчас? ModelState.IsValid вернет 'false', если проверка модели не удалась. Это ожидаемое поведение. – Shyju