Asp.net mvc 4 Web API+;关于复杂类型的模型绑定的MVC4
我有以下课程:Asp.net mvc 4 Web API+;关于复杂类型的模型绑定的MVC4,asp.net-mvc-4,asp.net-web-api,entity-framework-4.1,Asp.net Mvc 4,Asp.net Web Api,Entity Framework 4.1,我有以下课程: public class State { public long Id { get; set; } public string Name { get; set; } public string Abbreviation { get; set; } // Navigation Properties public virtual Country Country
public class State
{
public long Id { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
// Navigation Properties
public virtual Country Country { get; set; }
}
public class School
{
public long Id { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
// Navigation Properties
public virtual State State { get; set; }
}
以及我的SQL Server中的以下数据
| School| | |
| Id | Name | State |
| 1 | UCLA | 1 |
+-------+-------------+---------------+
| State | | |
| Id | Name | Abbreviation |
| 1 | California | CA |
我正在尝试创建一个Rest控制器,它使用HTTP POST谓词和Web API创建一个school实例
public HttpResponseMessage<School> Post( School school )
{
SchoolService.CreateSchool( school );
var response = new HttpResponseMessage<School>( school, HttpStatusCode.Created );
string uri = Url.Route( null, new { id = school.Id } );
response.Headers.Location = new Uri( Request.RequestUri, uri );
return response;
}
公共HttpResponseMessage Post(学校)
{
学校服务。创建学校(学校);
var响应=新的HttpResponseMessage(学校,HttpStatusCode.Created);
字符串uri=Url.Route(null,新{id=school.id});
response.Headers.Location=新Uri(Request.RequestUri,Uri);
返回响应;
}
WebAPI从我的Web表单中正确地绑定了我的学校类的名称和缩写属性,并在控制器中调用POST方法,但它不知道如何处理State类。我不太清楚如何设置。我想要一个绑定到State类的下拉列表,当我提交学校的创建时,现有数据中的正确状态将被分配到新的学校实例。首先,您的域模型设计有点粗糙。你的
School
表应该有一个FK
toState
表,你的POCO课程中也应该有:
public class School
{
public long Id { get; set; }
public long StateId { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
// Navigation Properties
public virtual State State { get; set; }
}
然后您应该有一个表单字段,如下所示:
<select id="StateId" name="StateId">
<option value="">Select a State</option>
<option value="310">CA</option>
<option value="311">NY</option>
</select>
选择一个状态
加利福尼亚州
纽约
首先,您的域模型设计有点粗糙。你的School
表应该有一个FK
toState
表,你的POCO课程中也应该有:
public class School
{
public long Id { get; set; }
public long StateId { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
// Navigation Properties
public virtual State State { get; set; }
}
然后您应该有一个表单字段,如下所示:
<select id="StateId" name="StateId">
<option value="">Select a State</option>
<option value="310">CA</option>
<option value="311">NY</option>
</select>
选择一个状态
加利福尼亚州
纽约
在我当前的项目中,我使用以下方法实现了类似的目标:
我有一个设备类(POCO)和一个DeviceCommand类(POCO)。设备可以有多个命令,每个命令将恰好有一个设备
我并没有为ViewModel而烦恼,POCO类在层之间使用
public class Device
{
[Key]
public int ID { get; set; }
public int DeviceID { get; set; }
public bool IsActive { get; set; }
// Navigational properties
public ICollection<DeviceCommand> CommandList { get; set; }
}
在我的DbContext派生类中,我有以下代码:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity<DeviceCommand>()
.HasRequired(d => d.Device)
.WithMany(l => l.CommandList)
.HasForeignKey(b => b.DeviceId)
.WillCascadeOnDelete();
}
protectedoverride void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.has必需(d=>d.Device)
.WithMany(l=>l.CommandList)
.HasForeignKey(b=>b.DeviceId)
.WillCascadeOnDelete();
}
在我看来,您必须使用注释或fluent API设置外键关系
如果POST方法中的参数没有任何属性,那么决策完全取决于参数的.NET类型。“简单类型”使用模型绑定。复杂类型使用格式化程序
请参考此链接以更好地了解web api绑定:
希望这能有所帮助。在我当前的项目中,我使用以下方法实现了类似的效果: 我有一个设备类(POCO)和一个DeviceCommand类(POCO)。设备可以有多个命令,每个命令将恰好有一个设备 我并没有为ViewModel而烦恼,POCO类在层之间使用
public class Device
{
[Key]
public int ID { get; set; }
public int DeviceID { get; set; }
public bool IsActive { get; set; }
// Navigational properties
public ICollection<DeviceCommand> CommandList { get; set; }
}
在我的DbContext派生类中,我有以下代码:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity<DeviceCommand>()
.HasRequired(d => d.Device)
.WithMany(l => l.CommandList)
.HasForeignKey(b => b.DeviceId)
.WillCascadeOnDelete();
}
protectedoverride void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.has必需(d=>d.Device)
.WithMany(l=>l.CommandList)
.HasForeignKey(b=>b.DeviceId)
.WillCascadeOnDelete();
}
在我看来,您必须使用注释或fluent API设置外键关系
如果POST方法中的参数没有任何属性,那么决策完全取决于参数的.NET类型。“简单类型”使用模型绑定。复杂类型使用格式化程序
请参考此链接以更好地了解web api绑定:
希望这有帮助。您如何提交
存储
类的值?你能发布HTTP请求的详细信息(标题、表单字段和值等)吗?我也有同样的问题;我在一篇文章中对一个复杂类型进行XML反序列化,它尝试使用ModelBinder而不是默认的XmlMediaTypeFormatter。有人提到JSON可以很好地实现这一点——您使用的是XML还是JSON序列化?如何提交Store
class的值?你能发布HTTP请求的详细信息(标题、表单字段和值等)吗?我也有同样的问题;我在一篇文章中对一个复杂类型进行XML反序列化,它尝试使用ModelBinder而不是默认的XmlMediaTypeFormatter。有人提到JSON可以很好地实现这一点——您是使用XML还是JSON序列化?嗨,Tugberk,在我之前的迭代中,我会有一个包含FK的学校视图模型。自从引入Web API以来,我想尝试在不使用FKs和不使用viewmodel类的情况下实现这一点,希望有某种方法来绑定复杂类型,例如本例中的状态。我想我的问题是,是否可以不使用FKs以这种方式实现它,如果可以,如何设置Post方法以及如何提交state的值。如果不可能的话,我可能不得不以FK/viewmodel的方式完成。嗨,Tugberk,在我之前的迭代中,我会有一个包含FK的学校视图模型。自从引入Web API以来,我想尝试在不使用FKs和不使用viewmodel类的情况下实现这一点,希望有某种方法来绑定复杂类型,例如本例中的状态。我想我的问题是,是否可以不使用FKs以这种方式实现它,如果可以,如何设置Post方法以及如何提交state的值。如果不可能的话,我可能不得不用FK/viewmodel的方式来完成。