简体   繁体   English

MVcHtmlString中的堆栈溢出异常

[英]Stack Overflow Exception in MVcHtmlString

I have created my own Html Helper which adds red asterisks to any required field. 我创建了自己的Html Helper,它可以为任何必填字段添加红色星号。

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 我的方法不是为处理3个参数而设计的,所以我添加了一个可以处理3个参数的调用者

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. 从逻辑上讲,我期望参数labelText将从上面的代码行中获取“删除原因”的值。 However, instead it had thrown a StackOverflowException inside my 3-parameter method. 但是,它在我的3参数方法中抛出了StackOverflowException。 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. PS:如果我的内部帮助代码有助于解决问题,请告诉我。

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(...) 你的注释,使用return myLabelFor(...)第4次重载不抛出异常的原因是因为它调用你的第二个重载,而第二次重载又调用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 ) 我建议您更改第4个重载以直接调用LabelHelper() ,并更改所有公共重载以显式调用LabelHelper() ,传递所有4个参数,这是内置的`HtmlHelper扩展方法使用的模式(您可以在这里查看LabelFor()源代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM