MVC 5, HttpGet works, HttpPost does not work, why? - asp.net-mvc

I am making some custom methods in an MVC 5/Web Api. I try to make a custom GET method as follows:
[AllowAnonymous]
[Route("TrainItemCheckIfWorks")]
[HttpGet]
public string TrainItemCheckIfWorks()
{
return "Hello";
}
Which works beautifully. I do the same thing with HttpPost, as follows:
[Route("CheckPost")]
[HttpPost]
[AllowAnonymous]
public double[] GetPostItem()
{
return new double[] {1, 2, 3};
}
The HttpPost fails but I do not get a specfic error. I just get Server Error in '/' Application.
The resource cannot be found.Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /TrainItemModels/CheckPost
THis is very frustrating and I have been spending all weekend trying to figure out why I am getting this error. Any help will greatly help

Related

Why is my routing prefix not working?

In my browser's address bar, I've got the following input:
http://localhost:55105/Tasks/UpdateStatus/8/1
However, it is not hitting my controller method when I debug.
[Route("Tasks/UpdateStatus/{id}/{status}")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UpdateStatus(int id, int status)
{
Task task = db.Tasks.Find(id);
if (ModelState.IsValid)
{
task.Status = status;
db.Entry(task).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(task);
}
Getting following error:
Server Error in '/' Application. The resource cannot be found.
Your action method expects the parameters to be passed as POST and the via the way you are doing in the browser url it is get request as parameters are part of url as query string. What you need is a form in your view and post the values via form.
Make sure that you are sending the data as post method for you request.
For just to understand you can try renaming the [HttpPost] to [HttpGet] and see it will work, but that's not the way for the above use case as you are updating data in database so you should be using POST not GET

MVC Request - Core .NET - Non HTML Response

I'm new to Core.NET and would greatly appreciate some enlightenment.
I've watched many PluralSight videos, and have Core .NET book 'Pro ASP.NET Core MVC'.
All very well cover Routing / Controller Initialization / Action Method Execution / Action Result / View Engine. I'm hung up on the Non HTML Response though. (Please see image below)
In Traditional ASP.NET if I wanted to call some class that did something and returned no value, I'd simply:
// Call Twilio class that sends a test message
TwilioRest Send_Test_SMS = new TwilioRest();
Send_Test_SMS.testSMS_Send();
My question is:
How do I call the above class's function from the controller.
When adding a controller or when modifying a controller for that - do I need to alter or add something to the Startup.cs file
The course materials I have do a great job at covering returning HTML views - such as:
//------book examples below-----
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
But I feel like an idiot trying to do something so simple and would appreciate some insight into this.
Thank you in advance.
So I'm not sure whether I got your point, but I guess you want to do sth like that:
//------book examples below-----
public IActionResult Index()
{
// Call Twilio class that sends a test message
TwilioRest Send_Test_SMS = new TwilioRest();
Send_Test_SMS.testSMS_Send();
return Ok(); // Similiar meaning as => return StatusCode(200);
}
It's up to your design / contract which status code you want to return here you can find a list of http codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
So to summarize you don't need to return 'HTML response', but obviously 'HTTP response' must be returned.
If I misunderstood you then apologize.

Action Name not showing Up In URL

I am trying to create a form in a view and am running into trouble with the routing; it seems to be totally ignoring the action name that I am providing. Here are my controller methods (Controller is called "MyController"):
[HttpGet]
public ActionResult CreateNewRequest()
{
if (ModelState.IsValid)
{
MyViewModelClass model = new MyViewModelClass();
return View("CreateNewRequest", model);
}
else
{
return DisplayModelStateError(ModelState.Values);
}
}
[HttpPost]
public ActionResult CreateNewRequest(MyViewModelClass model)
{
//code to process the view model
return RedirectToAction("Index");
}
In my view, I have tried several variations of the same thing to render a form, including:
#using (Html.BeginForm("CreateNewRequest","My",FormMethod.Post))
#using (Html.BeginForm("CreateNewRequest","My"))
#using (Html.BeginForm("CreateNewRequest","My",null,FormMethod.Post))
They all fail when the user clicks the submit button; I get an error that says:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /My
What is especially odd is that if i reverse them (which I know to be incorrect), I get an error message implying it looked for the action as opposed to totally ignoring it. For example, if I try
#using (Html.BeginForm("My","CreateNewRequest",FormMethod.Post))
I get the following error message:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /CreateNewRequest/My
Any ideas here?

ASP.Net Web API: Regarding web api action calling url or end point url

i am new in asp.net web api. just reading a article on web api from this url http://www.c-sharpcorner.com/article/remote-bind-kendo-grid-using-angular-js-and-Asp-Net-web-api/
now see this code
[RoutePrefix("api/EmployeeList")]
public class EmployeeDetailsController : ApiController
{
[HttpGet]
[Route("List")]
public HttpResponseMessage EmployeeList()
{
try
{
List<Employee> _emp = new List<Employee>();
_emp.Add(new Employee(1, "Bobb", "Ross"));
_emp.Add(new Employee(2, "Pradeep", "Raj"));
_emp.Add(new Employee(3, "Arun", "Kumar"));
return Request.CreateResponse(HttpStatusCode.OK, _emp, Configuration.Formatters.JsonFormatter);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.OK, ex.Message, Configuration.Formatters.JsonFormatter);
}
}
}
as per my understanding the requesting url should be /api/EmployeeList/List but if anyone look the above image then must notice different url api/Employee/GetEmployeeList is being used to call list action method. so i just like to know the reason why different url is getting issued to call List action function ?
also do not understand how this url api/Employee/GetEmployeeList can work in this situation because controller name is EmployeeDetailsController but RoutePrefix has been used to address it api/EmployeeList and action method name is EmployeeList() which has been change to List..........so some one tell me how this url api/Employee/GetEmployeeList can invoke list action of web api ?
please discuss in detail. thanks
Did you activate AttributeRouting? If not, standard routing is in place and your current attributes will be ignored.
You need to do this in the WebApi registration process, like this:
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Other Web API configuration not shown.
}
Then, you can remove any method call like this:
config.Routes.MapHttpRoute
to disable conventional routing.
BTW, the call api/Employee/GetEmployeeList is valid because Employee is the name of your controller, Get is the verb and EmployeeList is the name of the method.
Did you enable attribute routing? You do this by default in webapiconfig.cs by adding this line of code:
config.MapHttpAttributeRoutes();
#Monojit-Sarkar. The URL the user showed in postman did not also match the code. In the code, these are the users we expect to see:
_emp.Add(new Employee(1, "Bobb", "Ross"));
_emp.Add(new Employee(2, "Pradeep", "Raj"));
_emp.Add(new Employee(3, "Arun", "Kumar"));
But the results in postman are different as shown in the image the user posted. So something is disconnected from the article/image and the sample code.

