Doesn't show view from controller even debugger goes inside View - c#

I am new in MVC .net. I am not able to call view from controller. I have debug the flow. It goes to view successfully but doesn't show view on screen.
Controller name: Downloads
Action name: MakePayment
Redirect view: Success //success is view of View/Downloads/Success.cshtml
Code: DownloadsController
[HttpPost]
public ActionResult MakePayment(Downloads CCM)
{
if (true)
{
return View("Success");
}
else
{
return View("Failure");
}
}
View
#{
ViewBag.Title = "Success";
}
<h2>Your transaction has been completed successfully.</h2>
Method that I use to call the ActionResult MakePayment. I had use Ajax here because I wanted to call javascript function before form get submit.
View: Index.cshtml
#using (Ajax.BeginForm("MakePayment", "Downloads", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, OnBegin = "payByCreditCard" }))
{
//submit button
}
According to the return View("Success");, it should call the view. In fact when I debug the flow, it goes to Success view but doesn't display the view on screen. It keeps old view on screen.
Degug route after success: _ViewStart-->Success.cshtml-->_Layout.cshtml.
Can anybody suggest me if I am missing something?

Since you are making an ajax call using Ajax.BeginForm helper method, you need to specify where the response (of the ajax call) to be replaced in the DOM. You can specify that using the UpdateTargetId property
#using (Ajax.BeginForm("MakePayment", "Downloads", new AjaxOptions { HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId="YourDivToShowResult"
OnBegin = "payByCreditCard" }))
{
<div id="YourDivToShowResult"></div>
<input type="submit" />
}
Since this is an ajax call, It will not do a redirect. Instead,it will update the content of the div (with Id YourDivToShowResult) in the same page with response coming back which is the markup returned by Success view.
Also since we are showing a partial page update, you might consider returning a partial view.
[HttpPost]
public ActionResult MakePayment(Downloads CCM)
{
if (everything is good)
{
return PartialView("Success");
}
else
{
return PartialView("Failure");
}
}
This will return the markup from either of those views without the layout.

If you want to go to other view you have to redirect the page like:
return RedirectToAction("Success", "Downloads");

Related

Ajax Postback - Render full view once again

I am using Ajax.BeginForm() and a UpdateTargetId. However when the user has successfully completed the form and I have done the processing I want to redirect them to a brand new page.
Calling RedirectToAction() and returning a view from there does not work as it targets the id.
I also need to pass parameters to the action. So is my only option to make a JavaScript call of:
return JavaScript("window.location = 'http://www.somewhere.com/blah/blah?aMyParam=123'");
Is there a more elegant way to do this?
Although the way you are doing is correct but more elegant way to do this is shown below :-
Controller -
[HttpPost]
public ActionResult MyAction(MyModel model)
{
if (model.SomeCondition)
{
// return to the client the url to redirect to
return Json(new { url = Url.Action("MyAction2") });
}
else
{
return PartialView("_MyPartialView");
}
}
View -
#using (Ajax.BeginForm("MyAction", "MyController", new AjaxOptions { OnSuccess = "onSuccess", UpdateTargetId = "foo" }))
{
...
}
Javascript -
var onSuccess = function(result) {
if (result.url) {
window.location.href = result.url;
}
}
As shown above you can return Json(having url) from controller action and then redirect from onSuccess javascript function.

Redirect within partial view in MVC

