Cannot Find Definitions of Editor-Label and Editor-Field in MVC 4, Did Ms Remove It? Why

Cannot find definitions of editor-label and editor-field in MVC 4, did MS remove it? Why?

Well there are a couple of options you can take:

Wrap the elements in a class

Wrap all your inputs in a div and change your styles to target that div instead of .editor-label and .editor-field.

So HTML

<label class="editor-label">blah</label>
<input class="editor-field" />

Becomes

<div class="editor">
<label class="editor-label">blah</label>
<input class="editor-field" />
</div>

And your CSS

.editor-label { /**/ }
.editor-field { /**/ }

Becomes

.editor label { /**/ }
.editor input,
.editor select { /**/ }

Add them back with JavaScript

You may be able to get away with using some JavaScript to add the classes back in.

Demo on jsFiddle

var content = document.getElementById('content');
var labels = content.getElementsByTagName('label');

for (var i = 0; i < labels.length; i++) {
labels[i].classList.add('editor-label');
var id = labels[i].getAttribute('for');
var input = document.getElementById(id);
input.classList.add('editor-field');
}

Modify the editor templates

I wrote a blog post on how to modify display and editor templates a few months ago allowing custom HTML to be output from HtmlHelper.EditorFor() and HtmlHelper.DisplayFor(). This would allow you to put the classes back in where they were. This method may be more trouble than it's worth for your situation though.

Basically you can place a custom view in at the location Views/Shared/EditorTemplates/ named based on the type you want to override, for example string.cshtml for string. An example view for string could be:

string.cshtml

@model string

@{
var id = ViewData.TemplateInfo.GetFullHtmlFieldId(Model);
}

<label class="editor-label" for="@id"></label>
<input type="text" class="editor-field" id="@id" />

Pass in htmlAttributes

You can't pass in a class to the htmlAttributes argument on EditorFor(), but you can for LabelFor() and TextBoxFor(), etc. You could change all instances of EditorFor() to their respective types and provide the classes in the call.

@Html.LabelFor(e => e.UserName, new { @class="editor-field" })
@Html.TextBoxFor(m => m.UserName, new { @class="editor-field" })

Further reading

  • My blog post - ASP.NET MVC display and editor templates

Standard MVC4 project's Site.css does not contain definition for display-label, editor-label, editor-field

This may not be an answer that helps particularly, but it does seem that what you've seen is expected behaviour. I've just created projects in both VS2010 and VS2012 in MVC3 and MVC4 and it does seem that the styles of those classes have been removed from MVC4, probably because their initial styling was simply this :

.display-label, 
.editor-label {
margin: 1em 0 0 0;
}

.display-field,
.editor-field {
margin: 0.5em 0 0 0;
}

It doesn't hurt to have classes with no styles automatically added to those elements, but it does provide a default hook for you to apply your own styles, that's probably the reason they left them in.

Sadly, this isn't something mentioned in the release notes for ASP.NET MVC 4.

How to get rid of default label in EditorForModel

You need to write this in your editor template cshtml to get it work as expected:

@foreach (var property in ViewData.ModelMetadata.Properties)
{
<div class="editor-field">
<label>@property.GetDisplayName()</label>
@Html.Editor(property.PropertyName)
</div>
}

In MVC 4 using Razor not finding the class in the default css(site.css) provided by Microsoft for changing the style of textbox and dropdown

According to this Answer by Daniel Imms says

I need to wrap the elements in class as:

HTML as:

<div class="editor">
<label class="editor-label">Test</label>
<input class="editor-field" />
</div>

Instead of:

<label class="editor-label">Test</label>
<input class="editor-field" />

CSS as:

.editor label { /**/ }
.editor input,
.editor select { /**/ }

Instead of:

.editor-label { /**/ }
.editor-field { /**/ }

We may use some javascript to add the classes back in:

var content = document.getElementById('content');
var labels = content.getElementsByTagName('label');

for (var i = 0; i < labels.length; i++) {
labels[i].classList.add('editor-label');
var id = labels[i].getAttribute('for');
var input = document.getElementById(id);
input.classList.add('editor-field');
}

MVC ViewModel Error - No parameterless constructor defined for this object

If I had a nickel for every time I've seen this problem. It's typically related to the naming of your model properties and how you use them in a DropDownList. 99.999% of the time it's because people are using Html.DropDownList() and naming it the same as their SelectList. This is one reason you should use the strongly typed DropDownListFor.

In this case, your problem is that you have SelectLists named Genres and Artists, then in your view you have:

@Html.DropDownList("Genres", String.Empty)
@Html.DropDownList("Artists", String.Empty)

See, same name.

What you should do is change your Model to make the SelectLists be named GenreList and ArtistList. Then, change your view to use strongly typed model.

@Html.DropDownListFor(m => m.AlbumItem.GenreID, Model.GenreList)
@Html.DropDownListFor(m => m.AlbumItem.ArtistID, Model.ArtistList)

