Redirection in controller in MVC 3 with Razor - asp.net-mvc-3

I need a little help. I'm trying to make a little project in MVC 3 with Razor. A page with 2 buttons: Button 1 and Button 2. When I click on Button 1 I want to go at Page 1. The same with Button 2 ( to Page 2). It's not difficult, BUT I want the redirection to be made in Controller, not in View (cshtml). I know that I need to use ActionName and RedirectToAction, but I don't know how. Please help me!

What you'll need to do is check which button was pressed in the HttpPost part of the controllers action then redirect accordingly.
As a very basic example you could add two
<input type="submit" name="submit" value="<val>">
controls into your forms view each having the same name and a different value (instead of ) then add a string parameter called submit to the HttpPost action. Assuming the buttons have values "button1" and "button2" Then in your action's code you could use:
if(submit == "button1") {
RedirectToAction("Page1");
} else {
RedirectToAction("Page2");
}
to redirect based on which button was pressed

This is a simplified example, but I think you will get my meaning. You simply need to name your buttons and check the formcollection to see which exists in the collection thus indicating which what clicked. see code below:
#using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
<input type="submit" value="Go 1" name="go-1" />
<input type="submit" value="Go 2" name="go-2" />
}
and now the Action implementation.
[HttpPost]
public ActionResult Test(FormCollection collection)
{
if (collection.AllKeys.Contains("go-1")) return View("Page1");
if (collection.AllKeys.Contains("go-2")) return View("Page2");
return View("Index");
}
and thats it.

In your controller action for page 1, you can use RedirectToAction:
public ActionResult Process()
{
// do processing
// redirect to page 2
return this.RedirectToAction("Index", "Page2");
}
You can invoke the Process action from the Page 1 button using either a GET or POST request, depending on if the Process action is idempotent. E.g your page 1 view:
#Html.BeginForm("Process", "Page1", FormMethod.Post)
{
<input type="submit" name="button" value="Submit" />
}
Alternatively, you could use an ActionLink:
#Html.ActionLink("Redirect to Page 2", "Process", "Page1")

Related

MVC3: Button action on the same view

i wish to change the inner html of a view on button click but maintain the view. I know how to change the html content of a div in javascript, but how can I have the action of the button not return a different view?
My buton looks like
<input type="submit" value="submit" onchange="myfunc()"/>
where myfunc() is the function in Javascript changing the div content.
Assuming you want a link to render content using ajax (and hopefully using razor) you can do something like the following:
First, setup the action to render the content partially. this can be done a few ways, but I'll keep with the logic in the action (and make it callable directly or by ajax):
[HttpPost]
public ActionResult Save(SomeModel model)
{
/* build view */
return Request.IsAjaxRequest() ? PartialView(model) : Wiew(model);
}
Next, setup a container in your page where the content will be populated along with the form you're looking to submit. If you want the form to disappear on a save, wrap it in the container. Otherwise, keep the container separated. In the below example, the from will submit and on success it'll come back, otherwise the new content will appear in its place:
<div id="ajaxContentPlaceholder">
#using (Ajax.BeginForm("Save", new AjaxOptions { UpdateTargetId = "ajaxContentPlaceholder" })) {
<!-- form elements -->
<input type="submit" value="save" />
}
</div>

how to have two forms in one View, working separately and well, in ASP.NET MVC 3?

