Stack Overflow Exception in MVcHtmlString

回眸只為那壹抹淺笑 提交于 2019-12-23 12:27:37

问题


I have created my own Html Helper which adds red asterisks to any required field.

It successfully works with both

@Html.myLabelFor(model => model.Description)
//and
@Html.myLabelFor(model => model.Description, new { /*stuff*/ })

However, some of the code lines are like following

@Html.myLabelFor(model => model.Description, "Deletion Reason", new { /*stuff*/ })

My method was not designed to handle 3 parameters, so I added a caller which would handle 3 parameters

public static MvcHtmlString myLabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
     Expression<Func<TModel, TValue>> expression, string labelText, Object htmlAttributes)
  {
      return myLabelFor(html, expression, labelText, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
  }    

Below are other methods that are working properly (including internal, which contains all necessary code and whose structure I used as a reference)

public static MvcHtmlString myLabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
   Expression<Func<TModel, TValue>> expression, IDictionary<String, Object> htmlAttributes)
  {
      return LabelHelper(html, ModelMetadata.FromLambdaExpression(expression, html.ViewData),
          ExpressionHelper.GetExpressionText(expression), null, htmlAttributes);
  }

  public static MvcHtmlString myLabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
  Expression<Func<TModel, TValue>> expression)
  {
      return LabelHelper(html, ModelMetadata.FromLambdaExpression(expression, html.ViewData),
          ExpressionHelper.GetExpressionText(expression), null);
  }

  public static MvcHtmlString myLabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
      Expression<Func<TModel, TValue>> expression, Object htmlAttributes)
  {
      return myLabelFor(html, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
  }

  //USED ITS STRUCTURE AS A REFERENCE
  internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName,
      String labelText = null, IDictionary<String, Object> htmlAttributes = null)

Logically, I was expecting that parameter labelText would take a value of "Deletion Reason" from the line of code above. However, instead it had thrown a StackOverflowException inside my 3-parameter method. Microsoft description was vague, additional explanation did not help, and additional solution was using

Expression<Func<TModel, string>> expression instead of my Expression<Func<TModel, TValue>> expression

I do not understand what I am doing wrong. At this point I can only think of "fiddle with parameters until it works", but I am hopeful there is more elegant solution to that problem.

PS: Please let me know if my code for internal helper will help to solve the problem.


回答1:


You getting an exception on the first overload, because the method is recursively calling itself, and keeps doing so until the execution stack overflows. Rather than calling itself you need to change

return myLabelFor(html, 
                  expression,
                  labelText,
                  HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

to

return LabelHelper(html,
                   ModelMetadata.FromLambdaExpression(expression, html.ViewData),
                   ExpressionHelper.GetExpressionText(expression),
                   labelText,
                   HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

From your comments, the reason your 4th overload which uses return myLabelFor(...) does not throw the exception is because it calls your 2nd overload which in turn calls return LabelHelper(...)

I recommend that you change the 4th overload to call LabelHelper() directly, and change all the public overloads to explicitly call LabelHelper(), passing all 4 parameters, which is the pattern used by the in-built `HtmlHelper extension methods (you can view the source code for LabelFor() here)



来源:https://stackoverflow.com/questions/38003156/stack-overflow-exception-in-mvchtmlstring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!