0

I am wanting to pass a template parameter to my helper method for rendering errors. I have seen several examples where this is done but appear to require that the variables in the template are in scope when the helper is invoked.

e.g. Expression of HelperResult to format item from a list

I am hoping to do something like:

    public static MvcHtmlString ErrorBlock<TModel>(this HtmlHelper helper, TModel model, string @class = null, object context = null, string view = null, object attributes = null, Func<ErrorModel,HelperResult> errorTemplate = null)
        where TModel : ErrorModel

...

@ShopMR.ErrorBlock(Model, errorTemplate: r => @<div>@r.Message</div>)

But I get the following compiler errors:

  1. Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
  2. Cannot convert lambda expression to type 'HelperResult' because it is not a delegate type

I have tried creating a delegate but it results in the same error. Is this possible? Should my func return some other type that can be compiled/evaluated as Razor text?

2 Answers 2

1

To get rid of the compilation errors change the rasor to this :

@ShopMR.ErrorBlock(Model, errorTemplate:r => new HelperResult( x => { x.WriteLine($"<div>r.Message</div>" ); } )

The errorTemplate was expecting a lambda expression that returns HelperResult Template.

Sign up to request clarification or add additional context in comments.

1 Comment

That fixed the issue although I was hoping there was a cooler solution that would still allow me to leverage compile-time checking. Thank you so much!
0

After blundering around I came up with something I liked a little better (although I am sure there is a cleaner solution)

    public static MvcHtmlString ErrorBlock<TModel>(this HtmlHelper helper, TModel model, 
        string @class = null, object context = null, string view = null, object attributes = null, 
        Func<ErrorModel, Func<ErrorModel,IHtmlString>> errorTemplate = null)
        where TModel : BaseModel
    {
    ...
        if (errorTemplate != null)
        {
            var formattedErrors = errors.Select(e => errorTemplate?.Invoke(e)?.Invoke(e)?.ToHtmlString() ?? string.Empty);
            tb.InnerHtml = string.Join("", formattedErrors);
        }
    }
    ....

This allowed me to use my intended syntax in calling the extension:

@ShopMR.ErrorBlock(Model, errorTemplate: r => @<div>@r.Message</div>)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.