Reputation: 4453
This is my UI which uses ajax to post data to the web api.
<form id="myForm" method="post">
Username <input name="Email" id="Email" type="text" /> <br />
Password <input name="Password" id="Password" type="text" /> <br />
Confirm Password <input name="ConfirmPassword" id="ConfirmPassword" type="text" /> <br />
<input id="btnRegister" type="submit" value="Register" />
</form>
<script>
$(function () {
$('#btnRegister').click(function () {
debugger
var sForm = $('#myForm').serialize();
$.ajax({
type: 'POST',
url: 'https://localhost:44358/api/Account/Register',
contentType: "application/json",
dataType: "json",
data: sForm,
success: function () {
alert('Success');
},
error: function (xhr, status, error) {
}
})
})
})
</script>
In my Web API, I have this action method.
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
Using Postman, I have tested it and it works. I can insert into database but I hit the above error if I send it from html.
My RegisterBindingModel:
public class RegisterBindingModel
{
[Required]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Added another normal controller in the same project to test. It passes the ModelState
but hang at the line in bold.
[HttpPost]
public ActionResult Register(RegisterBindingModel registerBindingModel)
{
if (!ModelState.IsValid)
{
return View();
}
using (var client = new HttpClient())
{
**HttpResponseMessage responsePost = GlobalVariables.WebApiClient.PostAsJsonAsync("Account/Register", registerBindingModel).Result;**
if (responsePost.IsSuccessStatusCode)
{
// Get the URI of the created resource.
Uri returnUrl = responsePost.Headers.Location;
if (returnUrl != null)
{
ViewBag.Message = "Added";
}
}
else
{
ViewBag.Message = "Internal server Error: " + responsePost.ReasonPhrase;
}
}
return View();
}
GlobaVariable:
public class GlobalVariables
{
public static HttpClient WebApiClient = new HttpClient();
static GlobalVariables()
{
WebApiClient.BaseAddress = new Uri("http://localhost:44358/api/");
WebApiClient.DefaultRequestHeaders.Clear();
WebApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}
Anyone can give some clue here?
Upvotes: 0
Views: 2727
Reputation: 8302
This was happening because of the default routing convention was not being followed initially but after your corrected your base url, then the API started working. According to the specs:
In ASP.NET Web API, a controller is a class that handles HTTP requests. The public methods of the controller are called action methods or simply actions. When the Web API framework receives a request, it routes the request to an action.
To determine which action to invoke, the framework uses a routing table. The Visual Studio project template for Web API creates a default route:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Hence when you need to call your API, your base url should have the /api
to it.
Upvotes: 1
Reputation: 3932
method not allowed is when you try and do a post, to a get etc.
add the tag [HttpPost]
on your endpoint.
// POST api/Account/Register
[AllowAnonymous]
[HttpPost]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
Upvotes: 1