首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Controller/ViewComponent中设置/更改显示(Name=“”)属性

在Controller/ViewComponent中设置/更改显示(Name=“”)属性
EN

Stack Overflow用户
提问于 2019-03-14 12:41:10
回答 1查看 3.5K关注 0票数 0

根据 2010年的回答,关于mvc-2,这是不可能的。那么现在,在ASP.NETcore 2.2中呢?

我的用法:

我有一个由两个视图使用的BaseViewModelTableView (用于用户)和TableManagentView (用于管理员)。BaseViewModelViewComponent调用。以下是一些样本:

BaseViewModel:

代码语言:javascript
复制
public class BaseViewModel {
    [Display(Name = "Comment")
    public string UserComment { get; set; }
}

TableView:

代码语言:javascript
复制
@await Component.InvokeAsync(nameof(Base), new { myObject = myObject, stringName = "User"})

TableManagementView:

代码语言:javascript
复制
@await Component.InvokeAsync(nameof(Base), new { myObject = myObject, stringName = "Admin"})

基地:

代码语言:javascript
复制
public class Base : ViewComponent
{
    public IViewComponentResult Invoke(BaseViewModel myObjet, string invokingView)
    {
        // here i want to do something like that
        if (invokingView == "User") {
            myObject.UserComment.SetDisplayName("My Comment");
        } 
        if (invokingView == "Admin") {
            myObject.UserComment.SetDisplayName("User's Comment");
        }


        return View("BaseViewComponent", myObject);
    }
}

BaseViewComponent:

代码语言:javascript
复制
@Html.DisplayNameFor(model => model.UserComment)

BaseViewModel是简化的,但是有更多的属性。我想这样做的原因是为了避免两个表中的代码重复。唯一需要改变的是标签的名称。

我试过reflection,但没有成功:

代码语言:javascript
复制
public IViewComponentResult Invoke(BaseViewModel myObject, string invokingView)
    {
        MemberInfo property = typeof(BaseViewModel).GetProperty("UserComment");
        property.GetCustomAttributes(typeof(DisplayAttribute)).Cast<DisplayAttribute>().Single().Name = "test";

        return View("BaseViewComponent", myObject);
    }

Name不会改变,并且保持与初始设置相同的"Comment"

如果无法以编程方式设置属性名,我还有其他解决方案吗?我正在考虑ViewBag/ViewDataTempData,但这个解决方案对我没有吸引力。什么是正反两方面?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-14 15:39:25

对我留下的注释进行扩展,解决这个问题的一种方法是让您的BaseViewModel成为一个抽象类,并有来自它的具体类。所以UserViewModelAdminViewModel。然后,这两个具体类将成为TableViewTableManagentView的模型,并负责告诉“外部世界”如何标记字段。

基类有两个主要方面(除了常规字段):一个将包含标签的抽象Dictionary<string, string>和一个从列表:string GetLabel(string propName)获取标签的方法。所以就像这样:

代码语言:javascript
复制
public abstract class BaseViewModel
{
    protected abstract Dictionary<string, string> Labels { get; }

    public string UserComment { get; set; }

    public string GetLabel(string propName)
    {
        if (!Labels.TryGetValue(propName, out var label))
            throw new KeyNotFoundException($"Label not found for property name: {propName}");

        return label;
    }
}

然后创建两个派生类UserAdmin

代码语言:javascript
复制
public sealed class UserViewModel : BaseViewModel
{
    protected override Dictionary<string, string> Labels => new Dictionary<string, string>
    {
        { nameof(UserComment), "User label" }
    };
}

public sealed class AdminViewModel : BaseViewModel
{
    protected override Dictionary<string, string> Labels => new Dictionary<string, string>
    {
        { nameof(UserComment), "Admin label" }
    };
}

它们只实现Dictionary<string, string>,并为基类上的每个字段设置适当的文本。

接下来,将您的BaseViewComponent更改为:

视图

代码语言:javascript
复制
@model DisplayNameTest.Models.BaseViewModel

<h3>Hello from my View Component</h3>

<!-- Gets the label via the method on the base class -->
<p>@Model.GetLabel(nameof(BaseViewModel.UserComment))</p>

<p>@Model.UserComment)</p>

ComponentView类(现在更简单)

代码语言:javascript
复制
public IViewComponentResult Invoke(BaseViewModel viewModel)
{
    return View(viewModel);
}

最后,将视图TableViewTableManagentView更改为:

代码语言:javascript
复制
@model WebApp.Models.AdminViewModel

@{
    Layout = null;
}

<h1>Admin View</h1>
<div>
    @await Component.InvokeAsync("Base", Model)
</div>

和财务主任:

代码语言:javascript
复制
public IActionResult Index()
{
    var adminViewModel = new AdminViewModel { UserComment = "some comment from admin" };
    return View(adminViewModel);
}

现在,当您导航到TableView时,您将把一个UserViewModel传递给BaseViewComponent,它将找出正确的标签。引入新的字段将要求您更改视图模型,在字典中添加一个新条目。

这并不完美,但我认为这是一个解决问题的好办法。到目前为止,我还不是MVC专家,所以也许其他人也能想出一种更自然的方法来实现它。我还准备了一个工作示例应用程序,并将其推到GitHub上。您可以在这里查看:aspnet-视图-组件-演示。希望它能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55162817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档