Warum erhalte ich null anstelle einer leeren Zeichenfolge, wenn ich eine POST-Anfrage von Razor View erhalte?

76

Ich habe eine leere Zeichenfolge erhalten, wenn es keinen Wert gab:

[HttpPost]
public ActionResult Add(string text)
{
    // text is "" when there's no value provided by user
}

Aber jetzt komme ich an einem Modell vorbei

[HttpPost]
public ActionResult Add(SomeModel Model)
{
    // model.Text is null when there's no value provided by user
}

Also muss ich den ?? ""Operator benutzen .

Warum passiert das?

Alex
quelle
Eine alternative Lösung zur Verwendung von Attributen für jede Modelleigenschaft, wie unten beschrieben, ist die Verwendung eines benutzerdefinierten Modellbinders, siehe stackoverflow.com/questions/12734083/…
Anders

Antworten:

161

Sie können das DisplayFormatAttribut für die Eigenschaft Ihrer Modellklasse verwenden:

[DisplayFormat(ConvertEmptyStringToNull = false)]
Michael Jubb
quelle
Dies half mir bei der impliziten Modellbindung, bevor meine Aktion ausgeführt wurde. Verwendet es zusammen mit MetadataTypeAttribute, um automatisch generierte Eigenschaften der Entity Framework Model-First-Klasse
EvAlex
1
Dies ist definitiv ein Muss.
Serge
Ich verwende: public ActionResult Quotations(string projectName, string brandName, string modelName, string clientName) { var model = _dataAccess.Quotations_Select(projectName, brandName, modelName, clientName); return View(model); } Aufrufen einer gespeicherten Prozedur und Bereitstellen von Werten, sodass das Attribut für mich nicht funktioniert. Was soll ich machen?
Talal Yousif
3
Es ist ein langer Weg, aber wenn Sie (wie ich) in MVC6 aus irgendeinem Grund dies nicht über ein Attribut festlegen und Ihre Metadaten an anderer Stelle speichern möchten, können Sie Ihren eigenen Metadatenanbieter schreiben und im Startup registrieren .cs wie : AddMvc(o => ModelMetadataDetailsProviders.Add(new YourProvider())). Dort in GetDisplayMetadatakönnen Sie alles tun, was Attribute tun. Für diese Frage wird es seincontext.DisplayMetadata.ConvertEmptyStringToNull = false;
evilkos
Dies stand im Widerspruch zu meiner anderen Validierung, die ich auf dem Grundstück hatte. Am Ende habe ich eine Eigenschaft mit einem Hintergrundfeld erstellt, in der get eine leere Zeichenfolge zurückgibt, wenn das Hintergrundfeld null ist.
Peheje
9

Die Standardmodellbindung erstellt ein neues SomeModel für Sie. Der Standardwert für den Zeichenfolgentyp ist null, da es sich um einen Referenztyp handelt. Daher wird er auf null gesetzt.

Ist dies ein Anwendungsfall für die Methode string.IsNullOrEmpty ()?

Hackerhasid
quelle
1
Ja das ist, was ich dachte. Ich habe nicht bemerkt, dass der Standardwert für den Zeichenfolgentyp null ist, nicht String.Empty. Nein, dies ist bei der IsNullOrEmpty-Methode nicht der Fall. Ich habe KEINE NULL-Spalten in meiner SQL-Tabelle, daher erhalte ich eine Ausnahme, wenn Nullzeichenfolgen vorhanden sind. Also muss ich wohl weiter das ?? "" Operator. Vielen Dank!
Alex
Sie können auch eine Eigenschaft mit einem Hintergrundspeicher verwenden und string.empty anstelle von null aus dem ViewModel zurückgeben, z. B.:
hackerhasid
1
woops! Hier ist ein Pseudocode: private Zeichenfolge _text; öffentlicher String Text {get {return _text; } set {_text = value ?? string.empty; }} - so etwas
Hackerhasid
2

Ich versuche dies in Erstellen und Bearbeiten (mein Objekt heißt 'Entität'): -

        if (ModelState.IsValid)
        {
            RemoveStringNull(entity);
            db.Entity.Add(entity);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(entity);
    }

Was das nennt: -

    private void RemoveStringNull(object entity)
    {
        Type type = entity.GetType();
        FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic);
        for (int j = 0; j < fieldInfos.Length; j++)
        {
            FieldInfo propertyInfo = fieldInfos[j];
            if (propertyInfo.FieldType.Name == "String" )
            {
                object obj = propertyInfo.GetValue(entity);
                if(obj==null)
                    propertyInfo.SetValue(entity, "");
            }
        }
    }

Dies ist hilfreich, wenn Sie Database First verwenden und Ihre Modellattribute jedes Mal gelöscht werden oder andere Lösungen fehlschlagen.

user2284063
quelle