Why does AuthenticationManager.SignOut() Fail when I Change the Response?

I just started fiddling around with OWIN/Katana and MVC.NET 5.0. The default Visual Studio 2013 ASP.NET Web Application/MVC Template has an AccountController with a LogOut() action:
public ActionResult LogOff() {
AuthenticationManager.SignOut();
return RedirectToAction("Index", "Home");
}
As expected, this works just fine. However, when I change the response status code, e.g. by:
Response.SetStatus(HttpStatusCode.SeeOther);
... The AuthenticationManager.SignOut() method no longer causes the user to become logged off. Why is that?
I tried different approaches for setting the http status code for the response, as well as changing http headers like Location, and always with the same result - the user is not logged off when the LogOff() action is executed, if I get into tempering with the response.
I tried not using RedirectToAction (which explicitly implements a 302 redirect - that's another story), and not returning an ActionResult, but that made no difference - not that I'd really expect it to.
Using Fiddler I can tell that the response as it appears to the browser looks fine, not holding any surprises.
I also tried looking through the source code of the OWIN middleware at work, but the architecture is still unfamiliar to me, and I found no answers that I could grasp in there. I need your help in sorting this out, so thank you in advance!
The reason AuthenticationManager.SignOut() fails is that Response.SetStatus(HttpStatusCode.SeeOther) internally ends the response:
public static void SetStatus(this HttpResponseBase response, int httpStatusCode)
{
response.StatusCode = httpStatusCode;
response.End();
}
(See System.Web.WebPages.ResponseExtensions)
After this, naturally the ResponseManager cannot manipulate the response to remove cookies etc.
This works fine for me with the following LogOut method, are you doing something slightly differently?
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
Response.StatusCode = 303;
AuthenticationManager.SignOut();
return RedirectToAction("Index", "Home");
}

Resources