MVC5 Getting a button to call an action method in Controller - asp.net-mvc-5

As the heading states when I click a button on my main view I need it to call a method in my controller for that view. Ive been trying for hours and Ive changed the specific lines of code many times but all variations seem to give the same errors so im just showing the simplest versions to get my point across. Everytime I try something I get a 404 error that the path is not found. So im assuming something is wrong with the code in my view. Im not using JQuery or any javascipt
The line of code in my index view:
#Html.ActionLink("Button4Pressed", "Button4Pressed", "HomeController");
I know this wont work for getting methods but it works for changing pages so I thought I would start there. Im not sure if I should be doing it as a href or button.
my method in my HomeController:
[HttpPost]
public ActionResult Button4Pressed()
{
state = "year";
MyChart();
return View();
}
heres my Solution Explorer
Im pretty new to MVC and propably doing some pretty stupid stuff so any help is appreciated thanks.

You have two options:
Option A
Remove the [HttpPost] attribute from your controller method and you will be able to create normal links to it, i.e. with #Html.ActionLink()
Option B
Keep the [HttpPost] attribute and use a form or ajax to send the request as a HTTP Post request, i.e.
<form id="Button4Pressed" action="#Url.Action("Button4Pressed", "Home")" method="post"></form>
Button4

Related

faces-redirect=true not working while creating and rendering view

I am currently working on a JSF 2.2 application. As per requirements, I have created custom view handler (using ViewHandlerWrapper) for my application. All the methods are just passing to default view handler except renderView which I am overriding as follows -
private viewHandler viewHandlerWrapped = null;
renderView(FacesContext facesContext, UIViewRoot viewToRender) {
String viewId = viewToRender.getViewId();
if (viewId == some condition) {
/* Do calculation to derive viewId */
}
UIViewRoot viewRoot = viewHandlerWrapped.createView(facesContext,viewId+"?faces-redirect=true");
facesContext.setViewRoot(viewRoot);
//now let system render the view
viewHandlerWrapped.renderView(facesContext,viewRoot);
}
The above is working fine and rendering & navigation is happening as expected. The only issue is faces-redirect=true is not working. The URL seems to be always one behind.
I have gone through many answers given in stackoverflow or internet. But nowhere I am able to find how to solve this.
I think I am doing something wrong e.g. ?faces-redirect=true might not be the correct way while creating view. But I am not sure what can be done to correct this.
Can someone please help me out with this?
After struggling with this for more than 4 weeks, I finally found a way to get the correct URL (instead of previous one). I am updating my answer here in case any one else falls into same problem -
"It looks like we can not use the faces-redirect=true the way I was using while creating and rendering the pages. It should be suffixed with form action. So I have changed my code as follows -
1) actions are returned on click of a button e.g.
public string doAction {
----
return "action?faces-redirect=true";
}
2) Code is updated to use implicit navigation wherever possible. With this, I didn't need to build my custom viewhandler as navigation is happening implicitly. So, I have scrapped the viewhandler.
With above two simple steps, the correct URL is being displayed on the browser now.

(Yii2) the page that you are looking for used information.....?

my simple view file
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
?>
<?php ActiveForm::begin()?>
<?=Html::submitButton('something')?>
<?php ActiveForm::end()?
Clicked the button. After I reload the page and browser shows me
this
So how can I remove this?
This problem happen when you submit data in a form and then refresh the page
Browsers should stop this, or at least prompt if you want to resend the data,
but the best way to prevent this from happening is submit the data .. and manage the submit properly.
In you case your submit repeat the index action because you don't manage proper the action code
(all you're being made does not produce the creation of a new model to be complete so as not prroduce displaying a result.
or any other action ..
your code continues to call the same action that produces post calling for action and so on)
try adding a simple die() or a render for another view
public function actionIndex()
{
if (Yii::$app->request->post('submit')==='my_value') {
echo "Button my_value Clicked";
die(); // or render a proper view
}
return $this->render('index');
}
This is basic browser behavior. Your form is doing a POST request and obviously when you try to refresh it will ask for this. Even if you write a basic html page without yii, you will still have this.

Angular formly with angular ui bootstrap typeahead dynamic options

I am trying to get angular formly and angular ui bootstrap typeahead playing nice. What I want is to have my select list populated from an http get request, and each time there is a change to the select field it should fire a function to get a new list of options.
typeahead="address for address in getLocation($viewValue)"
I'm not sure I did the jsbin right, but here we go.
JsBin of my problem
Here is a plunker with the typeahead working alone.
dynamic typeahead works here
I can't even get the getLocation function to fire. I have tried vm.getLocation, but no dice.
Help would be very appreciated!
Thanks. ;-)
Async select options
Watchers Example
Initially the options should be an empty array, and passed in with as shown above. Then you need to add a watcher that updates the $scope.options.templateOptions.options as its called.
But, I am still having trouble getting the typeahead to answer functions. In the typeahead docs you can use a callback to know when it is selected.
typeahead-on-select='onSelect($item, $model, $label)'
My onSelect function in the controller is never called.
Here is a working example...I combined the Async formly example with the UI Bootstrap example...notice it now becomes item.question for item instead of item for item...
Unsure why that is, I checked and its the same format the Async example is coming back as...tried all kinds of ways to get it to display the full JSON object but no luck...
if I set it to item for item, the whole JSON object shows in the model but the search returns [object Object], otherwise its only the single line which I have set to the label, which I guess is the same way it displays normally, so that's OK...
Anyway, it works
http://plnkr.co/IjuJ0HPGCKfZAOrK0u3z?p=preview
app.run(function(formlyConfig) {
formlyConfig.setType({
name: 'typeahead',
template: '<input type="text" ng-model="model[options.templateOptions.label]" uib-typeahead="item.question for item in to.options | filter:$viewValue | limitTo:15" class="form-control">',
wrapper: ['bootstrapLabel', 'bootstrapHasError'],
});
});

