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.开发者_如何学Go 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!
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);
}
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
}
}
Looks like that you can issue an ajax call on the client side, and based on the Json result, you can render different content from the client side.
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.
精彩评论