ASP.NET MVC: хорошая замена для пользовательского элемента управления?

Я нашел, что пользовательские элементы управления были невероятно полезны при работе с веб-формами ASP.NET. Путем инкапсуляции кода, требуемого для отображения управления с разметкой, создание допускающих повторное использование компонентов было очень просто и очень, очень полезно.

В то время как MVC обеспечивает удобное разделение проблем, это, кажется, повреждает инкапсуляцию (т.е., можно добавить управление, не добавляя или с помощью его кода поддержки, ведя к ошибкам периода выполнения). Имея необходимость изменить контроллер каждый раз, когда я добавляю управление к представлению, кажется, мне интегрирует проблемы, не разделяет их. Я повредил бы пуристскую идеологию MVC, чем бросил бы преимущества допускающих повторное использование, упакованных средств управления.

Я должен смочь включать компоненты, подобные пользовательским элементам управления веб-форм всюду по сайту, но не для всего сайта, и не на уровне, который принадлежит основной страницы. Эти компоненты должны иметь свой собственный код не только разметка (для взаимодействия с бизнес-слоем), и было бы замечательно, если бы контроллер страницы не должен был знать об управлении. Так как пользовательские элементы управления MVC не имеют codebehind, я не вижу хороший способ сделать это.

Обновление НАКОНЕЦ, польза (и, ретроспективно, очевидный) способ выполнить это.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace K.ObjectModel.Controls
{
    public class TestControl : ViewUserControl
    {
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write("Hello World");
            base.Render(writer);
        }
    }
}

Создайте новый класс, который наследовался ViewUserControl

Переопределите .Render() метод как показано выше.

Зарегистрируйте управление через его связанный ASCX, как Вы были бы в веб-форме:

<%@ Register TagName="tn" TagPrefix="k" Src="~/Views/Navigation/LeftBar.ascx"%>

Используйте соответствующий тег в любом представлении или основной странице, в которой Вы нуждаетесь:

<k:tn runat="server"/>

Удостоверьтесь, что Ваш .ascx наследовал Ваше новое управление:

<%@ Control Language="C#" Inherits="K.ObjectModel.Controls.TestControl" %>

Вуаля, Вы в порядке. Это тестируется с ASP.NET MVC 2, VS 2010 и.NET 4.0.

Ваш пользовательский тег ссылается на ascx частичное представление, которое наследовалось классу TestControl. Управление затем переопределяет Render() метод, который называют для рендеринга представления, давая Вам полный контроль над процессом от тега для вывода.

Различие между использованием этого подхода и вызовом Html.RenderPartial() или 'HTML. RenderAction ()' добавляет, что управление к представлению сделано с подобным веб-формам тегом, который не только более удобен для разработчиков, но и мешает им иметь для знания о названиях контроллера и методах. Название класса управления изолируется к ASCX, также помогая отбросить их в блоке и снова использовать их через отдельные проекты.

Некоторые могут сказать, что это нарушает SoC, но я полагаю, что этот подход функционально эквивалентен связыванию частичного представления и контроллера при поддержании чистой разметки. Должно быть ясно, однако, что это все еще до разработчика для хранения только связанной с презентацией логики в логике Бизнеса и доступа к данным управления, все еще принадлежат их соответствующих слоев.

11
задан 3Dave 26 May 2010 в 15:58
поделиться

5 ответов

На первый взгляд легко отбросить MVC как не имеющий возможностей для создания многократно используемых компонентов.

После знакомства с ASP.NET MVC вы обнаружите, что существует несколько методов создания богатых элементов управления и компонентов, а инкапсуляция аспектов MVC идет по тем же путям, что и инкапсуляция приложения WebForms.

Я думаю, что вы рассматриваете только аспекты представления в MVC, а не то, как все базовые M и C могут быть инкапсулированы и связаны вместе. Частичные представления, Render Action/Partial - это лишь небольшие части базовых компонентных возможностей MVC. Под обложкой скрывается гораздо больше богатства.

4
ответ дан 3 December 2019 в 08:54
поделиться

