查找控件的 MVC 等价物是什么?

What is the MVC equivalent of Find Control?

在 ASP.NET 网络表单中,可以从母版页修改页面控件。例如,在页面“/Sample”上,我可以通过执行以下操作将 TextBox1 设置为只读。

//Site.master.cs
protected void Page_Load(object sender, EventArgs e)
{
    if (Request.Path.ToUpper().Contains("/SAMPLE"))
    {
        TextBox TB = MainContent.FindControl("TextBox1") as TextBox;
        TB.ReadOnly = true;
    }
}

问题是...在使用 SiteLayout 的 MVC 应用程序中是否有等效的方法来执行此操作?

Background: We have purchased an MVC application and have access to modify the source code. We need to customize the behaviors on some of the pages. It will only be used by a few dozen people so a performance hit won't really be noticeable. If this was a Web Forms application we would use the above method. However this application is written with MVC and it is making our web form programmer (me) confused on how best to proceed. Customizing numerous pages is going to be a headache when we have to patch the software. Having all the changes in one central location would be easier to manage going forward. How can you have one place where you can customize other pages programmatically in MVC?

你的问题很宽泛。但一般来说,如果您想根据某些条件为剃刀视图中的控件提供只读呈现,您可以尝试以下方法。

您应该向您的视图模型添加 IsReadOnly 属性 并使用它以您想要的方式呈现控件。

public class CreateCustomerVM
{
    public bool IsReadOnly {set;get;} 

    //Other properties goes here
    public string Email { set; get; }
    public string Name { set; get; }

}

在您的 Action 方法中,根据您的条件设置 IsReadOnly 属性 值。

public ActionResult Index()
{
  var vm=new CreateCustomerVM();

  //Set the value based on your condition
  vm.IsReadOnly=true;

  return View(vm);    
}

并且在您看来,您使用 IsReadOnly 属性 来确定是否要显示只读控件。

@model YourNameSpaceGoesHere.CreateCustomerVM
@using (Html.BeginForm())
{
    @Html.TextBoxFor(m => m.Email)

    if(Model.IsReadOnly)
    {
        @Html.TextBoxFor(m => m.Name, new { @readonly = "readonly" })
    }
    else
    {
        @Html.TextBoxFor(m => m.Name)
    }
    <input type="submit"/>
}

FindControl 没有 MVC 等效项,因为视图是在单个操作中构建的,其中 ASP.NET 控件是针对多个不同事件构建和修改的。您不需要找到控件,您可以在构建时指定它的所有属性。

ASP.NET 控件(至少在本上下文中)的粗略等效项是 HTML helper。 HTML 帮助程序作为静态扩展方法实现,这允许它们在视图之间共享并在加载视图时执行一些操作。

using System.Web.Mvc;
using System.Web.Mvc.Html;

public static class MyExtensions
{
    public static MvcHtmlString TextBox1(this HtmlHelper helper, string name)
    {
        if (helper.ViewContext.HttpContext.Request.Path.ToUpper().Contains("/SAMPLE"))
        {
            return InputExtensions.TextBox(helper, name, null, new { @readonly = "readonly" });
        }

        return InputExtensions.TextBox(helper, name);
    }
}

用法

~/Views/Shared/_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>
                </div>
                <div class="float-right">
                    <section id="login">
                        @Html.Partial("_LoginPartial")
                    </section>
                    <nav>
                        <ul id="menu">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                        </ul>
                    </nav>
                </div>
            </div>
        </header>
        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">

                @* Render custom HTML Helper *@
                @Html.TextBox1("test")

                @RenderBody()
            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p>
                </div>
            </div>
        </footer>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>

请注意,也可以将逻辑直接放在视图中,但这样您就不能在其他视图中重用逻辑,这会使您的视图看起来很杂乱。

至于从文本框中读回数据,您需要将其放在 <form> 标记内,以便可以将其发布到控制器操作方法,这大致相当于提交按钮单击事件。与 ASP.NET 不同,MVC 支持多个 <form> 标记,因此您不必为页面上的不同操作混合逻辑。