2

I want to extend MVC with helpers. Let's assume I want to build an extension method that takes a property from the model and renders a paragraph.

I've written this code, but it won't compile. I didn't figure out how to do it:

public static class PExtension
{
    public static string PFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) where TModel: class 
    {
        var f = expression.Compile();
        // won't compile the line below:
        string propretyValue = f();
        return "<p>" + propretyValue + "</p>";
    }
}

For the record, my view should use something like:

@Html.PFor(m => m.Description);

Thanks.

EDIT

Error Description: *Delegate 'Func' does not take 0 arguments*

2 Answers 2

1

The expression parameter is specifying that the return value of the expression is TValue, but you are attempting to assign the return value of the compiled expression to a string. I'm guessing the compile error is something about "Cannot convert TValue to string"?

try this instead:

object propertyValue = f();
return string.Format( "<p>{0}</p>", propertyValue != null ? propertyValue.ToString() : string.Empty );

Update:

the error you posted indicates that you need to pass the model object to the expression in order for it to be evaluated. in looking at the ASP.NET MVC source code for how they do their extensions methods, they are obtaining the model from the ViewData like this:

ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

so try this:

ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
object propertyValue = f((TModel)metadata.Model);
return string.Format( "<p>{0}</p>", propertyValue != null ? propertyValue.ToString() : string.Empty );
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, I will post an answer with a little correction, but you pointed me in the right direction. Thanks.
1

Finally, code looks like this:

 public static class PExtension
    {
        public static MvcHtmlString PFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) where TModel : class
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);

            return MvcHtmlString.Create(string.Format("<p>{0}</p>", metadata.Model != null ? metadata.Model.ToString() : string.Empty));
        }
    }

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.