2016-08-03 6 views
0

In der POST-Endpunkt für meine Website Kontaktseite, die eine E-Mail an den Standort Besitzer basierend auf Benutzereingaben sendet, gebe ich eine ViewResult der gleichen Ansicht, aber mit einem neu initialisiert (leer) Modell ansehen.MVC Beitrag nicht die richtige ViewResult

Mein Ziel für den Client ist, beim Empfang der POST-Antwort dem Benutzer die gleiche Seite zu geben, aber mit allen leeren Formularfeldern. Statt dies zu tun, landet der Benutzer jedoch auf der gleichen Seite, wobei alle dieselben Formularinformationen noch ausgefüllt sind. Die E-Mail wird erfolgreich gesendet und es werden keine Fehler ausgelöst.

Irgendwelche Ideen?

Hier sind meine GET und POST-Endpunkte:

[HttpGet] 
public ViewResult contact() 
{ 
    return View(new ContactUsViewModel()); 
} 

[HttpPost] 
public async Task<ViewResult> contact(ContactUsViewModel inputModel) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      string body = 
       "<div style='font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: #444444;'>" + 
       "<p style='font-size: 17px;'>Email from <strong>{0}</strong> ({1})</p>" + 
       "<p>Date: {2}</p>" + 
       "<p>Phone: {3}</p>" + 
       "<p>Message:</p><p style='margin-left: 24px;'>{4}</p>" + 
       "</div>"; 
      string to = ConfigurationManager.AppSettings["ContactUsEmailAddress"]; 
      MailMessage message = new MailMessage(); 
      message.To.Add(new MailAddress(to)); 
      message.Subject = "Message from " + inputModel.Name; 
      message.Body = String.Format(body, new string[] 
       { 
        inputModel.Name, inputModel.Email, DateTime.Now.ToLongDateString(), inputModel.Phone, inputModel.UserMessage 
       } 
      ); 
      message.IsBodyHtml = true; 

      using (var smtp = new SmtpClient()) 
      { 
       await smtp.SendMailAsync(message); 
       // the "true" parameter in the constructor just sets a "Message sent" 
       // confirmation message in the view model that is displayed on the view 
       // via Razor. 
       return View(new ContactUsViewModel(true)); 
      } 
     } 
     else 
     { 
      return View(inputModel); 
     } 
    } 
    catch (Exception ex) 
    { 
     string ourEmailAddress = ConfigurationManager.AppSettings["ContactUsEmailAddress"]; 
     inputModel.PublicErrorMessage = "There was a problem sending your message. Please send an email directly to " + 
      "<a href='mailto:" + ourEmailAddress + "'>" + ourEmailAddress + "</a> so we can hear from you :)"; 
     inputModel.InternalErrorMessage = ex.Message; 
     return View(inputModel); 
    } 
} 

Falls dies relevant ist, hier ist mein ContactUsViewModel auch:

public class ContactUsViewModel : BaseViewModel 
{ 
    public ContactUsViewModel() { } 
    public ContactUsViewModel(bool messageSent) 
    { 
     this.MessageSentConfirmation = "Your message has been sent. We will get back to you shortly!"; 
    } 

    [Required(ErrorMessage = "Please include your name.")] 
    public string Name { get; set; } 

    [Required(ErrorMessage = "Please enter a valid email address.")] 
    [EmailAddress(ErrorMessage = "Please enter a valid email address.")] 
    public string Email { get; set; } 

    [Phone(ErrorMessage = "Please enter a valid phone number.")] 
    public string Phone { get; set; } 

    [Required(ErrorMessage = "Please enter a message.")] 
    public string UserMessage { get; set; } 

    public string MessageSentConfirmation { get; private set; } 
} 

EDIT: Ich weiß, dass die Post-Redirect-Get design pattern würde technisch Umgehung dieses Problems, aber es löst nicht wirklich die technische Einschränkung, dass es nicht möglich ist, dieselbe Ansicht mit einem leeren Ansichtsmodell zurückzugeben. Aus diesem Grund halte ich PRG nicht für die Lösung.

+0

Nun, Sie wissen, die richtige Art, dies zu tun, ist PRG-Muster. Der Grund dafür, dass Sie die gleichen Werte sehen, liegt darin, dass Ihre URL nicht geändert wurde und der Browser höchstwahrscheinlich die Daten selbst zwischenspeichert. –

+3

Sie sollten dem PRG-Muster folgen, weil Sie eine ** neue ** Ansicht (nicht die, die Sie eingereicht haben) zurückgeben möchten, aber Sie können 'ModelState.Clear()' immer verwenden - das Verhalten wird im 2. Teil von erklärt [diese Antwort] (http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) –

+0

@StephenMuecke danke für die Antwort. Bear mit mir, wie ich bin ein bisschen neu zu diesem Thema ... aber warum würde ich 'ModelState.Clear()' benötigen, wenn ich in meiner Return-Anweisung ein brandneues Modell initialisieren ('return View (new ContactUsViewModel (wahr)) ')? Außerdem versuche ich zu vermeiden, eine dedizierte URL zu haben, auf die Leute zugreifen können, die nur "Nachricht erhalten" sagt. Also habe ich eine neue Ansicht namens "message-received" gemacht, und meine Rückkehr könnte so aussehen: 'return View (" message-received) ". Ist das eine gute Idee? Es ist keine tatsächliche Umleitung, aber sie bleibt bestehen Die URL ist die gleiche. Ihre Rückmeldung und Hilfe wird sehr geschätzt. –

Antwort

1

Dies ist @StephenMueckes Lösung aus dem Kommentarbereich. Das Ausführen von ModelState.Clear() in meiner Controller-Methode, bevor meine return-Anweisung das Problem löst.

Verwandte Themen