пользовательский элемент управления - это просто некоторые вещи, которые визуализируют html , в mvc у вас есть помощники html и частичные представления и обычные представления (вы можете отображать их с помощью визуализации)

Html.Helper("someStuff")
Html.RenderPartial("viewname")
Html.RenderAction<Controller>(o => o.Action());

, поэтому в основном это просто помощники

, вы можете легко заменить вызов

Html.TextBoxFor(o => o.Name);

на

Html.RenderPartial("textbox", Model.Name);
2
ответ дан 3 December 2019 в 08:54
поделиться

В качестве примера возьмем страницу регистрации для сайта электронной коммерции. Вы запрашиваете у пользователя его имя, пароль, почтовую информацию, любимую породу собаки и т. Д. В другом месте приложения вам также необходимо указать адрес для выставления счетов и адрес доставки. Чтобы принудительно применить DRY, вы создаете пользовательский элемент управления, который управляет вводом адресной информации.

Итак, чтобы проиллюстрировать, ваш класс адреса выглядит примерно так:

public class Address
{
    public string StreetAddress { get; set; }
    public string City { get; set; }
    ...
}

Ваш класс регистрации:

public class UserReg
{
    public string UserName { get; set; }
    public Address MailingAddress { get; set; }
    ...
}

Ваши адреса для выставления счетов и доставки могут происходить от класса Address:

public class BillingAddress : Address
{ 
    ...
}

public class ShippingAddress : Address
{ 
    ...
}

Для следующих примеров я предполагаю что вы добавили System.Web.Mvc в раздел namespaces файла web.config .На основе этой иерархии классов ваш пользовательский элемент управления будет иметь тег элемента управления, который относится только к классу Address:

<%@ Control Language="C#" Inherits="ViewUserControl<Address>" %>

Поскольку вы это сделали, вам просто нужно передать соответствующую ссылку на модель со страницы. На странице регистрации пользователя:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<UserReg>" %>
    ...
    <% Html.RenderPartial("AddressControl", Model.MailingAddress); %>

На странице адреса для выставления счетов:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<BillingAddress>" %>
    ...
    <% Html.RenderPartial("AddressControl", Model); %>

На странице адреса доставки:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<ShippingAddress>" %>
    ...
    <% Html.RenderPartial("AddressControl", Model); %>

Я могу передать модель прямо со страницы выставления счетов и доставки, потому что класс напрямую происходит от Address. Пока существует логика для правильной обработки адресов, вам не придется вносить много изменений в контроллер, если таковые имеются.

1
ответ дан 3 December 2019 в 08:54
поделиться

Рассмотрим следующий пример:

  • Мое представление (CustomerDetail.ascx) привязывается к модели представления ICustomerDetail, которая выглядит так:

    interface ICustomerDetail {{ 1}} {
    имя строки {get; }
    Адрес CurrentAddress {get; }
    }

  • Я могу создать частичное представление Address.ascx, которое привязывается к модели представления IAddress

  • Когда я создаю CustomerDetail.ascx, я могу разместить Address.ascx на на той же поверхности и привяжите ее к полю oCustomerDetail.Address

  • IMO - мы должны составлять представления из нескольких таких меньших частичных представлений в MVC, и именно здесь вы увидите возможность повторного использования и силу пользовательские элементы управления (частичные представления)

  • Теперь, если мой контроллер вернет ICustomerDetail, я смогу без проблем повторно использовать Address.ascx

HTH.

1
ответ дан 3 December 2019 в 08:54
поделиться

Я немного запуталась.

Прежде всего, .NET MVC, эквивалентный элементам управления пользователя, - это Частичные представления . Частичные представления - это удобный способ инкапсулировать общие функции просмотра в одном месте. Затем вы можете вызвать частичное представление из другого представления.

Во-вторых, изменение представления не должно означать также изменение контроллера. Если вам необходимо внести изменения в оба параметра только потому, что изменилось ваше представление (а не базовые данные), то где-то в этой строке есть проблема с кодом.

5
ответ дан 3 December 2019 в 08:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: