如何做到“妥善”?MVC

本文关键字:MVC 妥善 何做 | 更新日期: 2023-09-27 18:16:38

我是一个较新的web开发人员(~1年的经验),刚刚加入了一家新公司,该公司使用Umbraco CMS为我们开发的许多网站。在我的上一份工作中,我只接触过WebForms,所以我在开始这份工作之前对MVC做了一点研究,并做了一个非常初学者的教程,但我不确定我是否理解社区的"最佳实践",当涉及到这些东西时,希望你们能帮助我。当谈到Umbraco CMS时,有一个叫做"宏脚本"的组件,它本质上是一个Razor视图(.CSHTML),它允许你编写一堆c#代码;并在您选择的任何CMS页面上显示此"宏脚本"。

在我的教程中(我在2个多月前完成),我想我记得读过一些关于永远不要将条件逻辑/c#与HTML混合的东西,并且最好使用模型&控制器吗?我有点困惑,因为我们并没有真正建立控制器在我们的网站放在第一位,因为他们是CMS页面,如果他们需要任何东西除了富文本,然后我们只是创建一个"宏脚本",并把它放在需要扩展功能的页面。

我在这里工作的第一个月发现,如果我能够使我的代码在整个网站上可重用,我可以节省很多时间,但我不确定如何以一种"MVC友好"的方式做到这一点?下面是一个示例"宏脚本",它显示在CMS中创建的表单,然后尝试获取公司的"联系"信息并将其显示在表单下面。我附上的例子非常简单,但是我看到的一些宏脚本变成了500多行的可怕的混乱,其中有巨大的for-each循环、开关和不可读的代码块。

是否有可能将这种类型的代码分割成在此视图中使用的模型?与将所有代码都放在同一个视图中相比,拆分代码有什么好处吗?(如果有足够的好处,我想把这个介绍给我的同事,并改变编码标准)。有人能给我一个例子,这将如何看,如果它被分割成适当的"MVC"?如果这不是正确的地方张贴这类问题,请指出我到一个更好的StackExchange网站。谢谢。

宏脚本抓取CMS表单&公司信息

@inherits umbraco.MacroEngines.DynamicNodeContext
@*
    Model = The current page the macro is executed on
            @Model.bodyText
    Parameter = collection of parameter values passed from the macro
            @Paramter.myParam
    Library = utillity library with common methods
            @Library.NodeById(1233)
*@
@* The fun starts here *@
@{
    string formClass = "form-content";
    var configNode = Model.AncestorOrSelf().Descendants("ConfigurationContainer").FirstOrDefault();
    if (configNode != null && configNode.Id > 0)
    {
        formClass = "form-content show-address";
    }
    if (custom.Library.NodeHasPropertyAndValue(Model, "bodyText"))
    {
        <hr />
    }
    <div class="form-page contact-us">
        <div>
            <div class="@formClass">
               @Html.Raw(umbraco.library.RenderMacroContent("<?UMBRACO_MACRO macroAlias='"umbracoContour.RazorRenderForm'" formGuid='""+Model.selectedForm+"'" ></?UMBRACO_MACRO>", Model.Id))
            </div>
        @if (configNode != null && configNode.Id > 0)
        {
            <address class="address-content">
                @if (custom.Library.NodeHasPropertyAndValue(configNode, "officeAddress"))
                {
                    var addressDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeAddress2")) ? string.Format("{0}, {1}", configNode.officeAddress, configNode.officeAddress2) : configNode.officeAddress;
                    string locationString = string.Empty;
                    string cityDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeCity")) ? configNode.officeCity : string.Empty,
                    stateDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeState")) ? configNode.officeState : string.Empty,
                    zipDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeZip")) ? configNode.officeZip : string.Empty;
                    if (!string.IsNullOrEmpty(cityDisplay) && !string.IsNullOrEmpty(stateDisplay))
                    {
                        locationString = string.Format("<br />{0}, {1} {2}", cityDisplay, stateDisplay, zipDisplay);
                    }
                    @addressDisplay@Html.Raw(locationString)
                }
                @if (custom.Library.NodeHasPropertyAndValue(configNode, "officePhone"))
                {
                    <br /><i class="fa fa-phone"></i> @configNode.officePhone
                }
                @if (custom.Library.NodeHasPropertyAndValue(configNode, "officeFax"))
                {
                    <br /><i class="fa fa-fax"></i> @configNode.officeFax
                }
                @if (custom.Library.NodeHasPropertyAndValue(configNode, "officeEmail"))
                {
                    <br /><i class="fa fa-envelope"></i> <a href="mailto:@configNode.officeEmail">@configNode.officeEmail</a>
                }
            </address>
        }
        </div>
    </div>
    if (custom.Library.NodeHasPropertyAndValue(Model, "lowerText"))
    {
        @Html.Raw(Model.lowerText)
    }
}

如何做到“妥善”?MVC

我将在这里使用Umbraco术语,乍一看可能不像Asp。Net MVC:

你需要问自己——你需要使用宏吗?如果你将宏直接嵌入到模板中,那么你可以使用PartialView(在/Views/Partials中找到,就像标准MVC一样)或者直接将布局合并到模板中(在/Views中找到)。

你应该做的第一件事是查看Umbraco文档(注意每个主题目标的Umbraco版本-那里仍然有Umbraco 4.10+特定的内容):

https://our.umbraco.org/documentation/Reference/Templating/

关于分离逻辑:

Code First Models:看看Umbraco Ditto -这是一种使用Umbraco IPublishedContent模型的方法;有相当多的文档,所以它应该是相当简单的实现。

控制器:你可以使用ASP。Net MVC控制器来支持你的部分和提供模型;你需要从SurfaceControllers继承:

https://our.umbraco.org/documentation/Reference/Routing/surface-controllers

渲染宏:不要使用@Html.Raw(umbraco.library.RenderMacroContent(..)) -它几乎被弃用了。现在的标准方法是用@Umbraco.RenderMacro()。所以这:

@Html.Raw(umbraco.library.RenderMacroContent("<?UMBRACO_MACRO macroAlias='"umbracoContour.RazorRenderForm'" formGuid='""+Model.selectedForm+"'" ></?UMBRACO_MACRO>", Model.Id))

@Umbraco.RenderMacro("FormsRenderForm", new { FormGuid = Model.selectedForm })

最后的想法:

就我个人而言,我不会使用宏来生成您的内容,除非您需要允许后台用户将功能嵌入到页面中并提供参数。如果不是这种情况,您最好直接在模板或分部视图中实现布局。