I have the following controller:
[Route("api/[controller]")]
[Authorize]
public class AuthenticationController : Controller
{
private readonly IAuthenticationService _authenticationService;
public AuthenticationController(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
}
[AllowAnonymous]
[HttpPost]
public IActionResult Authenticate([FromBody] UserModel userParams)
{
var authenticate = _authenticationService.Authenticate(userParams.Username, userParams.Password);
return Ok("");
}
[HttpGet]
public IActionResult GetAll()
{
var users = "Greta";
return null;
}
}
I'm trying to make a post with postman, but I get this result:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /api/Authentication/Authenticate</pre>
</body>
</html>
Have anyone an idea why I get this error?
I'm using the React-template with Visual Studio. Can it have something to do with that?
When I try to access the GetAll endpoint, I get this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<base href="/" />
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<!--
Notice the use of in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>ICOM.Cbs</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script type="text/javascript" src="/static/js/bundle.js"></script>
</body>
</html>
EDIT: It seems to work now. I removed FromBody and then It worked. I also tried with FromForm, and It works. I don't know why.
I suspect you just need to explicitly specify the route for the action:
[AllowAnonymous]
[HttpPost(nameof(Authenticate))]
public IActionResult Authenticate([FromBody] UserModel userParams)
{
var authenticate = _authenticationService.Authenticate(userParams.Username, userParams.Password);
return Ok("");
}
Notice the route in the HttpPost attribute, which I just set to the name of the method.
If you just use .UseMvc() in your Startup.cs, then you aren't specifying default routes, so you need to specify the route for each action. If you want default routes to be automatically assigned, then you need to use this in your Startup.cs:
app.UseMvc(routes => {
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
But even if you do that, if you specify a Route at the controller level, the default routes go out the window, so you must specify the routes at each action in that controller.
More reading:
Routing in ASP.NET Core
Routing to controller actions in ASP.NET Core
When using [FromBody] only in your controller and you are testing with PostMan. Instead of using form-data use raw and choose prefered Content-Type: application/json
Related
I have test API (.NET5) with one method for HttpGet and one method for HttpPost. When I do call the API from simple .html page as on example below, my browser is redirected to API call address and only text is diplayed. What I do want to do instead is call API > get response form it > process the response in the same page that called API.
What would be the proper way to achieve this? I can think of using return Redirect() from API and provide a result message as url parameter that can be processed, but user would see ugly URL in address bar. Do I need to make API call with Javascript behind the curtains and process the response on client side? Or is there some ActionResult derived class that allows to pass data back to caller, considering caller is a plain .html page and not a razor page view etc.
To be specific. User uploads a file, something gets wrong and this is the result. How to change this to let's say a text inside a HTML element targeted by ID, which is present on the page that triggered API call?
API code
[ApiController]
[Route("[controller]")]
public class TestController : Controller
{
[HttpGet("SayHi")]
public ActionResult Greetings()
{
return Ok("Hi!");
}
[HttpPost("UserFileUpload")]
public ActionResult UploadFile(IFormFile uploadFile)
{
if (uploadFile == null || uploadFile.Length <= 0)
return BadRequest("File might be corrupted or no file was uploaded.");
return Ok();
}
}
.html page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>Hello</h1>
<form action="https://localhost:44398/Test/UserFileUpload" method="post" enctype="multipart/form-data">
Execute get API method
<br />
<br />
<input type="file" id="upFile" name="uploadFile" />
<input type="submit" value="Send form data to API" />
</form>
</body>
</html>
I'm implementing an app in xamarin-forms.
For the authentication I'm using a web app asp.net (.net framework) identity framework to publish in azure. I Don't need to implement web page for app using.
I have defined the whole email confirmation part, what I am trying to do is a simple page where the user must be redirected when clicking on the email confirmation link.
This page, for the moment, will only have a text with "YOU EMAIL HAS BEEN CONFIRMED" but in the future I'll implement with other tags.
I defined this page in Views/SuccessConfirm.cshtml:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
<div>
<h1>Page1</h1>
<p class="lead">YOU EMAIL HAS BEEN CONFIRMED</p>
</div>
</body>
</html>
In order to test how this page will be shown I implemented the follow method in Controllers/AccountController.cs :
[HttpGet]
[Route("check")]
public async Task<IHttpActionResult> check()
{
return Ok(Redirect("./Views/SuccessConfirm");
}
But when I call it (https://localhost:44335/api/Account/check)this method return me this error. I'm not really sure that the Redirect method is the useful for me.
Error shown:
I'm a beginner in ASP.NET and I don't know if you need others information, please let me know.
How I can solve this problem?
Thank you
You need to create the controller and action for serving your SuccessConfirm page.
Then you can use RedirectToAction method to redirect to your action by action name and controller name, like this:
public async Task<IHttpActionResult> check()
{
return RedirectToAction("SuccessConfirm","SuccessConfirmController");
}
I'm trying to create a dashboard/graphical interface for managing purposes. How can I create buttons that call certain functions from a controller? It's in ASP.NET CORE 3, using the MVC-pattern.
What I want to do in the application is executing c# code by calling a method from my Index.cshtml page and passing parameters.
I've tried multiple solutions, namely those that state that the view and controller are synced with the controller function looking for the "equally named" view but it just doesn't work.
Edit: Found the solution: I needed to specify both the controller and ActionResult.
<form action="Home/Change" method="post">
<input type="text" name="DoorID" placeholder="Guid.." />
<br />
<input type="submit" value="Post" />
</form>
I was apparently not smart enough to read the countless tutorials.
Thanks for the help!
If you want to send a piece of data after the button click to the server, you should create a form in your view and a post action in your controller. However, if you don't want to post any data and you want to simply do something after button click, creat a get action in your controller and navigate to that action path using button click event. Finally, you can return the same page at your action and do what you want before hand.
Use [httpGet("path")] attribute on top of any public function in your controller to Mark it as action. Then you can invoke it in HTML using something like this <a asp-action="path">sth</a>
since you only wants to trigger a function on a btn click and pass some data i recommend you to make an ajax call to the back-end using java script or jquery is the more effective way.
it will look like this
$('#btn').click(function () {
$.post( "your action url ", { name: "John", time: "2pm" } )
.done(function(data)
{
// in case your action return some data it will be in the "data" variable
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- you need to have jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<input type="button" id="btn" value="click me ">
</body>
</html>
I have WinForm with WebBrowser control where I open HTML5 + Angular JS (TypeScript) form. I want to call typescript function from my C# code but it is not working with InvokeScirpt() method.
webBrowser1.Document.InvokeScript("method", new object[] {"123", "453")});
I am able to call Javascript method using this way when i load HTML + Javascript page in webbrowser control.
Also, please note typescript function I am able to call from the HTML page I have (on button click)
Could you please suggest whether this is a right way to call typescript function from C# webbrowser control OR I need to try something else?
Thanks,
Typescript methods will compile to javascript methods when you build your application, so to call them, you can call compiled methods like any other javascript methods.
Example
In the example, I suppose you have a app.ts containing this class:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
And I suppose you have added app.js in index.html add this code:
<html>
<head>
<script src="app.js"></script>
</head>
<body>
...
</body>
</html>
Then in your windows forms application, you can use Greeter this way:
string javascript = "var greeter = new Greeter('World!'); alert(greeter .greet());";
webBrowser1.Document.InvokeScript("eval", new object[] { javascript });
I had a same problem. I wanted to load an Angular 2+ from in WebBrowser control and do form auto fill. So I did as Follow :
In the head section of index.html of Angular 2+ project I add a javascript function.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<base href="/" />
<title>Test</title>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<script type="text/javascript">
function callAngularFunction(params) {window.angularComponentReference.zone.run(function (){window.angularComponentReference.LoginLogout(params); }); }
</script>
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>
Then in a constructor of a component which I would like the belonging method, response
import { Component, OnInit, NgZone } from '#angular/core';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit{
constructor(private ngZone: NgZone){}
ngOnInit() {
window['angularComponentReference'] = { component: this, zone: this.ngZone, LoginLogout: (params) => this.AutoLogin(params) };
}
public AutoLogin(params: any){
//params could be a string with ',' separator
//then assign each parameter to proper variable in this component
//which bind to Html fields
}
}
In C#
winWebBrowser.Document.InvokeScript("callAngularFunction", new object[]
{"username,password"});
hope it helps.
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.
Index.cshtml
#{
ViewBag.Title = "Index";
Layout = "Null";
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<p>Welcome to the first application of MVC</p>
</div>
</body>
</html>
firstcintroller.cs
namespace mvcapp.Controllers
{
public class firstController : Controller
{
// GET: first
public ActionResult Index()
{
return View();
}
}
}
Make sure the controller name is “first” in yout RouteConfig.cs file in App_Start folder.
And, create a folder with name “first” file in Mvc\Views folder and place Index.cshtml inside first folder and execute the project.
For more information, find below URL:
ASP.NET MVC Page Won't Load and says "The resource cannot be found"