MVC Action Link Issue

I have come across what appears to be an inconsistency in MVC 5 regarding the Html.Actionlink. In different cshtml files I can use the same code, but the url target that is generated is different.
For example, this line of code:
<td>#Html.ActionLink(item.Description, "Edit", new { item.ParentTableID }) </td>
generates this URL
localhost\MyControllerClass\Edit?ParentTableID=35
That then properly calls the ActionView method Edit and feeds the parameter with 35 as expected.
However, in another cshtml file, this line
<td>#Html.ActionLink("Edit", "EditChild", new { id = f.ApplicationTableFieldID})</td>
produces this url
localhost/MyControllerClass/Edit/7
and when it hits the EditChild Action View, the parameter is null.
I have seen this now a couple of times and not yet been able to understand what makes the difference. But I need the first result.
Thanks.
Ensure that your ID parameters are named correctly in both your Action method and your ActionLink Html helper. The visual difference comes from MVC default routing and how it can take a parameter named ID and put it in the URL without the query string (? followed by stuff)
If your action method looks like this
public ActionResult EditChild(int ParentTableID){}
Then you will need to have your ID parameter named ParentTableID when you pass it back in your URL
<td>#Html.ActionLink("Edit", "EditChild", new { ParentTableID = f.ApplicationTableFieldID})</td>
Should now produce the following URL
localhost\MyControllerClass\EditChild?ParentTableID=3

Can MVC Custom Error pages retain Route Values?

The MVC project that I am currently working on uses Regions so that we can localise pages etc.
I have spotted a problem with our Error page. We have turned the custom error pages on in the web.config file. If we are on a page lets say : /IT/News/Index and we get an error, when it redirects it will go to /Error and there will be no routevalue attached to it.
Is there away to ensure that the langauge routevalue is retained by the Error page?
I have searched around and cannot find a solution at the moment and was wondering if anyone else could help or point me in the right direction?
Hope that this all makes sense. Any help is much appreciated.
If you're getting physically redirected to /Error then it's not because of the MVC HandleErrorAttribute. It's probably due to your Web.Config having system.web/customErrors defined for error handling. Using the HandleErrorAttribute causes it to inject a specific view instead of the view you would have normally returned but does not redirect you to a different action by default. The problem is when redirected because of customErrors, there is no inherant information available to tell you where they came from. But using HandleErrorAttribute DOES cause some info to be populated for you. Specifically it creates a HandleErrorInfo to use as a view model and passes that to the view you specify. For example, here's one that is reigstered in the /App_Start/FilterConfig.cs file.
public class FilterConfig
{
public static void RegisterFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute {View = "Error"});
}
}
When you redirect to an error View using the HandleErrorAttribute, certain information is populated for you. The HandleErrorInfo view model will contain the ControllerName of the original controller requested, and the ActionName of the original action. Also, the ViewData and the TempData from the original request will be copied into the ViewData and Temp data for the request to the Error view. With that information it should have what you need. Be aware that not all errors happen inside of an Action however, and exceptions that don't happen in an action will not be caught by the HandleErrorAttribute. So you'll still need to use something like customErrors (or system.webServer/httpErrors if you're doing it inside of IIS7+) to handle exceptions that occur elsewhere in your app.
Here's a link to the HandleErrorAttribute file on CodePlex in case you're wondering what it does. HandleErrorAttribute.cs
I'm not sure if this solution meets you requirements. You can override in your base controller OnException and then redirect to a specific page.
protected override void OnException(ExceptionContext filterContext)
{
string controller = filterContext.RouteData.Values["controller"].ToString();
string action = filterContext.RouteData.Values["action"].ToString();
//get other stuff from routing
//here you can do redirect or other stuff
//if handled exception
//filterContext.ExceptionHandled = true;
base.OnException(filterContext);
}
It depends how you're getting to the error pages, really. If you're using an ActionFilter-based method to catch exceptions, then you can get route values from the context that gets passed into the OnException method. If you're using a redirect from a catch block, then you can push the relevant information into TempData or pass it directly as a parameter, depending on how you're doing that redirect.
You can add a custom HandleErrorAttribute or use a base controller to be inherited by all your controllers. Either way, you need to get the RouteData object, like this
var routeData = filterContext.RouteData;
with that object, you can get all the route values accordingly to your needs. Check the object definition in MSDN site for more detail
Say you have the following route
routes.MapRoute(
"Language", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { language = "en", controller = "Sites", action = "Index", id = UrlParameter.Optional } // Parameter default
Then routeData.Values.Keys will tell you the name of the parameter and routeData.Values.Values the value itself
Then, wherever you handle the exception, you can store the route data in a TempData variable, like this
TempData["RouteData"]
And after that, it will be available on your error page
#model System.Web.Mvc.HandleErrorInfo
#{
ViewBag.Title = "Error";
}
<h2>
Sorry, an error occurred while processing your request.
</h2>
#TempData["RouteData"];

Resources