2

我有一个 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 提要或条目阅读器指定实体类型时,它必须与指定实体集的基本类型相同或子类型。

一定有办法做到这一点......有什么想法吗?

干杯

4

0 回答 0