简体   繁体   中英

A Contact page with ASP.NET MVC 3

I have a contact page and this page shall either show a form or a success message or a failure message, so basically something like this:

@model MyApp.Models.ContactData

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div>

...Some static content...


If page was opened the first time
    -> Render a form here
Else If form was posted and data successfully processed
    -> Render a success message here
Else If form was posted but error occurred during processing
    -> Render a failure message here

...Some static content...


</div>

I don't know what's the best way to achieve this with MVC 3. Do I create three completely separate views (which is something I'd like to avoid because of the static content which would be the same for all three views)? Or could I create three partial views and then decide based on an additional flag I could put into the model class which partial view to render? Or can I inject somehow the partial views dynamically from the controller into the view?

The controller I have so far looks like this:

public class ContactController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(ContactData contactData)
    {
        if (ModelState.IsValid)
        {
            ContactService service = new ContactService();
            bool result = service.Process(contactData);

            return ?; // What do I return now? It must somehow depend on result.
        }
        else
            return View(contactData));
    }

}

I had a similar page and behaviour with ASP.NET WebForms and the solution was there to put the three variable blocks of markup into asp:Panel controls and then switch on or off the Visible flag of those panels from code-behind. I guess I need quite another approach with ASP.NET MVC to reach the same goal.

What is the best way?

Thank you for suggestions in advance!

Perhaps use the ViewBag to help achieve all this. Of course it's a dynamic, so you can add & check for any prop you want/need/expect.

[HttpPost]
public ActionResult Index(ContactData contactData)
{
    if (ModelState.IsValid)
    {
        ContactService service = new ContactService();
        bool result = service.Process(contactData);
        ViewBag.ContactSuccess = true;
    }
    else
    {
        ViewBag.ModelStateErr= "some err";
    }

    return View(contactData));
}

Then in your View:

if (ViewBag.ContactSuccess !=null && ((bool)ViewBag.ContactSuccess))
{
        //thanks for posting!
}
else
{  
    if (ViewBag.ModelStateErr !=null)
    {
        //show that we have an err
    }
    else
    {
        //we have no err nor a 'true' contact success yet
        //write out the form
    }
}

You can try this way:

    [HttpPost]
    public ActionResult Index(Contact contactData)
    {
        if (ModelState.IsValid)
        {
            ContactService service = new ContactService();
            if (service.Process(contactData))
            {
                TempData["Success"] = "Your success message.";
                return RedirectToAction("Index");
            }
            else
            {
                TempData["Error"] = "Your fail message.";                   
            }
        }
        return View(contact);
    }

看起来您可以在客户端发出ajax调用,并且基于Json结果,您可以从客户端呈现不同的内容。

I'd suggest coding up three different Views

  • index.cshtml
  • contactSuccess.cshtml
  • contactFail.cshtml

Then in your Controller, you'll have similar code as before

public class ContactController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(ContactData contactData)
    {
        if (ModelState.IsValid)
        {
            ContactService service = new ContactService();
            bool result = service.Process(contactData);

            return View("contactSuccess.cshtml"); 
        }
        else
            return View("contactFail.cshtml", contactData);
    }

}

This way each view has an independent and you don't have a big inline IF block in the middle of your markup.

Alternatively (and this is how I'd do it) you can have the index.cshtml contain three partials...

  • _ContactForm.cshtml
  • _ContactSuccess.cshtml
  • _ContactFail.cshtml

and then you can load the partial views into the index view, and even swap them out dynamically using AJAX.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM