2015-03-05 2 views
1

Я сделал свой первый помощник MVC для разделения длинных строк в таблице, и я также проверяю, является ли строка NULL, и пользователь может отправить NullString ='NA' вместо пустой строки.Объект MVC Helper и его название

public static IHtmlString Split(
     this HtmlHelper helper, 
     string source, 
     int size = 30, 
     string NullString = "") 

Теперь у меня есть ситуация, когда строка находится внутри объекта, и этот объект также может быть нулевым.

@if (item.city == null) 
{ 
    <td>NA</td> 
} 
else 
{ 
    <td class="format">@item.city.name</td> 
} 

Я хочу сделать что-то общее, где я получаю объект и имя свойства. Тогда я могу получить значение от объекта.

public static IHtmlString Split(
     this HtmlHelper helper, 
     OBJECT source, 
     STRING property, 
     int size = 30, 
     string NullString = "") 

Есть ли способ я могу получить source.property() от родового объекта?

по запросу полный код моей текущей функции

public static IHtmlString Split(this HtmlHelper helper, string source, int size = 30, string NullString = "") 
    { 
     TagBuilder tb = new TagBuilder("td"); 
     tb.Attributes.Add("class", "format"); 

     if (source == null) 
     { 
      tb.InnerHtml = NullString; 
     } 
     else if (source.Length < size) 
     { 
      tb.InnerHtml = source; 
     } 
     else 
     { 
      int middle = source.Length/2; 
      int before = source.LastIndexOf(' ', middle); 
      int after = source.IndexOf(' ', middle + 1); 

      if (before == -1 || (after != -1 && middle - before >= after - middle)) 
      { 
       middle = after; 
      } 
      else 
      { 
       middle = before; 
      } 

      string s1 = source.Substring(0, middle); 
      string s2 = source.Substring(middle + 1); 

      tb.InnerHtml = s1 + "<br />" + s2; 
     } 
     MvcHtmlString result = new MvcHtmlString(tb.ToString(TagRenderMode.Normal)); 
     return result; 
    } 
+0

Можете ли вы опубликовать код вашей функции split? – shenku

+0

Хорошо, но это не та часть, с которой у меня проблема. –

+0

Вместо источника объекта вы должны написать выражение Lambda с помощью выражения 'Expression >'. –

ответ

1

Один подход должен был бы получить тип объекта, а затем проверить существование свойства данного имени. Ваш вспомогательный метод будет принимать следующие аргументы:

public static IHtmlString Split(
    this HtmlHelper helper, 
    object source, 
    string property = "", 
    int size = 30, 
    string NullString = "") 

Тогда вы получите System.Type исходного объекта и решить, следует ли рассматривать его как строку, или попытаться получить значение некоторого заданного свойства.

 var stringToSplit = string.Empty; 
     if (source == null) 
     { 
      stringToSplit = NullString; 
     } 
     else if (string.IsNullOrEmpty(property)) 
     { 
      stringToSplit = source.ToString(); 
     } 
     else 
     { 
      Type type = source.GetType(); 
      var propertyInfo = type.GetProperty(property); 
      if (propertyInfo != null) 
      { 
       var propertyValue = propertyInfo.GetValue(source); 
       stringToSplit = propertyValue != null ? propertyValue.ToString() : NullString; 
      } 
      else 
      { 
       stringToSplit = NullString; 
      } 
     } 

Тогда вы бы проверить длину stringToSplit и разделить его в случае необходимости.

+0

Работа совершенна и очень проста, теперь в конце мне просто нужно вызвать мою старую функцию, передав 'stringToSplit'. Также, следуя вашей идее сделать опцию 'property' опционально, я переопределяю метод ToString в моем классе, чтобы вернуть имя. Я очень доволен своим взглядом: D –

1

Это, как я мог бы это сделать.

Используйте шаблоны Razor для создания метода расширения, который принимает объект для проверки и лямбда, чтобы захватить строку.

public static class HtmlHelperExtensions 
{ 
    public static IHtmlString AlternateTemplates<TModel>(this HtmlHelper htmlHelper, TModel model, 
     Func<TModel, string> stringProperty, Func<string, HelperResult> template, 
     Func<object, HelperResult> nullTemplate) where TModel : class 
    { 
     HelperResult result; 

     if (model != null) 
     { 
      var propertyValue = stringProperty.Invoke(model); 
      var splitValue = YourCustomSplitFunction(propertyValue); // TODO: Impliment yout split function to return a string (in this case) 

      result = template(splitValue); 
     } 
     else 
     { 
      result = nullTemplate(null); 
     } 

     htmlHelper.ViewContext.Writer.Write(result); 

     return MvcHtmlString.Empty; 
    } 
} 

Учитывая модель, как это:

public class ViewModel 
{ 
    public Region Region { get; set; } 
} 

public class Region 
{ 
    public string City { get; set; } 
} 

Мои действия контроллера в качестве примера:

На мой взгляд, я мог бы назвать:

@Html.AlternateTemplates(Model.Region, x => x.City, @<div>@item</div>, @<div>N/A</div>) 

Итак, это если проверка объект, который я отправляю (в данном случае это Region), не является нулевым, затем захватить указанное мной свойство (в этом случае City), затем отрисуйте его против моего первого шаблона html/razor, иначе используйте альтернативу.

Легко.

Некоторые чтения: http://www.prideparrot.com/blog/archive/2012/9/simplifying_html_generation_using_razor_templates

+0

Я думаю, что ваш метод интересен.Но в моем представлении у меня есть IEnumerable и внутри 'foreach (item in Model)' i try do '@ Html.AlternateTemplates (item, x => x.city.name, @ @item, @ N/A) 'и не только сбой, но даже не показывайте мою страницу отладки, потому что сказано, что« никакие символы не были загружены ». Удалите строку, и я могу отлаживать разрыв непосредственно перед этой строкой. –