I have kind of a weird scenario. I'm creating a site using the ASP.NET MVC Framework that contains a profile page which has a user's picture, info, etc. I have a view called Profile which loads partial views using the Ajax action link into a div. Here is an example:
#Ajax.ActionLink("Basic Info", "Index", "BasicInfo",
new {id=Model.UserName},new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "content",
HttpMethod = "GET"
})
The Index action of BasicInfo just shows the user's basic information. I want to have an edit link in that partial view that when pressed loads another action method, Edit where I can edit the values (another partial view). I have a couple of questions:
1) I didn't make Profile a layout even though it would be similar to a master page in ASP.NET because it would need a controller. Is there a way to create a layout that has its own controller?
2) How do I do a redirect within a partial view without doing a postback i.e. updating the div holding the partial view that was previously called by Ajax to an edit view?
3) I hope this all makes sense. I would see a profile with the person's basic information and I can press edit within that view and the edit view of that basic information controller is loaded into the div without doing a postback. What would be the best way to accomplish this?
You will find this a it easier using the jQuery ajax methods rather than the Ajax.ActionLink() and Ajax.BeginForm() methods. In the main view
<button type="button" class="details" data-id="Model.UserName">View details</button>
<div id="content"></div>
var detailsUrl = '#Url.Action("Details", "User")';
var editUrl = '#Url.Action("Edit", "User")';
// Display the details view
$('.details').click(function() {
$.get(detailsUrl, { id: $(this.data('id') }, function(response) {
$('#content').html(response);
});
});
// Display the edit view
$('#content').on('click', '#edit', function() {
$.get(editUrl, { id: $(this.data('id') }, function(response) {
$('#content').html(response);
});
});
// Post the edit form and replace with the updated details view
$('#content').on('click', '#save', function() {
var id = $(this).data('id');
var data = $(this).closest('form').serialize();
$.post(editUrl, data, function(response) {
if (response) {
$.get(detailsUrl, { id: id }, function() {
$('#content').html(response);
});
} else {
// Oops
}
}).fail(function (result) {
// Oops
});
});
The above assumes a UserController with the following methods
public PartialViewResult Details(int ID) // or string?
{
// Get the user model based on the ID
return PartialView("_Details", model);
}
public PartialViewResult Edit(int ID) // or string?
{
// Get the user model based on the ID
return PartialView("_Edit", model);
}
public JsonResult Edit(UserModel model) // replace with the name of your model
{
// Save the model
return Json(true); // indicate success
}
where the partial views are
_Details.cshtml
#model UserModel
.... // display properties of the model
<button type="button" id="edit" data-id="Model.UserName">Edit</button>
_Edit.cshtml
#model UserModel
<form>
.... // controls for properties of the model
<button type="button" id="save" data-id="Model.UserName">Save</button>
</form>
I might be misunderstanding things.
I think you're trying to flip a display view of a part of a page for an edit view of that part of the page.
I'll keep things general, because there's not enough code to refer to directly.
You should register javascript event handlers against the various clicks that can take place (in a jquery closure in a separate file is my personal preference). Those handlers should request whichever actions (returning partial views) are required.
e.g. when someone clicks the edit link, the handler calls the /GetEditStuff action, gets the partial view, and on success, clears out the previous content of the parent div and replaces it with the partial view.

Prevent updating html with some conditions in MVC Ajax.BeginForm?

I have the following code in my View,
It's for searching in a site, a user can submit the following form multiple times.
#using (Ajax.BeginRouteForm("Search", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "SearchContents",
LoadingElementId = "SearchAjaxLoader",
OnSuccess = "SearchLoadContentsOnSuccess",
OnFailure = "SearchLoadContentsOnFailure",
OnBegin = "SearchLoadContentsOnBegin",
OnComplete = "SearchLoadContentsOnComplete",
}))
{
#Html.AntiForgeryToken()
<input type="text" name="Search" />
<input type="submit" value="Submit" />
}
I wanna reject old ajax results and show the latest ajax result only.
In a non mvc Ajax form, I was creating an array as ajax counter and compare the server responses with it to prevent update html.
I wanna know how I can prevent Ajax.BeginForm to update Html on some conditions.
As an example I will demonstrate with an OnSuccess call, you can do this for each event you wish to handle.
In your AjaxOptions remove this to prevent the replace;
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "SearchContents",
In you SearchLoadContentsOnSuccess JavaScript method, without seeing the method I am guesing it will be something like this:
function SearchLoadContentsOnSuccess()
{
// Do something
}
Change it to this:
function SearchLoadContentsOnSuccess(e)
{
// Do something
}
Now the e parameter will contain the data that is sent back from your ajax call.
In your updated method, I would simply check the response and act acordingly.
As an example if you response contains a value and results property:
function SearchLoadContentsOnSuccess(e)
{
// Do something
$(e.value == 1)
{
$('#SearchContents').html(e.results);
}
}
You would simply change the javascript in the above method to suite your needs.

Display Success message on the same page when submit

