ChatGPT解决这个技术问题 Extra ChatGPT

Default value in an asp.net mvc view model

I have this model:

public class SearchModel
{
    [DefaultValue(true)]
    public bool IsMale { get; set; }
    [DefaultValue(true)]
    public bool IsFemale { get; set; }
}

But based on my research and answers here, DefaultValueAttribute does not actually set a default value. But those answers were from 2008, Is there an attribute or a better way than using a private field to set these values to true when passed to the view?

Heres the view anyways:

@using (Html.BeginForm("Search", "Users", FormMethod.Get))
{
<div>
    @Html.LabelFor(m => Model.IsMale)
    @Html.CheckBoxFor(m => Model.IsMale)
    <input type="submit" value="search"/>
</div>
}

D
Dismissile

Set this in the constructor:

public class SearchModel
{
    public bool IsMale { get; set; }
    public bool IsFemale { get; set; }

    public SearchModel()
    { 
        IsMale = true;
        IsFemale = true;
    }
}

Then pass it to the view in your GET action:

[HttpGet]
public ActionResult Search()
{
    return new View(new SearchModel());
}

Will this also initialize the values to the value you set in the database as well? Or just in the object?
@Zapnologica This is written as a ViewModel, which exists independently of the data-backed model. In practice, you could create the ViewModel, and override these defaults with values pulled from a database entry (using the data-backed model), but as-is, this will always use these default values. Now, when this gets submitted by the browser as part of a posted form, what you do with that data (whether it gets saved to the DB or whatever) is up to you.
Could this work if I overload the constructor with two parameters and set default properties just in the controller?
@Celdor I used this but overloaded the constructor with an object as parameter, set this object in the controller, worked like a charm. The values of the ViewModel where set to the values of the object I gave the constructor. (I guess using 2 parameters isn't a big difference)
G
Guruprakash

Use specific value:

[Display(Name = "Date")]
public DateTime EntryDate {get; set;} = DateTime.Now;//by C# v6

It is weird that I can't use it in Asp.net core 3.1 with C# 8. It doesn't raise error, but not work either
C
CodeGrue

Create a base class for your ViewModels with the following constructor code which will apply the DefaultValueAttributeswhen any inheriting model is created.

public abstract class BaseViewModel
{
    protected BaseViewModel()
    {
        // apply any DefaultValueAttribute settings to their properties
        var propertyInfos = this.GetType().GetProperties();
        foreach (var propertyInfo in propertyInfos)
        {
            var attributes = propertyInfo.GetCustomAttributes(typeof(DefaultValueAttribute), true);
            if (attributes.Any())
            {
                var attribute = (DefaultValueAttribute) attributes[0];
                propertyInfo.SetValue(this, attribute.Value, null);
            }
        }
    }
}

And inherit from this in your ViewModels:

public class SearchModel : BaseViewModel
{
    [DefaultValue(true)]
    public bool IsMale { get; set; }
    [DefaultValue(true)]
    public bool IsFemale { get; set; }
}

Whilst this is a clever solution, I would suggest that with C#6, it is better (more performant) to use auto-property initializers like such: public bool IsMale { get; set; } = true
O
Oleksii Aza

In case you need to post the same model to server the solution with having default bool value in constructor would not be viable for you. Let's imagine that you have following model:

public class SearchModel
{
    public bool IsMale { get; set; }

    public SearchModel()
    { 
        IsMale = true;
    }
}

On view you would have something like this:

@Html.CheckBoxFor(n => n.IsMale)

The problem is when user uncheck this checkbox and post it to the server - you would end up with default value set up in constructor (which in this case is true).

So in this case I would end up with just specifying default value on view:

@Html.CheckBoxFor(n => n.IsMale, new { @checked = "checked" })

u
user14006190
<div class="form-group">
                    <label asp-for="Password"></label>
                    <input asp-for="Password"  value="Pass@123" readonly class="form-control" />
                    <span asp-validation-for="Password" class="text-danger"></span>
                </div>

use : value="Pass@123" for default value in input in .net core


佚名

What will you have? You'll probably end up with a default search and a search that you load from somewhere. Default search requires a default constructor, so make one like Dismissile has already suggested.

If you load the search criteria from elsewhere, then you should probably have some mapping logic.