在使用不同项目中存在的MetaData类时,DataAnnotations未得到反映

时间:2021-09-06 20:05:54

I'm learning Asp.Net MVC. I stumbled on such a thing while practising. I have Shop Project consisting of the simple Shopie Data Model which is a partial class. I applied DataAnnotations on another partial class ShopElob which is a MetaData class for this Shop Data Model.

我正在学习Asp.Net MVC。练习时我偶然发现了这样的事情。我有Shop Project包含简单的Shopie数据模型,这是一个部分类。我将DataAnnotations应用于另一个部分类ShopElob,它是此商店数据模型的MetaData类。

namespace Shop
{
  public partial class Shopie
  {
  public int ShopieId { get; set; }
  public String ShopieName { get; set; }
  public string Landmark { get; set; }
  public decimal Minprice { get; set; }
  public String Email { get; set; }
  }
}

ShopElob

namespace Shop
{
[MetadataType(typeof(ShopElob))]
public partial class Shop
{
}

public class ShopElob
{
[Display(Name = "Shopiez Name")]
public String ShopName { get; set; }

[DisplayFormat(DataFormatString = "{0:0.00}")]
public decimal MinPrice { get; set; }

[DataType(DataType.EmailAddress)]
public String Email { get; set; }
}
}

But when I create Strongly typed view of Shopie Model in another MVC project DataAnnotationsdemo, the UI doesn't reflect the DataAnnotations from the MetaData class even after referecing the Shop project in MVC project and provided the following code in Web.config of Views

但是当我在另一个MVC项目DataAnnotationsdemo中创建Shopie Model的强类型视图时,即使在MVC项目中引用Shop项目并在Web.config of Views中提供以下代码之后,UI也不会反映MetaData类中的DataAnnotations。

<Pages>
<namespaces>
    <add namespace="Shop.Shopie"/>
  </namespaces>
</Pages>

In controller I have the following code

在控制器中,我有以下代码

public ActionResult Index()
{
 PopulateData pd = new PopulateData();
 Shopie s=pd.beginPopulate();
 return View(s);
 }

And in View I specified the model as

在View中,我将模型指定为

@model Shop.Shopie

The above two projects lie within one solution.

以上两个项目属于一个解决方案。

2 个解决方案

#1


0  

So for me the approach here isn't correct - I think its good practice to have your entity framework in a separate project but I would still create an annotated ViewModel class in the Presentation layer. The reason for this is that it moves more towards a solution that conforms to separation of concerns and ensures all information related to presentation is in the presentation layer with data and logic in a separate DAL project.

所以对我来说这里的方法是不正确的 - 我认为将实体框架放在一个单独的项目中是一种很好的做法,但我仍然会在Presentation层中创建一个带注释的ViewModel类。其原因在于它更倾向于采用符合关注点分离的解决方案,并确保与表示相关的所有信息都在表示层中,并在单独的DAL项目中使用数据和逻辑。

I would create a static class called EntityViewModelExtensions in the presentation layer that looks something like this.

我将在表示层中创建一个名为EntityViewModelExtensions的静态类,看起来像这样。

public static ShopViewModel ToViewModel(this Shop model)
{
    return new ShopViewModel
    {
        ShopName = model.ShopName,
        MinPrice = model.MinPrice,
        Email = model.Email
    };
}

This can be called within your Controller Action as

这可以在您的Controller Action中调用

public ActionResult Index()
{
     PopulateData pd = new PopulateData();
     ShopViewModel s = pd.beginPopulate().Select(p => p.ToViewModel()).ToList();
     return View(s);
 }

Your ShopViewModel would then look like

然后你的ShopViewModel就像

public class ShopViewModel
{
    [Display(Name = "Shopiez Name")]
    public String ShopName { get; set; }

    [DisplayFormat(DataFormatString = "{0:0.00}")]
    public decimal MinPrice { get; set; }

    [DataType(DataType.EmailAddress)]
    public String Email { get; set; }
 }

The page itself would accept a model of type ShopViewModel.

页面本身将接受ShopViewModel类型的模型。

This then means all information relating to presentation (including Model Annotations and Display Attributes) are kept within the presentation layer whereas all information related to Database and Business Logic is in the DAL.

这意味着与表示有关的所有信息(包括模型注释和显示属性)都保存在表示层中,而与数据库和业务逻辑相关的所有信息都在DAL中。

I gave a talk on this topic a few weeks ago at DotNetNotts, if you want to check it out you can see it on YouTube.

几个星期前我在DotNetNotts上就这个话题进行了讨论,如果你想查看它,你可以在YouTube上看到它。

