我有一个 OData Web API 控制器,它有一个 POST 来插入一个 UserProfile,但是为了不暴露我的数据库实体,我希望 Post 方法接受一个 UserProfileBindingModel。这可能吗?
目前,我的 UserProfiles 中有以下内容:
[EnableQuery(PageSize = 100, AllowedQueryOptions = AllowedQueryOptions.All)]
public IHttpActionResult Get()
{
return Ok(_db.UserProfile.ToUserViewModels());
}
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public IHttpActionResult Post([FromBody] UserProfileBindingModel model)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var userProfile = ToUserProfile(model);
_db.UserProfile.AddOrUpdate(userProfile);
_db.SaveChanges();
return Created(userProfile);
}
这是我的 ODataConfig.cs 文件:
public static class ODataConfig
{
public static void Register(HttpConfiguration config)
{
// OData builder
var builder = new ODataConventionModelBuilder();
// Register entities
builder.EntitySet<UserProfile>("UserProfiles").EntityType.Name = "UserProfile";
builder.EntitySet<UserProfileViewModel>("UserProfileViewModel").EntityType.Name = "UserProfileViewModel";
builder.EntitySet<UserProfileBindingModel>("UserProfileBindingModel").EntityType.Name = "UserProfileBindingModel";
// OData model config
var model = builder.GetEdmModel();
// OData route config
config.MapODataServiceRoute("odata", "odata", model);
}
}
UserProfile 在哪里:
public class UserProfile
{
public string Id { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
public string Email { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateBirth { get; set; }
}
UserProfile 的 Fluent API 是:
public class UserProfilesMap : EntityTypeConfiguration<UserProfile>
{
public UserProfilesMap()
{
// Primary Key
HasKey(t => t.Id);
// Properties
Property(t => t.Id)
.IsRequired()
.HasColumnType("nvarchar")
.HasMaxLength(128)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(t => t.DateCreated)
.IsRequired()
.HasColumnType("datetime");
Property(t => t.DateModified)
.IsRequired()
.HasColumnType("datetime");
Property(t => t.Email)
.IsRequired()
.HasColumnType("nvarchar")
.HasMaxLength(256);
Property(t => t.Username)
.IsRequired()
.HasColumnType("nvarchar")
.HasMaxLength(256);
Property(t => t.FirstName)
.IsRequired()
.HasColumnType("nvarchar")
.HasMaxLength(100);
Property(t => t.LastName)
.IsRequired()
.HasColumnType("nvarchar")
.HasMaxLength(100);
Property(t => t.DateBirth)
.IsRequired()
.HasColumnType("datetime");
// Table & Column Mappings
ToTable("UserProfiles");
Property(t => t.Id).HasColumnName("Id");
Property(t => t.DateCreated).HasColumnName("DateCreated");
Property(t => t.DateModified).HasColumnName("DateModified");
Property(t => t.Email).HasColumnName("Email");
Property(t => t.Username).HasColumnName("Username");
Property(t => t.FirstName).HasColumnName("FirstName");
Property(t => t.LastName).HasColumnName("LastName");
Property(t => t.DateBirth).HasColumnName("DateBirth");
}
}
而 UserProfileViewModel 是:
public class UserProfileViewModel
{
public string Id { get; set; }
public string Email { get; set; }
public string Username { get; set; }
public string FullName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateBirth { get; set; }
}
UserProfileBindingModel 是:
public class UserProfileBindingModel
{
public long Id { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[EmailAddress(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "InvalidEmail")]
[StringLength(100, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MustBetweenCharacters", MinimumLength = 6)]
[Display(Name = "Email", ResourceType = typeof(Resources))]
public string Email { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[StringLength(100, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MustUnderCharacters")]
[Display(Name = "FirstName", ResourceType = typeof(Resources))]
public string FirstName { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[Display(Name = "LastName", ResourceType = typeof(Resources))]
[StringLength(100, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MustUnderCharacters")]
public string LastName { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[Display(Name = "Username", ResourceType = typeof(Resources))]
[StringLength(30, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MustBetweenCharacters", MinimumLength = 6)]
public string Username { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[Display(Name = "Password", ResourceType = typeof(Resources))]
[StringLength(255, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MustBetweenCharacters", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[Display(Name = "ConfirmPassword", ResourceType = typeof(Resources))]
[StringLength(255, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MustBetweenCharacters", MinimumLength = 6)]
[Compare("Password", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "PasswordMustMatch")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "IsRequired")]
[Display(Name = "DateBirth", ResourceType = typeof(Resources))]
[DataType(DataType.Date)]
public DateTime DateBirth { get; set; }
}
Get 方法工作正常,但使用 post 方法我收到以下消息:
实体类型“UserProfileBindingModel”与提供的实体集“Default.Container.UserProfiles”的基本类型“UserProfile”不兼容。当为 OData 提要或条目阅读器指定实体类型时,它必须与指定实体集的基本类型相同或子类型。
一定有办法做到这一点......有什么想法吗?
干杯