18
votes

I am using asp.net mvc 3 and I keep getting this error and I don't understand it since I am not using a template.

I have this in my partial view

@model ViewModels.FormViewModel

    <div="tabs-1">
        @Html.TextBoxFor(x => x.Due.ToShortDateString())
    </div>

in my viewmodel

public class FormViewModel
    {
        public DateTime Due { get; set; }


        public FormViewModel()
        {
            DueDate = DateTime.UtcNow;         
        }
    }

and I get this error

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

6

6 Answers

51
votes

Should be like this:

@Html.TextBoxFor(x => x.Due)

And if you want some format for this date:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime Due { get; set; }

and then:

@Html.EditorFor(x => x.Due)

of if you really want to use this .ToShortDateString() method you need to use a non-strongly typed helper (obviously that's something I would recommend against):

@Html.TextBox("Due", Model.Due.ToShortDateString())
7
votes

There is an overload that can help achieve this, while keeping it strongly typed.

// Specify that you're providing the format argument (string)
@Html.TextBoxFor(x => x.Due, format: Model.Due.ToShortDateString())

// Or use the overload with format and html options, where null is the htmloptions
@Html.TextBoxFor(x => x.Due, Model.Due.ToShortDateString(), null)
5
votes

You're getting the error because the .TextBoxFor() html helper is using a built-in template (a textbox for string input), and you're giving it a lambda expression that is too complicated (i.e. does not belong to the set of types listed in the message).

To solve the problem, either change the type of the property you want to edit to a string, so MVC can use the default string template, or let MVC use the default datetime template instead. I'd recommend the latter:

@Html.TextBoxFor(m => m.Due)

If you're not happy with the way your users are asked to edit a date, put a partial view named "DateTime.cshtml" in ~/Views/Shared/EditorTemplates where you build the editor so it works the way you want.

5
votes

If you are using MVC and have an inline code element, try setting a parameter like this -

@{
string parameterValue = DateTime.Parse(@item.Value).ToShortDateString();

}

@Html.DisplayFor(model => parameterValue)
0
votes

You are misleading the application by passing a method in the parameter of textboxfor instead of passing an expression.

You had :

@Html.TextBoxFor(x => x.Due.ToShortDateString())

Store your result in a variable and then use an expression. Try this

var shortDate = Model.Due.ToShortDateString();
@Html.TextBoxFor(x => shortDate )
0
votes

Instead of adding format in model Use @Value Annotations as below

@Html.TextBoxFor(x => x.Due new {@Value=Model.Due.ToShortDateString()})