Standardwert in einem MVC-Ansichtsmodell von asp.net


69

Ich habe dieses Modell:

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

Aber basierend auf meinen Recherchen und Antworten hier wird DefaultValueAttributeeigentlich kein Standardwert festgelegt. Diese Antworten stammen jedoch aus dem Jahr 2008. Gibt es ein Attribut oder einen besseren Weg als die Verwendung eines privaten Felds, um diese Werte auf true zu setzen, wenn sie an die Ansicht übergeben werden?

Hier ist die Aussicht sowieso:

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

Antworten:


125

Stellen Sie dies im Konstruktor ein:

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

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

Übergeben Sie es dann an die Ansicht in Ihrer GET-Aktion:

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

Initialisiert dies auch die Werte auf den Wert, den Sie in der Datenbank festgelegt haben? Oder nur im Objekt?
Zapnologica

1
@Zapnologica Dies wird als ViewModel geschrieben, das unabhängig vom datengestützten Modell existiert. In der Praxis können Sie das ViewModel erstellen und diese Standardeinstellungen mit Werten überschreiben, die aus einem Datenbankeintrag (unter Verwendung des datengestützten Modells) abgerufen wurden. In diesem Zustand werden jedoch immer diese Standardwerte verwendet. Wenn dies nun vom Browser als Teil eines veröffentlichten Formulars übermittelt wird, liegt es an Ihnen, was Sie mit diesen Daten tun (ob sie in der Datenbank gespeichert werden oder was auch immer).
Aejay

Könnte dies funktionieren, wenn ich den Konstruktor mit zwei Parametern überlade und Standardeigenschaften nur in der Steuerung festlege?
Celdor

@Celdor Ich habe dies verwendet, aber den Konstruktor mit einem Objekt als Parameter überladen, dieses Objekt in der Steuerung festgelegt und wie ein Zauber funktioniert. Die Werte des ViewModel wurden auf die Werte des Objekts gesetzt, das ich dem Konstruktor gegeben habe. (Ich denke, die Verwendung von 2 Parametern ist kein großer Unterschied)
dmg_

21

Verwenden Sie einen bestimmten Wert:

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

17

Erstellen Sie eine Basisklasse für Ihre ViewModelsmit dem folgenden Konstruktorcode, der angewendet wird, DefaultValueAttributeswenn ein ererbendes Modell erstellt wird.

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);
            }
        }
    }
}

Und erben Sie davon in Ihren ViewModels:

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

3
Obwohl dies eine clevere Lösung ist, würde ich vorschlagen, dass es mit C # 6 besser (leistungsfähiger) ist, Auto-Property-Initialisierer wie die folgenden zu verwenden:public bool IsMale { get; set; } = true
Chris Haines

2

Falls Sie dasselbe Modell auf dem Server veröffentlichen müssen, ist die Lösung mit dem Standardwert boolim Konstruktor für Sie nicht realisierbar. Stellen Sie sich vor, Sie haben folgendes Modell:

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

    public SearchModel()
    { 
        IsMale = true;
    }
}

Zu sehen wäre so etwas:

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

Das Problem besteht darin, dass der Benutzer dieses Kontrollkästchen deaktiviert und auf dem Server veröffentlicht. Am Ende wird der Standardwert im Konstruktor eingerichtet (was in diesem Fall der Fall ist).

In diesem Fall würde ich also nur den angezeigten Standardwert angeben:

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

1
<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>

Verwenden Sie: value = "Pass @ 123" als Standardwert für die Eingabe im .net-Kern


-2

Was wirst du haben? Sie werden wahrscheinlich eine Standardsuche und eine Suche erhalten, die Sie von irgendwoher laden. Für die Standardsuche ist ein Standardkonstruktor erforderlich. Machen Sie also einen, wie Dismissile bereits vorgeschlagen hat.

Wenn Sie die Suchkriterien von einer anderen Stelle laden, sollten Sie wahrscheinlich über eine Zuordnungslogik verfügen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.