How to use POST in ApiController - javascript

I have searched for at least an hour and a half now and I'm not any closer to learning how to use POST methods in my ApiController. I need an effective way of using post to create a login system that will search my database based on the username/password combination and create a JSON object that I can send back to my web page. Any resources on using post? I've tried to acomplish this with get but I can use any variables more than 'ID'
public IHttpActionResult GetLogin(string id)
{
//Query Database for Unique username.
if (id == "mager1794")
{
//Create Login class with username, and password details.
return Ok( new Models.Login() { id = 1, userName = "mager1794", passWord = "*******" });
}
return Ok(-1);
}
This is what I have for my Get method but I'm just not having any luck creating a POST version of this.

Maybe something like this:
[RoutePrefix("api/account")]
public class AccountController : ApiController
{
public class LoginInfo
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}
[Route("login")]
[HttpPost]
public IHttpActionResult AuthenticateUser(LoginInfo loginInfo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (!Membership.ValidateUser(loginInfo.Username, loginInfo.Password))
{
ModelState.AddModelError("", "Incorrect username or password");
return BadRequest(ModelState);
}
FormsAuthentication.SetAuthCookie(loginInfo.Username, true);
return Ok();
}
}
Client side:
<form action="#" id="login-form">
<label for="username">Username:</label>
<input type="text" name="username" id="username"/>
<label for="password">Password:</label>
<input type="password" name="password" id="password"/>
<div><input type="submit"/></div>
</form>
<script>
$(document).ready(function () {
$("#login-form").submit(function (e) {
e.preventDefault();
var username = $('#username').val();
var password = $('#password').val();
$.ajax({
type: 'POST',
url: '/api/account/Login/',
data: { Username: username, Password: password },
success: function () {
// refresh the page if username and password are correct
location.reload();
}
});
});
});
</script>

Related

How to send client data to MVC controller for Login page?And save to database?

