2015-04-01 80 views
1

我有一个Web API(2)项目,其中有部门和员工。一个员工有一个部门,一个部门有一个员工名单。

现在在前端创建或编辑员工时,用户必须选择一个部门。将这个信息发布到API中时,部门包含了员工列表(这导致了一个无效的模型状态),我该如何防止这种情况发生?

这是我的相关设置:

型号:

public class Employee : IEntity, ICreatedOn, IModifiedOn, IMappable 
{ 
    [Key] 
    public virtual int Id { get; set; } 

    public virtual Department Department { get; set; } 

    // .. other properties 
} 

public class Department : IEntity, IMappable 
{ 
    [Key] 
    public virtual int Id { get; set; } 

    public virtual ICollection<Employee> Employees { get; set; } 

    // .. other properties 
} 

的Web API控制器:

public class EmployeesController : ApiController 
{ 
    private readonly IEmployeeService _employeeService; 

    public EmployeesController(IEmployeeService employeeService) 
    { 
     this._employeeService = employeeService; 
    } 

    // .. GET, POST, DELETE etc. 

    // PUT: api/Employees/5 
    [ResponseType(typeof(void))] 
    public IHttpActionResult PutEmployee(int id, EmployeeVM employee) 
    { 
     // This is always invalid, because the employee has a department, which in turn has a list of employees which can be invalid 
     // What to do to exclude the list of employees from validation, or even better prevent from being sent to the API 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     // Update etc.. 

     return StatusCode(HttpStatusCode.NoContent); 
    } 

角(DataService.js):

app.factory('DataService', 
    ["$http", 
    function ($http) { 

     return { 
      // other functions 
      updateEmployee: _updateEmployee 
     } 

     function _updateEmployee(employee) { 

      // Maybe exclude the list of employees in employee.department in here?? 
      return $http.put(employeesUrl + "/" + employee.id, employee); 
     } 

     // .. other functions 
    }]); 

注意事项:

  • 它发生在认沽和后两者(更新和创造)
  • 我使用AutoMapper映射到的ViewModels,看起来一样的实体
  • 我使用实体框架对于ORM

我已经试过:

  • [JsonIgnore]在Employees集合属性;这会导致雇员在加载部门时也未被加载
  • [绑定(排除=“雇员”)]属性在控制器操作参数中,这没有任何影响
  • [Bind(Exclude =“Department.Employees “)]相同

什么工作,但我敢肯定,必须有一个更好的解决方案:

function _updateEmployee(employee) { 

    var newEmp = angular.copy(employee); 
    delete newEmp.department.employees; 
    return $http.put(employeesUrl, newEmp); 
} 
+0

显示您的EmployeeVM请 – Artiom 2015-04-01 13:06:05

回答

1

创建更新employee一个新的请求。像:

public class UpdateEmployeeRequest{ 
    public int EmployeeId {get;set;} 
    public int DepartmentId {get;set;} 
    //and so on 
} 

对于此请求,您可以指定具体验证。

,并宣布与实体明确ID:

public class Employee : IEntity, ICreatedOn, IModifiedOn, IMappable 
{ 
    [Key] 
    public int Id { get; set; } 

    [ForeignKey("Department")] 
    public Guid DepartmentId { get; set; } 

    [Required] 
    public virtual Department Department { get; set; } 
    // .. other properties 
} 
0

我将修改雇员实体这样

public class Employee : IEntity, ICreatedOn, IModifiedOn, IMappable 
    { 
     [Key] 
     public virtual int Id { get; set; } 

     //Add DepartmentId 
     public Guid? DepartmentId { get; set; } 
     public virtual Department Department { get; set; } 

     // .. other properties 
    } 

然后你才可以设置DepartmentID的,就是这样。 EF会照顾其余的