The reason this happens is that you are posting a value called Genres to the controller. The default model binder dutifully looks in the model to find something called Genres and instantiate it. But, rather than an ID or string, it finds a SelectList named Genres, and when it tries to instantiate it, it finds there is no default constructor.

Thus your error. SO is filled with questions asking about this same thing.

Razor View throwing The name 'model' does not exist in the current context

I think you have messed up the web.config file which lives in the Views folder.

Create a new project targeting the same .NET framework and copy its Views/web.config file on top of the one in your current project. This will fix your problem.

Also, as Dudeman3000 commented, if you have Areas in your MVC project they all have Views\web.config files too.

Creating EditorTemplate for string properties ASP.NET MVC4

You can use this:

@model string

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
new
{
@class = "form-control",
placeholder = ViewData.ModelMetadata.Watermark
?? ViewData.ModelMetadata.DisplayName
?? ViewData.ModelMetadata.PropertyName
})

Remove placeholder, if you don't want it.

Re: placeholder, this is a hint to the user of what can be entered in the input. You can decorate your model properties with annotations:

[Display(Name = "Client")]
public int ClientId { get; set; }

[Display(Prompt = "Please enter mailing Name")]
public string MailingName { get; set; }

If you use something like this, then your inputs will have placeholder attribute with values taken from these annotations, in the order specified in the editor template (Prompt (watermark), Name, then name of the property).

How to add required attribute to mvc razor viewmodel text input editor

You can use the required html attribute if you want:

@Html.TextBoxFor(m => m.ShortName, 
new { @class = "form-control", placeholder = "short name", required="required"})

or you can use the RequiredAttribute class in .Net. With jQuery the RequiredAttribute can Validate on the front end and server side. If you want to go the MVC route, I'd suggest reading Data annotations MVC3 Required attribute.

OR

You can get really advanced:

@{
// if you aren't using UnobtrusiveValidation, don't pass anything to this constructor
var attributes = new Dictionary<string, object>(
Html.GetUnobtrusiveValidationAttributes(ViewData.TemplateInfo.HtmlFieldPrefix));

attributes.Add("class", "form-control");
attributes.Add("placeholder", "short name");

if (ViewData.ModelMetadata.ContainerType
.GetProperty(ViewData.ModelMetadata.PropertyName)
.GetCustomAttributes(typeof(RequiredAttribute), true)
.Select(a => a as RequiredAttribute)
.Any(a => a != null))
{
attributes.Add("required", "required");
}

@Html.TextBoxFor(m => m.ShortName, attributes)

}

or if you need it for multiple editor templates:

public static class ViewPageExtensions
{
public static IDictionary<string, object> GetAttributes(this WebViewPage instance)
{
// if you aren't using UnobtrusiveValidation, don't pass anything to this constructor
var attributes = new Dictionary<string, object>(
instance.Html.GetUnobtrusiveValidationAttributes(
instance.ViewData.TemplateInfo.HtmlFieldPrefix));

if (ViewData.ModelMetadata.ContainerType
.GetProperty(ViewData.ModelMetadata.PropertyName)
.GetCustomAttributes(typeof(RequiredAttribute), true)
.Select(a => a as RequiredAttribute)
.Any(a => a != null))
{
attributes.Add("required", "required");
}
}
}

then in your templates:

@{
// if you aren't using UnobtrusiveValidation, don't pass anything to this constructor
var attributes = this.GetAttributes();

attributes.Add("class", "form-control");
attributes.Add("placeholder", "short name");

@Html.TextBoxFor(m => m.ShortName, attributes)

}

Update 1 (for Tomas who is unfamilar with ViewData).

What's the difference between ViewData and ViewBag?

Excerpt:

So basically it (ViewBag) replaces magic strings:

ViewData["Foo"]

with magic properties:

ViewBag.Foo

MVC5 Application: Create Identity User results in Invalid Model State?

As you can se in your last picture you have an error on the property SponsorOrgId that has the value string.Empty (""). Maybe the SponsorOrgId in ApplicationUser has the [Requried] attribute.

EDIT

Regarding your problem when trying to add the user to the Database (that was happen when you call UserManager.Create(user,password);

IdentityResult result = await UserManager.CreateAsync(user, user.PasswordHash);
if (result.Succeeded)
{
await db.SaveChangesAsync();
return RedirectToAction("Index", "UserManagement");
}
else
{
var errors = string.Join(",", result.Errors);
ModelState.AddModelError("", errors);
}

Then you can debug the value of "errors" or read the error message from your ModelState.

Regarding your EDIT

Add name to this part:

var user = new ApplicationUser() { UserName = applicationUser.UserName, Email = applicationUser.Email, PasswordHash = password, Name = applicationUser.Name };

EDIT 2
The problem is that is not possible to create a user without a username. But you can add the user's email to the username. And then change it to the user specified username. To make it pass the validation you need to add this part.

UserManager.UserValidator = new UserValidator<User>(UserManager) { RequireUniqueEmail = true };


Related Topics



Leave a reply



Submit