gpt4 book ai didi

asp.net-mvc - 用户控件的 MVC 替代品

转载 作者:行者123 更新时间:2023-12-04 16:01:52 26 4
gpt4 key购买 nike

我们正在将大型 WebForms 应用程序转移到 MVC。

在 WebForms 应用程序中,我们有一些可重用的控件 (.ascx)。例如,一个在您键入时显示用户名建议的文本框。该控件向页面添加了一些 JS/CSS,具有一些服务器端逻辑和自定义属性(如 SelectedUserID)。

在 MVC 应用程序中它应该是什么?我如何将这些东西封装到 MVC 应用程序中的一个可重用实体中?也许是局部 View ?但是您不能将 JS/CSS 添加到页面的 <head>。从局部 View (最好检查它是否尚未添加)...另外,我如何返回类似提到的 SelectedUserID 的内容在局部 View 中?

重新表述问题 - 您将如何在 MVC 应用中实现这样的控件?

附言。我知道您仍然可以在 MVC 应用程序中使用 .ascx 用户控件,但这似乎是一种“hacky/legacy”方式。什么是“合法”选项?

最佳答案

你的问题很宽泛。我所有的评论/答案都将在 Razor 中.在我看来,如果你打算切换到 MVC,你还不如使用 Razor。转换的理由有很多,但对于任何正在迁移的人,我会说我的首选,最好的理由有两个; first razor 让我放弃了一些关于如何使用 webforms 进行编程的坏习惯,并且在同一个庄园中它迫使我重新编写我的代码,而不是试图复制、粘贴和更改原始代码以在 MVC 中工作。

The control adds some JS/CSS to the page, has some server-side logic and custom properties. What should it be in an MVC app?

这是一个漂亮的religious software问题。有很多方法可以做到这一点。

所以我对如何在 MVC 中添加 JS/CSS 的宗教观点。包含服务器端的一种方法是在 Layout/Master 模板中创建一个区域。

Views/_ViewStart.cshtml

@{
Layout = "~/Views/Shared/Layout.cshtml";
}

Views/Shared/Layout.cshtml

<!doctype html>
<head>
<link href="/Styles/Global.css" rel="stylesheet" type="text/css" />
@RenderSection("Styles", required: false)
<script src="/Scripts/Global.js" type="text/javascript"></script>
@RenderSection("Scritps", required: false)

这将允许每个 View 选择(因为 required=false)使用 RenderSecion 代码添加任何样式或脚本。

Views/Home/Index.cshtml

@section Styles {
<link href="/Styles/Home/Index.css" rel="stylesheet" type="text/css" />
}

这非常简单,对于许多简单到中等复杂的网站来说可能是一个很好的解决方案。这对我来说还不够,因为我需要按照您的要求进行操作,并且只包含真正需要的文件。此外,部分 View 和模板无法呈现部分,我发现这是一个巨大的 PITA。所以我添加了一些 HtmlHelper 扩展方法。 (我只打算展示 Javascript 的代码,因为样式表几乎是相同的代码。这些方法不允许重复的 url。

域/HtmlHelperExtensions.cshtml

public static class HtmlHelperExtensions
{
private const string _JSViewDataName = "RenderJavaScript";
private const string _StyleViewDataName = "RenderStyle";

public static void AddJavaScript(this HtmlHelper HtmlHelper, string ScriptURL)
{
List<string> scriptList = HtmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._JSViewDataName] as List<string>;
if (scriptList != null)
{
if (!scriptList.Contains(ScriptURL))
{
scriptList.Add(ScriptURL);
}
}
else
{
scriptList = new List<string>();
scriptList.Add(ScriptURL);
HtmlHelper.ViewContext.HttpContext.Items.Add(HtmlHelperExtensions._JSViewDataName, scriptList);
}
}

public static MvcHtmlString RenderJavaScripts(this HtmlHelper HtmlHelper)
{
StringBuilder result = new StringBuilder();

List<string> scriptList = HtmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._JSViewDataName] as List<string>;
if (scriptList != null)
{
foreach (string script in scriptList)
{
result.AppendLine(string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", script));
}
}

return MvcHtmlString.Create(result.ToString());
}
}

更新的 Views/Shared/Layout.cshtml

<!doctype html>
<head>
<link href="/Styles/Global.css" rel="stylesheet" type="text/css" />
@Html.RenderStyleSheets()
<script src="/Scripts/Global.js" type="text/javascript"></script>
@Html.RenderJavascripts()

更新 View /Home/Index.cshtml

@Html.AddStyleSheet("/Styles/Home/Index.css")

关于你的下一个问题......

How do I encapsulate those things into one reusable entity in an MVC app? Maybe a partial view?

Razor 支持分部 View 和模板。虽然从技术上讲,两者的功能有很大的重叠,但为了让程序员在需要时利用它们,它们的设计方式存在局限性。

部分 View 需要模型/类才能呈现。这是一个完全有效的局部 View :

/Views/Home/Index.cshtml

@Html.Partial("Partial-Menu")

/Views/Shared/Partial-Menu.cshtml

<div id="menu">
<a href="/">Home</a>
<a href="/Home/About">About Us</a>
</div>

另一方面,模板确实需要模型才能呈现。这是因为模板是一种将任何类或结构呈现为编辑模板或显示模板的方法。

/Models/Person.cs

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

/Controllers/HomeController.cs

public ActionResult Index()
{
Person model = new Person();
model.FirstName = "Jon";
model.LastName = "Doe";

return this.View(model);
}

/Views/Home/Index.cshtml

@model Project1.Models.Person

@Html.DisplayModel()

@Html.EditforModel()

/Views/Shared/DisplayTemplates/Person.cshtml

@model Project1.Models.Person

<div>@Html.LabelFor(x => x.FirstName) @Html.DisplayFor(x => x.FirstName)</div>
<div>@Html.LabelFor(x => x.LastName) @Html.DisplayFor(x => x.LastName)</div>

/Views/Shared/EditorTemplates/Person.cshtml

@model Project1.Models.Person

<div>@Html.LabelFor(x => x.FirstName) @Html.EditorFor(x => x.FirstName)</div>
<div>@Html.LabelFor(x => x.LastName) @Html.EditrorFor(x => x.LastName)</div>

在我看来,任何可能变成用于数据输入的表单的模型都应该是模板。这是我更喜欢封装我的模型的方式。使用前面提供的扩展方法,我的部分 View 和模板都可以根据需要加载包含内容(目前只有我的大量模型之一实际需要使用它)。

我的偏好是每个呈现的页面最多包含三个(每个 Javascript 和样式)。我基本上有一个 Global.css/js、一个 Controller Home.css/js 和一个可能包含的页面 Index.css/js。我很少有 Controller 。

关于asp.net-mvc - 用户控件的 MVC 替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10823583/

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