0

I am learning ASP.Net MVC 5 , and I am stuck at usage of extention method. So I created an extension method and now I want to use it in my Razor view. But it's throwing error InvalidOprationException Error.

Model

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Display(Name = "Amount Owed")]
    public decimal Amount { get; set; }
}

View

@model IEnumerable<WebApplication3.Models.Student>
@using WebApplication3.Extension
<table class="table" id="studentstable" style="border: 1px solid black; background-color: silver">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.Name)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Amount)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Amount)
    </th>
</tr>

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @item.Amount.ConvertToDollar() @* this works fine *@
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Amount.ConvertToDollar())  @*I want somwething like this so that I do not lose the HTML HELPERs*@
        </td>
    </tr>
}
</table>

Extension Method

namespace WebApplication3.Extension
{
    public static class Helper
    {
        public static string ConvertToDollar(this decimal amount)
        {
            return String.Format("{0:C}", amount);
        }
    }
}

Error Line:

@Html.DisplayFor(modelItem => item.Amount.ConvertToDollar()). I can use simply @item.Amount.ConvertToDollar() But I want to embed it in HTMLHELPER. Please guide me. Is this even possible?

9
  • What do you mean embed it in HTMLHELPER? And this functionality is already built in to the frame work. You just add a [DisplayFormat(DataFormatString = "{0:C}")] attribute to your Amount property and use @Html.DisplayFor(m => item.Amount) You do not need to reinvent the wheel Commented Aug 4, 2017 at 22:35
  • @StephenMuecke: Thank you for the inputs. But I just explicitly wanted to use it so that, I can know how to use extension method. This was just an example. I did not mean to develop it logically. I just wanted to know how to use extension method. And be able to use it to show some stuff in UI using Razor code. Commented Aug 5, 2017 at 0:24
  • Suppose we really have a scenario where we need to use extension method. Then how to apply it in razor code. I mean I can write something like @model.blabla.extensionmethod() but I want to utilize the strongly typed stuff too. Commented Aug 5, 2017 at 0:25
  • I want to be able to use HTML helper and display the porperties by applying extension methods Commented Aug 5, 2017 at 0:26
  • There are plenty of examples on the web of how to create HtmlHelper extension methods. But in this case it would make no sense at all to create one. And a good place to start is to study the source code. But without knowing just what you really want to do its impossible to help Commented Aug 5, 2017 at 0:30

1 Answer 1

1

TLDR; You can not use an method at the end of the lambda that will be passed to @Html.DisplayFor(). You need to either convert your data earlier, use @Html.Display() or write display the data yourself.

Edited: The @Html.DisplayFor(modelItem => item.Amount.ConvertToDollar()) call throws the folowing error on my test project (i reconstructed a project similar to your for demonstration purposes)

InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions. This means that you can not use ConvertToDollar() in this call. You have to convert the value BEFORE returning it.

As far as i know you can not call an extension method at the end of a lambda before passing it to @Html.DisplayFor. You will have to use either an Attribute to decorate your class or a property a bit like

    [Display(Name = "Amount Owed")]
    public string AmountAsMoney => $"${this.Amount}";

I'm sorry, I don't think what you are trying to do is possible :-(

As requested, I found this example of real useful usage for an extension method in c#. As for personal example, i can not provide any code but so far i have only used extension methods in order to add functionality to a class defined in an other library that I didn't feel like inheriting, or that was sealed. (this goes againsst OOP principles but, still, we CAN do it.)

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

15 Comments

Ok, I will ask my doubt again. First forget that I want to convert amount to dollar. I know that it can be handled by the framework itself. But I was just learning about Extension method. And I explicitly wanted to use it. We only write extension method for the functionality which is most commonly used in the application and that functionality is not provided by framework. Also, to remove code duplication. With this in mind. suppose we do not have the functionality for the conversion of dollar symbol on amount. So, I wrote a sample extension method which will append amount with dollar symbol
So far so good. But my question is how to call extension method from htmlhelper. Supose I want to convert amount into dollar at 1000 places
Why do I need to write some thing like this ` @item.Amount.ConvertToDollar()`
I wanted to use inbuild htmlhelper and call the extension method. something like @Html.DisplayFor(modelItem => item.Amount.ConvertToDollar())
So bascially, I am trying to learn about extension method and how to call them in Razor code.
|

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.