考虑到这种当前状态有多糟糕,因为除了感觉错误之外,它并没有真正导致理解代码或创建任何不良依赖关系的任何重大问题。
当前状态非常糟糕,不仅仅是因为 UI 代码包含在域代码中。那已经很糟糕了,但这更糟。该NameIdHTML
属性返回一个硬编码的链接到该人的 UI 页面。即使在 UI 代码中,您也不应该对此类链接进行硬编码。这就是目的LinkExtensions.ActionLink
和UrlHelper.Action
目的。
如果您更改控制器或路由,链接将会更改。LinkExtensions
并UrlHelper
意识到这一点,您不需要任何进一步的更改。当您使用硬编码链接时,您需要在代码中找到此类链接被硬编码的所有位置(并且您需要知道这些位置存在)。更糟糕的是,您需要更改的代码位于与依赖链相反方向的业务逻辑中。这是维护的噩梦,也是错误的主要来源。你需要改变这一点。
如果这里有最佳实践,因为这似乎是一个常见的问题/模式。
是的,有一个最佳实践,那就是在您需要指向控制器操作返回的页面的链接时使用上述LinkExtensions.ActionLink
和方法。UrlHelper.Action
坏消息是,这意味着您的解决方案中的多个位置都会发生变化。好消息是很容易找到这些位置:只需删除该NameIdHTML
属性,错误就会弹出。除非您通过反射访问该属性。在这种情况下,您需要进行更仔细的代码搜索。
您将需要替换NameIdHTML
为使用LinkExtensions.ActionLink
或UrlHelper.Action
创建链接的代码。我假设NameIdHTML
返回的 HTML 代码应在此人显示在 HTML 页面上时使用。我还假设这是您代码中的常见模式。如果我的假设是正确的,您可以创建一个帮助类,将业务对象转换为它们的 HTML 表示。您可以向该类添加扩展方法,以提供对象的 HTML 表示。为了说明我的观点,我假设(假设地),你有一个Department
类,它也有Name
,Id
并且有类似的 HTML 表示。然后,您可以重载转换方法:
public static class BusinessToHtmlHelper {
public static MvcHtmlString FromBusinessObject( this HtmlHelper html, Person person) {
string personLink = html.ActionLink(person.Name, "Detail", "People",
new { id = person.Id }, null).ToHtmlString();
return new MvcHtmlString(personLink + " (" + person.Id + ")");
}
public static MvcHtmlString FromBusinessObject( this HtmlHelper html,
Department department) {
string departmentLink = html.ActionLink(department.Name, "Detail", "Departments",
new { id = department.Id }, null).ToHtmlString();
return new MvcHtmlString(departmentLink + " (" + department.Id + ")");
}
}
在您的视图中,您需要NameIdHTML
通过调用此辅助方法来替换。例如这段代码...
@person.NameIdHTML
...需要替换为:
@Html.FromBusinessObject(person)
这也将使您的视图保持干净,如果您决定更改您的视觉表示,Person
则可以轻松更改BusinessToHtmlHelper.FromBusinessObject
而不更改任何视图。此外,生成的链接会自动反映对路由或控制器的更改。UI 逻辑保留在 UI 代码中,而业务代码保持干净。
如果您想让您的代码完全不受 HTML 影响,您可以为您的人员创建一个显示模板。优点是您的所有 HTML 都包含视图,缺点是您要创建的每种类型的 HTML 链接都需要一个显示模板。Person
显示模板看起来像这样:
@model Person
@Html.ActionLink(Model.Name, "Detail", "People", new { id = Model.Id }, null) ( @Html.DisplayFor(p => p.Id) )
您必须person.NameIdHTML
用此代码替换您的引用(假设您的模型包含Person
type 的属性Person
):
@Html.DisplayFor(m => m.Person)
您也可以稍后添加显示模板。您可以创建BusinessToHtmlHelper
第一个和作为将来的第二个重构步骤,在引入显示模板后更改帮助程序类(如上面的那个):
public static class BusinessToHtmlHelper {
public static MvcHtmlString FromBusinessObject<T>( this HtmlHelper<T> html, Person person) {
return html.DisplayFor( m => person );
}
//...
}
如果您只小心使用由 创建的链接BusinessToHtmlHelper
,您的视图将不需要进一步更改。