Login.cshtml
<script type="text/javascript">
function data() {
var n = document.getElementById("username").value;
var m = document.getElementById("password").value;
?
</script>
<button type="submit"class="btn-login" onClick="Data()">
Giriş Yap </button>
Account Controller
DBEntities dB = new DBEntities();
[HttpPost] (username) (password)
public ActionResult Login(string KullaniciAdi,string Sifre)
{
// Session[KullaniciAdi] = dB.Profil.Where(x => x.KullaniciAdi == KullaniciAdi && x.Sifre == Sifre).FirstOrDefault();
var session = (from p in dB.Profil
where p.KullaniciAdi == KullaniciAdi
select p).FirstOrDefault();
return View();
}
My OOP homework is this website and i want to create a login with sending password and username to controller and compare submitted data and the data in the database .Please help :)
You can send client data by using ajax request,
this is your inputs
<input id="username" type="text" />
<input id="password" type="password" />
<input id="loginbutton" onclick="UserLogin()" type="submit" value="Submit" />
Submit button bind with UserLogin js function.
here is the js function. we are sending ajax post request here to our controller
<script type="text/javascript">
function UserLogin() {
var n = document.getElementById("username").value;
var p = document.getElementById("password").value;
var postObj = JSON.stringify({
"username": n,
"password": p
});
$.ajax({
url: "/Home/Login", // endpoint
type: "POST",
data: postObj,
contentType: "application/json; charset=utf-8",
success: function (result) {
// success
},
error: function (errorData) { onError(errorData); }
});
}
</script>
And your controller should be like, you can implement login logic inside of the method.
[HttpPost]
public ActionResult Login(string username, string password)
{
// use your code loged in
return Json(true, JsonRequestBehavior.AllowGet);
}
First You Create a Class :
public class LoginModel
{
[Required(ErrorMessage = "User Name can not be empty!")]
public string LOGINID { get; set; }
[Required(ErrorMessage = "Password can not be empty!")]
public string LOGINPW { get; set; }
}
Then Your Controller Action Method do this:
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel model)
{
//Here check the Login Id and Password
return View();
}
Now in view Write this. Now when you click the submit button a post call go to the Login Controller with given LOGINID and LOGINPW :
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<!-- login screen -->
<form action="#">
#Html.TextBoxFor(m => m.LOGINID, htmlAttributes: new { #class = "form-control", placeholder = "Login ID" })
#Html.ValidationMessageFor(model => model.LOGINID, "", new { #class = "text-danger", style = "float: left" })
#Html.PasswordFor(m => m.LOGINPW, htmlAttributes: new { #class = "form-control", placeholder = "Password" })
#Html.ValidationMessageFor(model => model.LOGINPW, "", new { #class = "text-danger", style = "float: left" })
<button type="submit" class="btn btn-primary" style="background: #2e6da4; color: #FFF;">Login</button>
</form>
}
#{
var actionURL = Url.Action("Action", "Controller",
FormMethod.Post, Request.Url.Scheme)
+ Request.Url.PathAndQuery;
}
#using (Html.BeginForm("Action", "Controller", FormMethod.Post,
new { #action = actionURL }))
{
<input type="text" name="username">
<input type="text" name="password">
<button type="submit"class="btn-login"></button>
}//Then use Request.Form[0] with the id to get the user name and password in the controller action.

Kendo UI DateTimePicker does not bind properly into the controller

I have a complex object that I need to pass to the controller when submitting a form. This complex object has an object and a list of objects. This is my Web API controller that receives the complex object via post with ajax:
[HttpPost]
public IHttpActionResult CreatePurchaseInvoice(NewPurchaseInvoice newPurchaseInvoice)
{
try
{
var purchaseInvoice = new PurchaseInvoice
{
Id = newPurchaseInvoice.PurchaseInvoice.Id,
DatePurchaseInvoice = newPurchaseInvoice.PurchaseInvoice.DatePurchaseInvoice
};
// Here i do other stuff with the list of objects
_context.SaveChanges();
}
catch(Exception ex)
{
return BadRequest();
}
return Ok();
}
This is my html form:
<form id="purchaseInvoiceForm">
<div class="row">
<div class="col-lg-6">
<label>Order:</label>
<select id="numberOrder" class="form-control" required name="numberOrder">
<option value="">Select an order number...</option>
</select>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>Date of Purchase Invoice:</label><br />
<input id="datePurchaseInvoice" style="width: 70%" />
</div>
</div>
</div>
//Here i have an html table and every row i push into an array of the complex object
</form>
And this is my jQuery code where i send the complex object via ajax:
$(document).ready(function(){
//this is the declaration of my complex object
var newPurchaseInvoice = {
PurchaseInvoice: {},
PurchaseInvoiceDetails: []
}
$("#purchaseInvoiceForm").submit(function (e) {
e.preventDefault();
newPurchaseInvoice.PurchaseInvoice= {
Id: $("#numberOrder").val(),
DatePurchaseInvoice : $("#datePurchaseInvoice").val()
}
$.ajax({
url: "/api/purchaseInvoices",
method: "post",
data: newPurchaseInvoice
});
});
});
The problem I have is that the date of the KendoDateTimePicker is not sending correctly to the controller.
I get this date and not the one I select with the kendoDateTimePicker. This is the DatePurchaseInvoice property of my PurchaseInvoice model in spanish:
This is my KendoDateTimePicker for jQuery:
$("#datePurchaseInvoice").kendoDateTimePicker({
value: new Date(),
dateInput: true
});
And this is my NewPurchaseInvoice model:
public class public class NewPurchaseInvoice
{
public PurchaseInvoice PurchaseInvoice{ get; set; }
public List<PurchaseInvoiceDetail> PurchaseInvoiceDetails{ get; set; }
}
This is my PurchaseInvoice model:
public class PurchaseInvoice
{
public int Id { get; set; }
public DateTime DatePurchaseInvoice { get; set; }
}
You need to be specifying the type of data you are supplying:
contentType: 'application/json'
And possibly dataType too depending on your response type. And according to this post, you may need to stringify your response. I don't think I've needed to do that but I don't often use AJAX operations for complicated data types.

Set Form authentication in WEB API

Actually i have two project. One for Mvc and another one is Web Api. I have written form as below in mvc project.
<form>
<div class="form-group">
<input type="email" class="form-control" id="email" placeholder="Username">
</div>
<div class="form-group">
<input type="password" class="form-control" id="pwd" placeholder="Password">
</div>
<div class="checkbox">
<input class="customCheckBox" onclick="setIsRemember()" type="checkbox" name="" value="false"><label for=""><span><span></span></span>Remember me</label>
</div>
<button id="buttonSubmit" class="btn btn-default">LOG IN</button>
</form>
Then i have written script for cross domain as below,
$("#buttonSubmit").click(function (e) {
var user =
{
UserName: $("#email").val(),
Password: $("#pwd").val(),
IsRemember: $(".customCheckBox").val()
}
$.ajax({
type: "POST",
url: "http://localhost:55016/api/ajaxapi/loginmethod",
data: user,
success: function (response) {
if (response.Success == false) {
alert("login fail");
}
if (response.Success == true) {
alert("login true");
}
}
});
});
I have written login credential checking in web Api. After login success i have set form authentication as below in web api source,
public class UserLogOn
{
public interface IFormsAuthentication
{
void SignIn(string userName, bool createPersistentCookie);
void SignOut();
}
public IFormsAuthentication FormsAuth
{
get;
private set;
}
public void FormsChange(IFormsAuthentication formsAuth)
{
this.FormsAuth = formsAuth ?? new FormsAuthenticationService();
}
public void LogOnUserCookieCreation(UserValuesForLogOn user)
{
this.FormsChange(null);
this.FormsAuth.SignIn(user.UserName, user.IsRemember);
if (user.IsRemember)
{
HttpCookie cookie = new HttpCookie("SignedIn");
cookie.Values.Add("UserName", user.UserName);
cookie.Values.Add("Password", user.Password);
FormsAuthentication.SetAuthCookie(user.UserName, true);
System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
}
}
public class FormsAuthenticationService : IFormsAuthentication
{
public void SignIn(string userName, bool createPersistentCookie)
{
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
}
public void SignOut()
{
FormsAuthentication.SignOut();
}
}
When this above code is working if set authentication in same project. But its not working when set authentication using webapi. Please share your suggestion.
Thanks......

Checkbox Constantly Returns False?

I'm submitting a form using AJAX as follows:
$('#userUpdateForm').submit(function (e) {
//var attachment = $('form#userUpdateForm').serialize();
var blue = document.getElementById('blueCheck').checked;
var personDetails = {
Enabled: $('#eCheck').val(),
Authorised: $('#authCheck').val(),
Green: $('#greenCheck').val(),
Blue: blue,
//Blue: $('input[name="blueCheckbox"]').is(':checked'),
Red: $('#redCheck').val(),
Id: $('#idCheck').val()
};
$.ajax({
type: "POST",
//url: '<%= Url.Action("submitForm", "Home") %>',
url: '#Url.Action("submitForm", "Home")',
data: JSON.stringify({ jsonForm: personDetails}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
'#Url.Action("Index", "Home")';
alert("Success");
},
error: function (result) {
alert("A problem occured when submitting the form.");
}
});
e.preventDefault();
});
'Blue' refers to a checkbox. The form then submits to the controller HomeController/submitForm as below:
public class updatePersonDetails
{
public string Enabled { get; set; }
public string Authorised { get; set; }
public string Green { get; set; }
public bool Blue { get; set; }
public string Red { get; set; }
public string Id { get; set; }
}
[HttpPost]
public ActionResult submitForm(updatePersonDetails personDetails)
{
System.Diagnostics.Debug.WriteLine(personDetails.Blue.ToString());
return View();
}
But 'Blue' persistently returns 'False' when the checkbox has been checked and should return true. As you can see below, I have tried a variety of things to get the value:
var attachment = $('form#userUpdateForm').serialize();
var blue = document.getElementById('blueCheck').checked;
Blue: $('input[name="blueCheckbox"]').is(':checked'),
What's even stranger is the jsonForm on the browser shows 'Blue:true' in the request payload. Is there something I'm missing from getting the proper value on the server side?
Edit: the HTML for the form
<form id="userUpdateForm" method="post">
<fieldset>
<legend>User Details</legend>
<input type="checkbox" name="authorisedCheckbox" value="Authorised" id="authCheck" />Authorised<br />
<input type="checkbox" name="enabledCheckbox" value="Enabled" id="eCheck" />Enabled<br />
</fieldset>
<fieldset>
<legend>Favourite Colours</legend>
<input type="checkbox" name="blueCheckbox" value="Blue" id="blueCheck" />Blue<br />
<input type="checkbox" name="greenCheckbox" value="Green" id="greenCheck" />Green<br />
<input type="checkbox" name="redCheckbox" value="Red" id="redCheck" />Red<br />
<input type="hidden" name="personId" id="idCheck" value='#ViewData["personId"]'>
</fieldset>
<input type="submit" value="Save Changes" name="Save Changes">
<button type="button">Cancel</button>
</form>
There's also a onload function to set the checkboxes to reflect the original data of the person, but I wouldn't have thought that would set the checkbox state as 'False' permanently.
var blueVal = '#ViewData["blue"]';
if (blueVal == "checked") {
document.getElementById("blueCheck").checked = true;
}
On the javascript side you send your data like this:
data: JSON.stringify({ jsonForm: personDetails}),
But your Action signature in the Controller is this:
[HttpPost]
public ActionResult submitForm(updatePersonDetails personDetails)
The default MVC Binder can't bind that together. In the POST your ViewModel is nested in an object with "jsonForm" property, MVC can't match that to the "personDetails" parameter.
You need to either:
Change the JSON property name to match the parameter name in your Action:
data: JSON.stringify({ personDetails: personDetails})
Or just delete the nested property. For simple POSTs there is no need for that. You can just POST your data like this:
data: JSON.stringify(personDetails)
I like this solution more because then it doesn't matter what the parameter name in your action is. The MVC will bind the data solely based on the property names in updatePersonDetails class.
Try to execute same code after removing below statement
e.preventDefault();
For more information about preventDefault please check below link
https://www.w3schools.com/jsref/event_preventdefault.asp
Hope this will help you!
Try this
var blue = $('#blueCheck').is(":checked") ? true : false;

Uploading file and posting text input values in one click?

I'm trying build an Asp.net web api for posting files. I found the following example in
https://code.msdn.microsoft.com/AngularJS-with-Web-API-22f62a6e
The Web API method is:
[RoutePrefix("api/photo")]
public class PhotoController : ApiController
{
private IPhotoManager photoManager;
public PhotoController()
: this(new LocalPhotoManager(HttpRuntime.AppDomainAppPath + #"\Album"))
{
}
public PhotoController(IPhotoManager photoManager)
{
this.photoManager = photoManager;
}
// GET: api/Photo
public async Task<IHttpActionResult> Get()
{
var results = await photoManager.Get();
return Ok(new { photos = results });
}
// POST: api/Photo
public async Task<IHttpActionResult> Post()
{
// Check if the request contains multipart/form-data.
if(!Request.Content.IsMimeMultipartContent("form-data"))
{
return BadRequest("Unsupported media type");
}
try
{
var photos = await photoManager.Add(Request);
return Ok(new { Message = "Photos uploaded ok", Photos = photos });
}
catch (Exception ex)
{
return BadRequest(ex.GetBaseException().Message);
}
}
And the file uploader html code: (I added a text input <input type="text" id="test" value="testit" /> for test.
<form name="newPhotosForm" role="form" enctype="multipart/form-data" ng-disabled="appStatus.busy || photoManagerStatus.uploading">
<div class="form-group" ng-hide="hasFiles">
<label for="newPhotos">select and upload new photos</label>
<input type="file" id="newPhotos" class="uploadFile" accept="image/*" eg-files="photos" has-files="hasFiles" multiple>
<input type="text" id="test" value="testit" /> <!--- Added a text input for test -->
</div>
<div class="form-group" ng-show="hasFiles && !photoManagerStatus.uploading">
<ul class="list-inline">
<li><strong>files:</strong></li>
<li ng-repeat="photo in photos"> {{photo.name}}</li>
</ul>
<input class="btn btn-primary" type="button" eg-upload="upload(photos)" value="upload">
<input class="btn btn-warning" type="reset" value="cancel" />
</div>
<div class="form-group" ng-show="photoManagerStatus.uploading">
<p class="help-block">uploading</p>
</div>
</form>
The JS upload function:
function upload(photos)
{
service.status.uploading = true;
appInfo.setInfo({ busy: true, message: "uploading photos" });
var formData = new FormData();
angular.forEach(photos, function (photo) {
formData.append(photo.name, photo);
});
return photoManagerClient.save(formData)
.$promise
.then(function (result) {
if (result && result.photos) {
result.photos.forEach(function (photo) {
if (!photoExists(photo.name)) {
service.photos.push(photo);
}
});
}
appInfo.setInfo({message: "photos uploaded successfully"});
return result.$promise;
},
function (result) {
appInfo.setInfo({message: "something went wrong: " + result.data.message});
return $q.reject(result);
})
['finally'](
function () {
appInfo.setInfo({ busy: false });
service.status.uploading = false;
});
}
However, it seems the value of the added input test cannot be passed to the Web API code?
You need to add custom DTO/POCO class, set the values and then pass it as parameter to your post method. Since file is not a simple type default MediaTypeFormatter of webAPI won't work so you need to build your custom MediaTypeFormatter.
Sample POCO class
Public Class Attachment
{
public string Input {get;set;}
public byte[] Content{get;set;}
}
Custom Media formatter as below
public class CustomFormatter : MediaTypeFormatter
{
/// <summary>
///
/// </summary>
public CustomFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
}
public override bool CanReadType(Type type)
{
return type == typeof(Attachment);
}
public override bool CanWriteType(Type type)
{
return false;
}
public async override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var provider = await content.ReadAsMultipartAsync();
var modelContent = provider.Contents
.FirstOrDefault(c => c.Headers.ContentType.MediaType == "application/json");
var attachment = await modelContent.ReadAsAsync<Attachment>();
var fileContents = provider.Contents
.Where(c => c.Headers.ContentType.MediaType == "image/jpeg").FirstOrDefault(); // or whatever is the type of file to upload
attachment.Content = await fileContents.ReadAsByteArrayAsync();
return attachment;
}
}
Register the custom media formatter:
private void ConfigureWebApi(HttpConfiguration config)
{
//other code here
config.Formatters.Add(new CustomFormatter());
}
Pass the POCO to your Web-API Controller
public async Task<IHttpActionResult> Post(Attachment attachment)
{
I haven't tested this in Visual Studio, but this is the approach you need to follow
More information here:
http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
And a sample here
http://blog.marcinbudny.com/2014/02/sending-binary-data-along-with-rest-api.html#.V5MDDzV7qYg

Categories