gpt4 book ai didi

c# - 拆分实体数据模型属性的数据注释 [必需] 属性

转载 作者:太空宇宙 更新时间:2023-11-03 19:31:05 27 4
gpt4 key购买 nike

我正在使用 Entity Framework 的表拆分功能来拆分我的实体数据模型,如下所示:

+--------+    +--------------+
| News | | NewsImages |
+--------+ +--------------+
| NewsID | | NewsID |
| Text | | Image |
+--------+ +--------------+

每个 News 实体都包含一个名为 NewsImage 的导航属性以引用相应的图像。


我正在使用 DataAnnotations 来验证我的模型。我将 [Required] 属性放在 News 类的 Text 属性上:

[MetadataType(typeof(NewsValidation))]
public partial class News
{
/* ... */
}

public class NewsValidation
{
[Required]
public string Text { get; set; }
}

这是我用来获取图像数据的服务器端代码:

[HttpPost]
public ActionResult Create(News news)
{
if (ModelState.IsValid)
{
UpdateNewsImage(news);
_newsRepository.Add(news);
_newsRepository.SaveChanges();

return RedirectToAction("Index");
}
}

private void UpdateNewsImage(News news)
{
byte[] newsImage = GetNewsImage();
news.NewsImage = new NewsImage { Image = newsImage };
}

private byte[] GetNewsImage()
{
foreach (string upload in Request.Files)
{
HttpPostedFileBase uploadedFile = Request.Files[upload];

if (!uploadedFile.HasFile())
{
break;
}

Stream fileStream = uploadedFile.InputStream;
int fileLength = uploadedFile.ContentLength;
byte[] fileData = new byte[fileLength];
fileStream.Read(fileData, 0, fileLength);

return fileData;
}

return null;
}

调用 UpdateNewsImage(news) 方法后,实体 news正确填充 相应的图像数据,但 ModelState .IsValid 属性仍然是 false;调试 ModelState.Values 导致一个错误:“The NewsImage field is required.”


如何将 [Required] 属性(或其他一些为每个 News 实体强制使用图像的机制)放在 NewsImage 属性上?

最佳答案

为什么不在验证类中的 NewsImage 属性上放置一个 [Required] 属性?这将要求 News 实体实例也具有相应的 NewsImage 实体实例。

当将 RequiredAttribute 放在引用(如在非字符串中)类型的属性上时,它只检查该属性不为 null。让我通过 RequiredAttribute.IsValid() 方法对此进行支持:

public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
string str = value as string;
if (str != null)
{
return (str.Trim().Length != 0);
}
return true;
}

如果您的模型状态无效,则意味着您的 NewsImage 为空。也许您在这里遗漏了一些明显的东西,而其他一些属性会使您的模型状态无效。

Asp.net MVC 文件数据绑定(bind)

我明白了。您似乎认为每次对模型执行某些操作时都会验证模型状态。当然不是这样。在执行操作之前,Asp.net MVC 会自动为您验证操作参数。因此,当您在操作方法的主体中时模型状态无效时,无论您对模型​​对象做什么,它都会保持这种状态。当然,除非您手动操作模型状态。在您的情况下,当您将图像添加到 News 时仍然不会更改模型状态(即使您的对象变得有效)。

据我了解,您对类型有疑问。 Asp.net MVC 默认模型绑定(bind)器能够自动将发布的文件流绑定(bind)到 HttpPostedFileBase 变量。您的 NewsImage.Image 属性属于 byte[] 类型,因此它不会自动绑定(bind)。

问题是您在 Web 应用程序中将数据模型实体用作应用程序/ View 模型实体,因此您不能只更改 NewsImage.Image 类型,因为它是 EF 数据模型的一部分.

为了让这个东西工作,我想最好/最简单的方法是用正确的属性类型编写一个单独的 View 模型实体类(不要将它与 EF 数据模型混淆)并添加一个公共(public)方法来转换它到数据模型 News 实体。

namespace WebProject.ViewModels
{
public class News
{
public int Id { get; set; } // not used when creating new entries but used with editing/deleting hens not being required

[Required]
public string Text { get; set; }

[Required]
public HttpPostedFileBase Image { get; set; }

public Data.News ToData()
{
return new Data.News {
Id = this.Id,
Text = this.Text,
NewsImage = new Data.NewsImage {
Id = this.Id,
Image = // convert to byte[]
}
}
}
}
}

因此,您的 View 模型对象将按预期正确地进行模型绑定(bind)和验证。好处是您的代码也将由于此更改而得到简化。当您需要从此 View 模型对象实例中获取数据实体实例时,请使用 ToData() 方法。当然,您也可以通过提供一个构造函数来提供相反的方法,该构造函数采用数据模型实体对象实例并填充 View 模型的属性。

如果您使用单独的数据库项目来保存 EF 数据模型,我建议您将 View 模型类严格放在 Web 应用程序项目(或任何其他应用程序模型项目)中,因为这是使用它的地方。

关于c# - 拆分实体数据模型属性的数据注释 [必需] 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4850535/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com