In the interests of completeness, if you did want to continue with your existing approach I think the reason it is failing is related to the name space. The name space you should be referencing is Shop. I've tested this on a very similar project and its worked without any issues with your code effectively copied and pasted as is.

为了完整性,如果您确实想继续使用现有方法,我认为它失败的原因与名称空间有关。您应该引用的名称空间是Shop。我已经在一个非常类似的项目上对此进行了测试,并且它的工作没有任何问题,您的代码被有效地复制和粘贴。

I hope that helps

我希望有所帮助

#2


0  

The point which was blocking Data Annotations to be applied in View was that the MetaData attribute was not applied on exact class.

阻止在View中应用数据注释的要点是MetaData属性未应用于确切的类。

Before:

[MetadataType(typeof(ShopElob))]
public partial class Shop
{
}

Correct Form is:

正确的表格是:

[MetadataType(typeof(ShopElob))]
public partial class Shopie
{
}

And the rest works fine. Obviously I prefer to opt Soc concepts suggested by @Steve Westgarth

其余的工作正常。显然我更喜欢选择@Steve Westgarth建议的Soc概念

#1


0  

So for me the approach here isn't correct - I think its good practice to have your entity framework in a separate project but I would still create an annotated ViewModel class in the Presentation layer. The reason for this is that it moves more towards a solution that conforms to separation of concerns and ensures all information related to presentation is in the presentation layer with data and logic in a separate DAL project.

所以对我来说这里的方法是不正确的 - 我认为将实体框架放在一个单独的项目中是一种很好的做法,但我仍然会在Presentation层中创建一个带注释的ViewModel类。其原因在于它更倾向于采用符合关注点分离的解决方案,并确保与表示相关的所有信息都在表示层中,并在单独的DAL项目中使用数据和逻辑。

I would create a static class called EntityViewModelExtensions in the presentation layer that looks something like this.

我将在表示层中创建一个名为EntityViewModelExtensions的静态类,看起来像这样。

public static ShopViewModel ToViewModel(this Shop model)
{
    return new ShopViewModel
    {
        ShopName = model.ShopName,
        MinPrice = model.MinPrice,
        Email = model.Email
    };
}

This can be called within your Controller Action as

这可以在您的Controller Action中调用

public ActionResult Index()
{
     PopulateData pd = new PopulateData();
     ShopViewModel s = pd.beginPopulate().Select(p => p.ToViewModel()).ToList();
     return View(s);
 }

Your ShopViewModel would then look like

然后你的ShopViewModel就像

public class ShopViewModel
{
    [Display(Name = "Shopiez Name")]
    public String ShopName { get; set; }

    [DisplayFormat(DataFormatString = "{0:0.00}")]
    public decimal MinPrice { get; set; }

    [DataType(DataType.EmailAddress)]
    public String Email { get; set; }
 }

The page itself would accept a model of type ShopViewModel.

页面本身将接受ShopViewModel类型的模型。

This then means all information relating to presentation (including Model Annotations and Display Attributes) are kept within the presentation layer whereas all information related to Database and Business Logic is in the DAL.

这意味着与表示有关的所有信息(包括模型注释和显示属性)都保存在表示层中,而与数据库和业务逻辑相关的所有信息都在DAL中。

I gave a talk on this topic a few weeks ago at DotNetNotts, if you want to check it out you can see it on YouTube.

几个星期前我在DotNetNotts上就这个话题进行了讨论,如果你想查看它,你可以在YouTube上看到它。

In the interests of completeness, if you did want to continue with your existing approach I think the reason it is failing is related to the name space. The name space you should be referencing is Shop. I've tested this on a very similar project and its worked without any issues with your code effectively copied and pasted as is.

为了完整性,如果您确实想继续使用现有方法,我认为它失败的原因与名称空间有关。您应该引用的名称空间是Shop。我已经在一个非常类似的项目上对此进行了测试,并且它的工作没有任何问题,您的代码被有效地复制和粘贴。

I hope that helps

我希望有所帮助

#2


0  

The point which was blocking Data Annotations to be applied in View was that the MetaData attribute was not applied on exact class.

阻止在View中应用数据注释的要点是MetaData属性未应用于确切的类。

Before:

[MetadataType(typeof(ShopElob))]
public partial class Shop
{
}

Correct Form is:

正确的表格是:

[MetadataType(typeof(ShopElob))]
public partial class Shopie
{
}

And the rest works fine. Obviously I prefer to opt Soc concepts suggested by @Steve Westgarth

其余的工作正常。显然我更喜欢选择@Steve Westgarth建议的Soc概念