.Net MVC ajax call return different views based on different conditions

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 :

  1. 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()
  2. 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 string

    public 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.

  3. 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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s