I have two action methods. One of them submits the inserted data of a "new product", and the other form must upload the photos of that product. Each one has it's own Model, View, and each one calls it's own Action from controllers, which are completely separate.
But I need to have the forms both in just one view.
I've done this by using #html.action() to render the "Upload" action's View in the "Insert New Product" action's View.
The problem is, both of the submit buttons call the same "Insert New Product" action :|
Take a look. Here's the first View:
#using (Html.BeginForm("Insert_New_Product", "Admin", FormMethod.Post))
{
// Inputs, Validation Messages and all those stuff ...
<input type="submit" name="Insert_New_Product" value="Add New Product" />
// Here, I render the "Upload" View :
#Html.Action("Upload", "UploadImage")
}
The "Upload" View looks like this :
#using (Html.BeginForm("Upload", "UploadImage", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
// Inputs and stuff ...
<input type="submit" value="Upload" name="Upload"/>
}
So how is this possible to have two (or more) forms, each one calling it's own ActionResult on submit?
I'd appreciate your help.
I think this #Html.Action("Upload", "UploadImage") is the problem. You're essentially rendering the second form inside of the first one. That's not going to work. Try changing it to this:
#using (Html.BeginForm("Insert_New_Product", "Admin", FormMethod.Post))
{
// Inputs, Validation Messages and all those stuff ...
<input type="submit" name="Insert_New_Product" value="Add New Product" />
}
// Here, I render the "Upload" View :
#Html.Action("Upload", "UploadImage")
Also, you should really be using Html.RenderAction instead of Html.Action as it writes directly to the response stream. See here for more information. Like so:
#{ Html.RenderAction("Upload", "UploadImage"); }

ASP MVC 3 is it possible to identify the <input> id in the controller [post] method?

I'm using a so as to edit an object, with an <input type="submit"> for validation
I've also another input, type="button" with an onclick event for the cancel button (with a redirect). However, this use a JS call, which I'd like to avoid.
I'd rather prefer to process the validation or cancel choice within the controller, so as to be NoScript compliant.
So is it possible to retrieve, within the controller post method, the id of the <input> that was clicked in the <form>?
Thanks
You can set the name of your
<input type="submit" name="submitButton" />
Then in your controller:
if(Request["submitButton"] != null) {
// ...
}
I'm not sure if I understand you, but if your cancel button does a redirect, it should end in a GET, and your submit button does a POST, that's how you should difference both request.
Check the [HttpPost] attribute in controller action methods.

multiple button click in asp.net MVC 3

I am having multiple dynamic buttons on my asp.net mvc 3 page. what is the best way to handle button click in asp.net mvc 3? there is no event handling in asp.net, so what is the best practice to hadle.?
You could handle the buttons clicks using javascript by subscribing to their click event. For example with jQuery you could give those buttons a class and then:
$(function() {
$('.someClass').click(function() {
// a button was clicked, this will point to the actual button
});
});
or if those are submit buttons of a form you could give them the same name and different values and then on the server test the value of the name parameter. It's value will equal to the button that was clicked.
Let's suppose for example that you have the following form with multiple submit buttons:
#using (Html.BeginForm())
{
... some input fields
<button type="submit" name="Button" value="delete">Delete data</button>
<button type="submit" name="Button" value="save">Save data</button>
}
Now inside the controller action you are posting to you could determine which button was clicked:
[HttpPost]
public ActionResult Index(MyViewModel model)
{
var button = Request["button"];
if (button == "save")
{
// the save button was clicked
}
else if (button == "delete")
{
// the delete button was clicked
}
...
}
If the buttons do not require the same form data, then you can create two forms with different action methods. This is the easiest solution.
If you need to use the same form data, then there are a number of methods, inclduing Darin and tvanfosson's approaches. There is also an approach based on attributes that will select the correct action method based on which button is clicked.
http://www.dotnetcurry.com/ShowArticle.aspx?ID=724
Depends on what the buttons are doing. If they are logically separate actions, then you could have each postback to a separate action on the server side. This often also works they are variants of the same action, Save vs. Cancel, for instance where Save posts back the form and Cancel redirects to you the previous url (say, going back to details from edit). If the buttons represent different data that would get posted back to the same action, you can give them different values. If the buttons are named, the values will get posted back along with the rest of the form, assuming they are included in the form. If posting back from AJAX, you might need to explicitly serialize the button value along with the form.
Example of Save/Cancel
#using (Html.BeginForm())
{
//...
<button type="submit" class="submit-button button">Save</button>
#Html.ActionLink( "Cancel", "details", new { ID = Model.ID }, new { #class = "cancel-button button" } )
}
Then use CSS, perhaps in conjunction with jQuery UI to style the buttons.
<script type="text/javascript">
$(function() {
$('.button').button();
...
});
</script>

