0

I use Ajax call to create records in Create view and after creating a record I return id and title values to the success of Ajax method. I call another View called Completed in the success by sending the id and title values to it. However, I cannot use Url.Action in the success method because I cannot get response values in it. On the other hand, I do not want to use & or ? in the parameters when I use another way as mentioned below. So, how can I solve this problem?

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)])
{
    //some stuff
    var redirectUrl = new UrlHelper(Request.RequestContext).Action("Completed", "Issue", new { /* no params */ });
    return Json(new { success= true, url = redirectUrl, id= model.ID, title = model.Title, });
    }


public ActionResult Completed()
{
    return View(new { id = Request.Params[0].ToString(), title = Request.Params[1].ToString() });
}


View (Create):

$('form').submit(function (event) {
    event.preventDefault();
    $.ajax({
        type: "POST",
        url: '@Url.Action("Create", "Issue")',
        data: formdata,
        dataType: "json",
        success: function (response) {
            if (response.success) {

            //Method I : Cannot use response values at here
            window.location.href = '@Url.Action("Completed", "Issue", new { id = response.id, title = response.title })';

            //Method II : I do not want to use ? as it is not recommended for security
            window.location.href = response.url + "?id=" response.id.toString() + "&title=" + response.title;
            }
        }
    });
});


View (Completed):

<div>   
@(ViewContext.RouteData.Values["id"]) - @(ViewContext.RouteData.Values["title"]) has been created.
</div>
Jack
  • 1
  • 21
  • 118
  • 236
  • 1
    You must use method II, (and it just needs to be `response.id` -no `toString()` necessary). What security issues do you think you have - both methods you show generate exactly the same url? And in any case, If your wanting to redirect, you should be making a normal submit and redirect in the POST method - there is no point in using ajax - its just extra overhead. –  Jul 24 '15 at 09:11
  • Generate proper `redirectUrl` in the server side the simple use ` window.location.href=response.redirectUrl` – Satpal Jul 24 '15 at 09:16
  • @StephenMuecke Yes, but I do not want to show the parameters on the address bar and also does not seems to be good. In that case we say that Method II is the only option to solve this problem I think. On the other hand, I think I do not need to use Success method if the new record has been created successfully and I can redirect the Completed action after Create operation is executed instead of returning Json. (Actually I just need to use Ajax success or error methof it when I want to display a message on the popup window). What do you suggest? – Jack Jul 24 '15 at 09:24
  • @Satpal I generated, but I want to know if it is possible to send parameters without & or ? signs and not displaying them on the address bar. – Jack Jul 24 '15 at 09:25
  • 1
    Well both your methods would have shown the full address in the address bar :) But what's the problem with showing them anyway. And what do you think would happen if the user later refreshed the page? (it will would fail!) –  Jul 24 '15 at 09:31
  • 1
    And since both the ID and Title properties are values that will be displayed in the view your redirecting to I just can see what your concern is (although it seems unnecessary to send the Title since you have already saved the object and it can be accessed with its ID only. –  Jul 24 '15 at 09:33
  • So, what do you suggest? Shall I redirect to Completed action after creating a new record (if operation succeed) instead of passing to the success method of the Ajax call? – Jack Jul 24 '15 at 09:46
  • @Christof, Need a break for a while. But I still don't understand what your 'security' issue is with showing the ID of the object your displaying in the view is? –  Jul 24 '15 at 09:54
  • @StephenMuecke Sorry. The problem is mentioned on [here](http://stackoverflow.com/questions/14475913/url-routing-image-handler-a-potentially-dangerous-request-path-value). On the other hand, maybe we do not need to think of it. I just want to be sure if I do not use the Create popup window (for displaying a message when success or error status), shall I redirect to the Completed action from Create method in Controller after the new record is created? In that case there is no need to return to the success method of the Ajax call. Is that true? – Jack Jul 24 '15 at 09:57
  • @StephenMuecke Forget the last comment. As far as I see it is impossible to redirect to Completed action in the Controller (after the new record is created) as I used Ajax call (I think I have to call from the Success of Ajax). So, if method II is the only way, how should I use it to pass the parameters properly? – Jack Jul 24 '15 at 11:24
  • @Christof, My recommendation is don't use ajax (it gives you no benefit at all in this case, just negatives). Do a normal post , save the model and redirect to the `Completed(int ID)` method passing the new `ID`. Then in the `Completed()` method, get the object from the repository again and display your view - your url when you redirect will just be `../Issue/Completed/1` –  Jul 24 '15 at 11:43
  • Thanks a lot for your recommendations. I built the structure with Ajax due to using some different approaches i.e. modal window. So, I have to use Ajax for this method but I will keep in mind for the next different approaches. For this, I think I should to use url with parameters. Regards. – Jack Jul 24 '15 at 11:48
  • @Christof, Having a modal window should make no difference - if the modal contains form and a submit button, it will do a normal post –  Jul 24 '15 at 11:54
  • I know it, but I had some problems regarding to retain submitted values on the popup after there is an error on Action method and I had to use Ajax. Anyway, thanks a lot for your help. – Jack Jul 24 '15 at 12:26

2 Answers2

1

Depending on how your routes are configured you could do this:

window.location.href = response.url + "/id/" response.id.toString() + "/title/" + response.title;

The end result would be something like: http://www.example.com/id/19/title/theTitle

But I would be very careful as someone could easily mimic that call and access your action method.

Jamie Rees
  • 7,973
  • 2
  • 45
  • 83
  • Thanks for answer. I tried it, but I could not retrieve the parameters using ViewContext.RouteData.Values["parameterName"] in the view. On the other hand, I am looking for a solution that does not show the parameters on the address line. – Jack Jul 24 '15 at 09:37
  • You should then POST your parameters over to the controller. – Jamie Rees Jul 24 '15 at 09:45
  • Thanks, but it does not make any sense for hiding the parameters. Anyway, the method you posted can also be used for different approaches. Voted+ – Jack Jul 24 '15 at 09:51
0

Use any unique hardcode value in Url.Action for id and title and then replace it with response value . See below eg-:

$('form').submit(function (event) {
    event.preventDefault();
    $.ajax({
        type: "POST",
        url: '@Url.Action("Create", "Issue")',
        data: formdata,
        dataType: "json",
        success: function (response) {
            if (response.success) {

            window.location.href = @Url.Action("Completed", "Issue", new { id = "newid", title ="newtitle" }).replace('newid',response.id).replace('newtitle',response.title);


            }
        }
    });
});
  • As I mentioned in the question, response is not recognized in @Url.Action method. – Jack Jul 24 '15 at 09:35
  • Thanks, but as I mentioned in the question, response is not recognized in @Url.Action method. – Jack Jul 24 '15 at 09:36