As we know that, ajax is more efficient because it will only change the part that customer changed instead of the whole view. However, efficiency usually takes some effect. But don’t worry,this blog is to introduce a method to achieve this goal:
Using ajax to submit async request to controller/action, then controller/action will return different views data based on different conditions. At last, front end will replace different elements based on returned views data.
Here is one good way after some research and experiment :
- Construct async ajax request:
Put this part in your form onlick event.
var form = $(‘#yourForm’);
$.ajax({
type: “POST”,
url: ‘@Url.Action(“Action”,”Controller”)’,
async: true,
data: form.serialize(),
dataType: “json”,
success:function(response) {
…… will fill this part up later, because this part depends on the response
});Another way to construct this ajax request is using Razor Ajax.BeginForm().For details, you may refer this StackOverflow: how to use Ajax.BeginFormA gentle reminder: Use the first way if you want more flexible customization.
Another gentle reminder: Pay attention to the order of js reference and webconfig setting if you use the Ajax.BeginForm() - Controller/Action return different views base on different conditions
Assume the condition is ModelState.IsValid:[HttpPost]
public async Task<ActionResult> Edit(YourForm form)
{
string partialHtml;
if (ModelState.IsValid)
{
try
{
await //logic
partialHtml = RenderViewHelper.RenderRazorViewToString(
ControllerContext, “_YourView”, yourModel);
return Json(new
{
Status = ResponseStatus.Success,
Data = partialHtml,
Id = yourId
});
}
catch (Exception ex)
{
ModelState.AddModelError(“Exception”, “Hi Boss, System is sick. Need MC!”);
}
}
partialHtml=RenderViewHelper.RenderRazorViewToString(ControllerCon tex t,”_TaskCardEditForm”, form);
return Json(new
{
Status = ResponseStatus.Fail,
Data = partialHtml,
Id = yourId
});
}The purpose of Status is as a flag to tell front end when to use which Data. The Data is the rendered partial view. The Id is used by javascript to replace front end element.
For render view to string inside action(My previous blog mentioned that ViewResult would be rendered after OnActionExcecuted), you may refer to stackoverflow: render view to stringpublic static String RenderRazorViewToString(ControllerContext controllerContext, String viewName, Object model)
{
controllerContext.Controller.ViewData.Model = model;using (var sw = new StringWriter())
{
var viewResult =
ViewEngines.Engines.FindPartialView
(controllerContext, viewName);
var viewContext = new ViewContext(controllerContext, viewResult.View, controllerContext.Controller.ViewData, controllerContext.Controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Someone put this in basecontroller(any controller inherit it can refer to this method), but i suggest to wrap it in a ViewHelper or Service as it will be only used in certain cases such as ajax call. By wrapping it, you can inject it only when you need it, which is much cleaner. - Front end parse the returned Json and replace the targeted element with string view data.
I will only show the function being invoked once the ajax call is successful. It’s the one i missed in Step 1.
success:function(response) {
if (response.Staus == 0) {
SuccessLogic(response.Data, response.Id);
} else {
FailLogic(response.Data, response.Id);
}
}Happy end: It’s done:)Some other things you may be interested to know:
JsonResult is inherited from ActionResult.
Json is an extension method which return a JsonResult.Hope that this blog can help you on implementing async ajax request.
Sorry for the ugly layout of code, the wordpress does not have such feature to insert a piece of code.