I'm using Html.Beginform in view page and get the parameters using FormCollection to the controller i want to return the Success message on the same ViewPage as a result.i'm using following code,
public string InsertDetails(FormCollection collection)
{
string result = "Record Inserted Successfully!";
return result;
}
It shows the success message on the new page.How can i resolve this? what i have to return to get the Success message on the same page?
Personally, I'd pop the result string into the ViewBag.
public ActionResult InsertDetails(FormCollection collection)
{
//DO LOGIC TO INSERT DETAILS
ViewBag.result = "Record Inserted Successfully!";
return View();
}
Then on the web page:
<p>#ViewBag.result</p>
I have following Options.
1. Use Ajax Begin Form with AjaxOptions like below
#using (Ajax.BeginForm("ActionName", "ControllerName", new { area = "AreaName" }, new
AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "alert('Success');" //This will execute once the Ajax call is finished.
}, null))
{
<input type="submit" name="nameSubmit" value="Submit" />
}
2. Use JQuery to Manually Setup the XHR Request
$.ajax({
url: "#Url.Action("ActionName", "ControllerName", new { area = "AreaName" });",
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({param : Value})
})
.done(function () { alert('Success');}) //This will execute when you request is completed.
.fail(function () { })
My Suggestions
There are following disadvantages while using the FormCollection
Point - 1
In case FormCollection is being used...It will be mandatory to Type Cast the Primitive Type Values un-necessarily because while getting the entry of specific Index of the System.Collections.Specialized.NameValueCollection, value being returned is of type String. This situation will not come in case of Strongly Typed View-Models.
Issue - 2
When you submit the form and goes to Post Action Method, and View-Model as Parameter exists in the Action method, you have the provision to send back the Posted Values to you View. Otherwise, write the code again to send back via TempData/ViewData/ViewBag
Point - 3
We have Data Annotations that can be implemented in View Model or Custom Validations.
ASP.Net MVC simplifies model validatons using Data Annotation. Data Annotations are attributes thyat are applied over properties. We can create custom validation Attribute by inheriting the built-in Validation Attribute class.
Point - 4
Example you have the following HTML
<input type="text" name="textBox1" value="harsha" customAttr1 = "MyValue" />
Question : How can we access the value of customAttr1 from the above eg from inside the controller
Answer : When a form get posted only the name and value of elements are posted back to the server. You can also use Hidden Fields to post the Attributes to Post Action method.
Alternatives : Use a bit of jQuery to get the custom attribute values, and post that along with the form values to action method
Another option is to rather put what you got in your custom attributes in hidden controls
That's the reason, I would always prefer to use View-Models
we can do it on Form inside view
#using (Ajax.BeginForm("Action", "Controller", new AjaxOptions { HttpMethod = "POST", OnSuccess = "Showmessage" }))
[HttpPost]
public ActionResult Test(TestViewModel model)
{
return Json(new {isok=true, message="Your Message" });
}
function Showmessage(data)
{
$('#Element').html('Successfully Submitted');
}

Validationsummary not showing errors generated in the controller

When I generate an error in the controller and return back the view, the validation summary doesn't show up. All works fine for errors generated from the view itself. How can we make the summary show up?
Here's the simplified controller method:
[HttpPost]
public ActionResult EditProfil(Prospect prospect)
{
ModelState.AddModelError(string.Empty, "You have an error");
if (!ModelState.IsValid)
return View("Edit", prospect);
return Json(prospect);
}
And the view looks like this:
#model Prospect
#{
ViewBag.Title = "Profil du prospect";
Layout = null;
}
//Some javascript and CSS unrelated to validations
#using (Html.BeginForm())
{
#Html.ValidationSummary(false)
//My form controls...
}
edit
the problem is a combination of
ModelState.AddModelError(string.Empty, "You have an error");
and
#Html.ValidationSummary(false)
an empty string is "" which is interperted as a property name, event thought it's an empty string. Either remove the boolean false from rendering the summary or pass null to the modelstate bag.
With MVC4, passing null to ModelState.AddModelError is invalid. This actually worked using:
ModelState.AddModelError(string.Empty, "Error");
and
#Html.ValidationSummary(false)
It turned out that I had two problems.
I was returning the wrong view.
I was using an Ajax call and not updating the div.
The following solved it for me:
<div id="results">
#{
using (Ajax.BeginForm("CreateLookupTable", "Lookup", new AjaxOptions { HttpMethod = "POST", OnSuccess = "FormSuccess()", UpdateTargetId ="results" }))
{
#Html.ValidationSummary(false)
// Form
}
</div>

Categories

Resources