Partial View - >> How to REFRESH the HTML content without having to redirect to the view

My site has a concept like Skype that allow users to go "Online" and "Offline". I created a partial view that allows the user to switch mode:
#if (Convert.ToBoolean(ViewData["IsLogged"].ToString()))
{
<div id="onlineStatus">
You are currently <strong>ONLINE</strong> >>
#Html.ActionLink("Go OFFLINE", "GoOffline", "Account")
</div>
}
else
{
<div id="offlineStatus">
Ready for business >>
#Html.ActionLink("Go ONLINE", "GoOnline", "Account")
</div>
}
This is how we load the Partial View:
public ActionResult OnlineStatusCtrl()
{
if (SiteUser.IsAuthenticated)
ViewData["IsLogged"] = SiteUser.IsOnline.ToString();
return PartialView("OnlineStatusCtrl");
}
When a user clicks on the link "Go ONLINE" or "Go OFFLINE", the Controller respond as:
public ActionResult GoOnline()
{
if (SiteUser.IsAuthenticated)
SiteUser.GoOnline();
ViewData["IsLogged"] = "True";
return RedirectToAction("Index", "Home");
//return PartialView("OnlineStatusCtrl");
//return EmptyResult();
}
public ActionResult GoOffline()
{
if (SiteUser.IsAuthenticated)
SiteUser.GoOffline(true);
ViewData["IsLogged"] = "False";
return RedirectToAction("Index", "Home");
}
This works well ...but the ONLY problem is that if I am on View XXXX, and I click on "Go Online", the controller redirects me to the Index View.
I tried "return EmptyResult()" or "return PartialView("OnlineStatusCtrl") but it does just not work.
From the code, you can see that the only thing the PartialView cares about is the "ViewData['IsLogged'] value"
QUESTION:
What is the way to REFRESH a partial view without having to refresh the entire page or redirect to the main page?
Is it maybe a matter of putting an Html.Beginform() ?
Is it maybe a matter of the Controller returning something that just refresh the content of the PartialView independently from what view is holding the PV itself?
Aiaiaiaia
I still can't figure out how MVC works with PartialViews/
UPDATE
I have updated the code as x suggested and the HTML output is as follow:
<div id="divStatus">
<form action="/" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#divStatus" id="form0" method="post">
<div id="offlineStatus">
Ready for business >>
Go Online
</div>
</form>
</div>
When I click on the LINK, the Controller return PartialView("_OnlineStatusCtrl"); which is hte name of the calling PV ...and the ENTIRE PAGE gets replaced.
You're going to have to use an ajax call of some sort (Microsoft ajax helpers built into MVC, or jquery/javascript ajax call.
To use Microsoft's Ajax, you can use Ajax.BeginForm or Ajax.ActionLink. Both take an AjaxOptions parameter that will allow you to set javascript functions for OnSuccess, and an UpdateTargetId to display the returned data (usually a partial view). Using this will call your action which should return a partial view. Your partial view then replaces the html element (usually a div) identified by the UpdateTargetId parameter. If you decide to go this route, make sure you reference all the proper Microsoft ajax/mvc scripts. You'll pretty much need each script with any combinations of Microsoft, Ajax, Mvc, and even unobtrusive in the name.
Here's an example of one of my ajax forms (modified slightly for simplicity)
<% using(Ajax.BeginForm("addAttribute", new { id = Model.PersonId, attributeId = item.AttributeId }, new AjaxOptions { UpdateTargetId = "myTargetId", OnSuccess = "initForm" })) { %>
<input type="submit" value="Ok" class="editMode okButton" disabled="disabled" />
<input type="button" class="editMode cancelButton" value="Cancel" />
<br />
<input type="button" value="Add" class="addButton" />
<% } %>
I have a div with an id of "myTargetId" (for this example) that will be updated with the returned partial view.

Resources