我有一个显示人事数据的表单,并提供更新人员信息并将更改保存到我的数据库的功能。见下面的表格:
绑定到文本框的字段我没有更新问题。但是,当涉及HTML选择列表(下拉列表)时,我无法保存新选择的值。
注意我可以在任意数量的文本框中进行更改,然后更改选择列表中的选项,并且表单的其余部分可以正常保存,而无需更改选择列表,所以它似乎没有任何失败。
我没有收到任何错误;但是,我在PUT之前看到了一个额外的OPTIONS请求,我不确定(所以关于为什么会这样做的任何其他提示也会受到赞赏)。
这是我的表格:
<form name="personForm" novalidate ng-controller="PersonnelEditCtrl as vm">
<fieldset class="col-md-4">
<legend>Basic Personnel Information</legend>
<div class="form-group row" ng-class="{'has-error':personForm.inputLastName.$invalid && personForm.inputLastName.$dirty}">
<label class="col-md-3 control-label" for="inputLastName">Last Name</label>
<div class="col-md-4">
<input class="form-control" id="inputLastName" name="inputLastName"
type="text" placeholder="Last Name (required)"
ng-model="vm.person.lastName" required ng-minlength="1" ng-maxlength="30" />
</div>
<span class="help-block" has-error">
<span ng-show="personForm.inputLastName.$error.required">
Last name is required.
</span>
<span ng-show="person.form.inputLastName.$error.minlength">
Last name must be at least 1 character in length.
</span>
<span ng-show="person.form.inputLastName.$error.maxlength">
Last name cannot exceed 30 characters in length.
</span>
</span>
</div>
<div class="form-group row" ng-class="{'has-error':personForm.inputFirstName.$invalid && personForm.inputFirstName.$dirty}">
<label class="col-md-3 control-label" for="inputFirstName">First Name</label>
<div class="col-md-4">
<input class="form-control" id="inputFirstName" name="inputFirstName"
type="text" placeholder="First Name (required)"
ng-model="vm.person.firstName" required ng-minlength="1" ng-maxlength="30" />
</div>
<span class="help-block" has-error">
<span ng-show="personForm.inputFirstName.$error.required">
First name is required.
</span>
<span ng-show="person.form.inputFirstName.$error.minlength">
First name must be at least 1 character in length.
</span>
<span ng-show="person.form.inputFirstName.$error.maxlength">
First name cannot exceed 30 characters in length.
</span>
</span>
</div>
<div class="form-group row" ng-class="{'has-error':personForm.inputMiddleInitial.$invalid && personForm.inputMiddleInitial.$dirty}">
<label class="col-md-3 control-label" for="inputMiddleInitial">Middle Initial</label>
<div class="col-md-4">
<input class="form-control" id="inputMiddleInitial" name="inputMiddleInitial"
type="text" placeholder="Middle Initial (required)"
ng-model="vm.person.middleInitial" required ng-minlength="1" ng-maxlength="1" />
</div>
<span class="help-block" has-error">
<span ng-show="personForm.inputMiddleInitial.$error.required">
Middle initial is required.
</span>
<span ng-show="person.form.inputMiddleInitial.$error.minlength">
Middle initial must be at least 1 character in length.
</span>
<span ng-show="person.form.inputMiddleInitial.$error.maxlength">
Middle initial cannot exceed 1 characters in length.
</span>
</span>
</div>
<div class="form-group row">
<label class="col-md-3 control-label" for="inputDateOfBirth">Date of Birth</label>
<div class="col-md-4">
<input class="form-control" ng-model="vm.person.dob" type="date" />
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label" for="selectPayband">Payband</label>
<div class="col-md-4">
<select id="selectPayband" name="selectPayband"
ng-model="vm.person.payband" ng-options="payband.name for payband in vm.paybands track by payband.id">
</select>
</div>
</div>
<div class="form-group row">
<div class="col-md-4">
<span>
<button class="btn btn-primary" style="width:80px; margin-right:10px"
ng-click="vm.submit()" ng-disabled="personForm.$invalid">Save</button>
</span>
<span>
<button class="btn btn-default" style="width:70px"
ng-click="vm.cancel(personForm)">Cancel</button>
</span>
</div>
</div>
<div class="form-group row" ng-show="vm.message">
<div class="col-md-6">
<pre style="font: inherit">{{ vm.message }}</pre>
</div>
</div>
</fieldset>
personnelEditCtrl.js
angular
.module("personnelService")
.controller("PersonnelEditCtrl",
PersonnelEditCtrl);
function PersonnelEditCtrl(personnelResource, paybandResource, $filter) {
var vm = this;
vm.person = {};
vm.message = '';
vm.paybands = [];
paybandResource.query(function (data) {
vm.paybands = $filter('orderBy')(data, 'Name');
});
personnelResource.get({ id: 2 },
function (data) {
vm.person = data;
vm.person.dob = new Date(vm.person.dob);
vm.originalPerson = angular.copy(data);
});
if (vm.person && vm.person.personId) {
vm.title = "Edit: " + vm.person.firstName + " " + vm.person.lastName;
}
else {
vm.title = "New Person";
}
vm.submit = function () {
vm.message = '';
if (vm.person.personId) {
vm.person.$update({ id: vm.person.personId },
function (data) {
vm.message = '... Save Complete';
})
}
else {
vm.person.$save(
function (data) {
vm.originalPerson = angular.copy(data);
vm.message = '... Save Complete';
})
}
};
vm.cancel = function (editForm) {
editForm.$setPristine();
vm.person = angular.copy(vm.originalPerson);
vm.message = "";
};
}
personnelResource.js
(function () {
"use strict";
angular
.module("common.services")
.factory("personnelResource",
["$resource",
"appSettings",
personnelResource])
function personnelResource($resource, appSettings) {
return $resource(appSettings.serverPath + "/api/people/:id", null,
{
'update':{method:'PUT'}
});
}
}());
paybandResource.js
(function () {
"use strict";
angular
.module("common.services")
.factory("paybandResource",
["$resource",
"appSettings",
paybandResource])
function paybandResource($resource, appSettings) {
return $resource(appSettings.serverPath + "/api/paybands/:id");
}
}());
数据库结构:
dbo.People
PersonId : int (PK)
FirstName : string
MiddleInitial: string
LastName : string
DateOfBirth: datetime
PaybandId : int (FK)
dbo.Paybands
Id : int (PK)
Name : string
它可能与它无关,但我也会发布“人物”的Web API控制器代码:
using System.Linq;
using System.Web.Http;
using CPS.WebAPI.Models;
using System.Web.Http.Cors;
using System.Data.Entity;
namespace CPS.WebAPI.Controllers
{
[EnableCorsAttribute("http://localhost:53265", "*", "*")]
public class PeopleController : ApiController
{
private CPS_Context db = new CPS_Context();
public IQueryable<Person> GetPeople()
{
return db.Person;
}
public Person Get(int id)
{
Person person;
if (id > 0)
{
var people = db.Person;
person = people.FirstOrDefault(p => p.PersonId == id);
}
else
{
person = db.Person.Create();
}
return person;
}
public void Post([FromBody]Person person)
{
CPS_Context db = new CPS_Context();
var newPerson = db.Person.Add(person);
db.SaveChanges();
}
public void Put(int id, [FromBody]Person person)
{
CPS_Context db = new CPS_Context();
db.Entry(person).State = EntityState.Modified;
var updatedPerson = db.SaveChanges();
}
public void Delete(int id)
{
}
}
}
不要介意Web API的最低限度代码,我只是从头开始做所有事情,尽可能减少所有事情,以便让它在同一时间运行。
非常感谢您提供的帮助我在选择列表中保存所选选项的任何帮助。如果您有任何其他问题或需要更多信息,请告诉我 - 我尽量尽可能彻底。再次感谢任何人提供的任何帮助!
答案 0 :(得分:5)
我的问题是JSON数据包含导航属性。更新失败,因为存在引用完整性冲突。
我的问题的解决方案是更新我的Entity Framework数据模型以从JSON中排除导航属性。我通过添加[JsonIgnore]属性这样做:
[ForeignKey("Payband")]
public virtual int PaybandId { get; set; }
[JsonIgnore]
public virtual Payband Payband { get; set; }