1
votes

I'm using MVC 4 and I am trying to send a post request and I am getting a successful return from my controller with the resulting view in HTML form, but I'm not sure what to do with it at that point.

JS

$("form").submit(function (e) {
    e.preventDefault();
    if ($(this).valid()) {
        $.ajax({
            url: submitUrl, type: "POST", traditional: true,
            data: { EventName: 'Name of event'},
            success: function(data){
                $("#content").html(data);
            }
        })
    }
});

my controller

[HttpPost]
public ActionResult CreateEvent(EventModel model)
{
    if(ModelState.IsValid)
    {
        return RedirectToAction("Index");
    }
    else
    {
        return View(model);
    }
}

So you can see that my controller either returns a View or a RedirectToAction. In the success callback of my ajax call I am doing the following: $("#content").html(data); But nothing seems to happen. Can someone help push me in the right direction of properly handling the return of the controller action.

Thank you so much!

1
You should return a JSON example: {"me": "its ok"} in your "success" should parse and display the message.John Paul Cárdenas
You can use the Window.location of javascript for redirect as you are doing in the server side. Return success flag to client and let him choose the pathDevesh
Hi John, sorry, but I didn't quite understand your statement. Should I return Json(View(model)) from my controller and leave my Javascript how it is? Thanks.mvcNewbie
HI Devesh, I thought about that, but I might need to do server validation on the model and return that "View(model)", so I'd want to see the modified model.mvcNewbie
First you must define what you want to return, you can give an example of what is returned?John Paul Cárdenas

1 Answers

4
votes

If I understand correctly, you have a Create Event form on your page and you want to send an AJAX request to create a new event. Then you want to replace a section in your page #content with the results of the CreateEvent action.

It looks like your AJAX is set up correctly so that CreateEvent returns a successful response. I think you're now confused about the response. You have several options but let's choose two.

JSON response

[HttpPost]
public ActionResult CreateEvent(EventModel model)
{
    if(ModelState.IsValid)
    {
        var event = service.CreateEvent(model); // however you create an event
        return Json(event);
    }
    else
    {
        // model is not valid so return to original form
        return View("Index", model);
    }
    ...

Now you need to generate html markup from the JSON and insert it into #content.

$.ajax({
    url: submitUrl, type: "POST", traditional: true,
    data: { EventName: 'Name of event'},
    success: function(data){
        var obj = JSON.Parse(data);
        var html; // build html with the obj containing server result
        $("#content").html(html);
    }
})

or HTML fragment

Instead of returning a full page with a Layout defined we'll return just a PartialView without Layout and all the head and script tags.

[HttpPost]
public ActionResult CreateEvent(EventModel model)
{
    if(ModelState.IsValid)
    {
        var event = service.CreateEvent(model); // however you create an event
        return PartialView("CreateEventResult", event);
    }
    else
    {
        // model is not valid so return to original form
        return View("Index", model);
    }
}

Now make a new partial view CreateEventResult.cshtml (Razor)

@model Namespace.EventModelResult
@ {
    Layout = null;
}
<div>
    <!-- this stuff inserted into #content -->
    @Model.Date
    ...
</div>

and the javascript is unchanged

$.ajax({
    url: submitUrl, type: "POST", traditional: true,
    data: { EventName: 'Name of event'},
    success: function(data){
        $("#content").html(data);
    }
})

Edit: If your Event creation fails for any reason after you have validated the input, you'll have to decide how you want to respond. One option is to add a response status to the object you return and just display that instead of the newly created Event.