ASP.NET MVC: логика для конкретной страницы - PullRequest
3 голосов
/ 01 июня 2009

Было много дискуссий по ASP.NET MVC и Codebehind-файлам , в основном там, где указывалось, что эти Codebehind-файлы являются злыми .

Итак, мой вопрос, как вы справляетесь со специфичной для страницы логикой ?

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

Примером может быть:

<% for(int i = 0; i < companyList.Count; i++) { %>
    RenderCompanyNameWithRightCapsIfNotEmpty(company, i)
<% } %>

С сопровождающим кодом:

private string RenderCompanyNameWithRightCapsIfNotEmpty(string company, index)
{
    if (index == 0) {
        return string.Format("<div class=\"first\">{0}</div>", company);
    }
    // Add more conditional code here
    // - page specific HTML, like render a certain icon
    string divClass = (index % 2 == 0) ? "normal" : "alternate";
    return string.Format("<div class=\"{1}\">{0}</div>", company, divClass);
}

Это будет использоваться только на одной странице и, скорее всего, может быть изменено.

Обновление : Подошла пара, я думал о том, где они:

1) Встроенный код на странице - с простыми методами, которые возвращают строки.

<script runat="server">
    private string RenderCompanyHtml(string companyName) ...
<script>

2) Установка метода, который возвращает строку в контроллере. Но это было бы помещением логики представления в контроллер .

public class SomeController : Controller 
{
    [NonAction] 
    private static string RenderCompanyHtml(string companyName) ...

    public ActionResult Index() ...
}

Ответы [ 3 ]

3 голосов
/ 01 июня 2009

Вы должны поместить этот код в элемент управления, где вы готовите данные представления.

Обычно я делаю область "вспомогательными методами" в своем классе контроллера с помощью нескольких методов [NonAction], чтобы поддерживать чистоту.

Итак, мой (упрощенный) контроллер будет выглядеть так:

public class SomeController : Controller 
{
  #region Helper methods
  [NonAction] 
  private static string CompanyNameWithRightCapsIfNotEmpty(string company)
  {
    if (string.IsNullOrEmpty(company)) {
        return company;
    }
    return UpperCaseSpecificWords(company);
  }

  #endregion

  public ActionResult Companies()
  {
    var companies = GetCompanies();
    var companyNames = companies.Select(c =>  CompanyNameWithRightCapsIfNotEmpty(c.Name));
    ViewData["companyNames"] = companyNames;
    return view();
  }
}
2 голосов
/ 01 июня 2009

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

Если вы собираетесь использовать вспомогательный параметр, вам будет лучше обойтись, сделав операцию, которую он выполняет, чуть менее специфичной для страницы. Если ваш метод RenderCompanyNameWithRightCapsIfNotEmpty должен быть настолько конкретным, было бы лучше, если бы ваша модель предоставила его. Один из способов - сделать так, чтобы модель предоставляла список с уже отформатированным текстом и представляла его как общедоступное свойство (скажем, IEnumerable отформатированных названий компаний).

1 голос
/ 01 июня 2009

Используйте Html Helpers.

Подобным образом создайте вспомогательные методы в static классе:

    public static string Label(this HtmlHelper helper, string target, string text)
    {
        return String.Format("<label for='{0}'>{1}</label>", target, text);
    }

.. затем используйте по вашему мнению:

<span><% =Html.Label("FinishDateTime.LocalDatetime", "Finish Time:")%><br />

Вы могли бы создать вспомогательный метод с именем возможно RenderCompanyName(string[] companies), который проверял бы наличие нулей, выполнял манипуляции с заглавными буквами и отображал html между ними - все в одном помощнике, если хотите.

Также: методы действия контроллера должны быть легкими - т.е. только получение данных и возвращение просмотров. Вы должны делегировать такие вещи, как манипулирование данными для представления, представлениям и помощникам HTML.

РЕДАКТИРОВАТЬ: Вот помощник, который вы могли бы после:

Этот помощник отображает IList<> в html в виде неупорядоченного списка <ul>...</ul>. Полезно то, что он дает вам контроль над тем, как выводится список через CSS И , и позволяет отображать дополнительный HTML / контент для каждого элемента. Посмотрите - это помощник:

    public static string UnorderedList<TItem>(this HtmlHelper helper,
        IList<TItem> items, Func<TItem, string> renderItemHtml,
        string ulID, string ulClass, string liClass)
    {
        StringBuilder sb = new StringBuilder();

        // header
        if (!ulID.IsNullOrTrimEmpty()) sb.AppendFormat("<ul id='{0}'", helper.Encode(ulID.Trim()));
        else sb.AppendFormat("<ul");
        if (!ulClass.IsNullOrTrimEmpty()) sb.AppendFormat(" class='{0}'>", helper.Encode(ulClass.Trim()));
        else sb.AppendFormat(">");

        // items
        foreach (TItem i in items)
        {
            if (!liClass.IsNullOrTrimEmpty())
                sb.AppendFormat("<li class='{0}'>{1}</li>", helper.Encode(liClass.Trim()),
                    renderItemHtml(i));
            else
                sb.AppendFormat("<li>{0}</li>", renderItemHtml(i));
        }

        // footer
        sb.AppendFormat("</ul>");

        return sb.ToString();
    }

.. использовать это легко. Вот простой пример для отображения списка тегов:

    <div id="tags">
        <h2>Tags</h2>
        <%=Html.UnorderedList<Tag>(Model.Tags.Tags,tag=>
            {
                return tag.Name;
            },null,null,null) %>
    </div>

.. в моем примере использования вы можете видеть, что я решил не указывать атрибуты css или id, а просто возвращаю имя элемента Tag через анонимный делегат. Анонимные делегаты очень просты в использовании .. в вашем случае, может быть, что-то вроде этого будет работать:

    <div id="tags">
        <h2>Tags</h2>
        <%=Html.UnorderedList<string>(ViewData["companies"],company=>
            {
                if (someCondition) return company.ToUpper();
                else return company;
            },null,null,null) %>
    </div>

.. ViewData["companies"] - это IList<string> для простоты.

...