httpput request is not working in webapi - asp.net-web-api

Things tried:
commented lines regarding webdav
edited iis config file i.e added PUT,DELETE verbs
jQuery .support.cors = true;
Error: 405: method not allowed (in chrome debugger)
response is going to ajax error.
ajax call code:
jQuery.support.cors = true;
function CheckLogin() {
var user = { "UserName": $('#UserName').val(), "Password": $('#Passsword').val() };
user = JSON.stringify(user);
$.ajax({
url: 'http://localhost/MvcRazorClient/api/HomeApi/SignIn',
//here i changed the webapi route to api/controller/action
type: "PUT",
data: user,
async: false,
crossDomain: true,
contentType: "application/json",
dataType: 'json',
success: function (data) {
if (data == true) {
alert('true')
} else {
alert('false');
}
},
error: function () {
alert('er');
}
});
}
my api controller code:
[HttpPut]
public bool SignIn(User u)
//here i tried parameters as "dynamic u" and "HttpRequestMessage u". nothing worked
{
return true;
}
help please.

i didnt disable webDAV in iis .
path: Control Panel\All Control Panel Items\Programs and Features->iis->world wide web services->Common Http Features->(uncheck) webDAV

Related

MVC Ajax Post error

I am getting error while I post Ajax request to controller method. In controller method I need to pass Model class object.
But it gives me 500 Internal server error.
Can anybody help me to make it correct?
Mu code is as per below:
jQuery:
var request = $("#frmHost").serialize();
$.ajax({
url: "/Host/HostItemDetails/" ,
type: "POST",
datatype: 'json',
contentType : "application/json",
data: request,
success: function (data) {
if (data == '1111') {
///Success code here
}
else if (data != '') {
jAlert(data);
}
}
});
Controller Method :
[HttpPost]
public JsonResult HostItemDetails(ClsHost objHost)
{
//Code here
return Json("1111");
}
Nirav Try this,
Parse the serialized data as a JSON object and later stringify that while posting using JSON.stringify().
$("#Button").click(function () {
var data = $("#frmHost").serialize().split("&");
var request = {};
for (var key in data) {
request[data[key].split("=")[0]] = data[key].split("=")[1];
}
$.ajax({
url: "/Home/HostItemDetails/",
type: "POST",
datatype: 'json',
contentType: "application/json",
data: JSON.stringify(request),
success: function (data) {
if (data == '1111') {
///Success code here
}
else if (data != '') {
jAlert(data);
}
}
});
});
I ran the same code that you are running.
To test the code I did the following changes. I took a button, and on click event I am sending the post back to the controller.
the '[HttpPost]' attribute is fine too.
Can you make one thing sure, that the frmHost data matches to the class ClsHost,but still that shouldn't cause the server error, the error will be different.
$(document).ready(function () {
$("#clickMe").click(function () {
var request = '{"Users":[{"Name":"user999","Value":"test"},{"Name":"test2","Value":"test"}]}';
$.ajax({
url: "/Home/HostItemDetails/",
type: "POST",
datatype: 'json',
contentType: "application/json",
data: request,
success: function (data) {
if (data == '1111') {
///Success code here
}
else if (data != '') {
jAlert(data);
}
}
});
});
});
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult HostItemDetails(ClsHost objHost)
{
//Code here
return Json("111", JsonRequestBehavior.AllowGet);
}
It is solved by removing same property name in Model class. It is mistakenly added by me twice.

Accessing ServiceStack Authenticated Service using Ajax

I've been working through a simple API example, a modified version of the ServiceStack Hello World example with authentication. The goal of the proof of concept is to create an a RESTful API that contains services requiring authentication accessible entirely through Ajax from several different web projects.
I've read the wiki for, and implemented, Authentication and authorization and implementing CORS (many, results [sorry, not enough cred to point to the relevant link]). At this point, my Hello service can authenticate using a custom authentication mechanism which is over-riding CredentialsAuthProvider and a custom user session object. I've created, or borrowed, rather, a simple test application (an entirely separate project to simulate our needs) and can authenticate and then call into the Hello service, passing a name, and receive a 'Hello Fred' response through a single browser session. That is, I can call the /auth/credentials path in the url, passing the username and id, and receive a proper response. I can then update the url to /hello/fred and receive a valid response.
My breakdown in understanding is how to implement the authentication for all ajax calls. My initial login, below, works fine. No matter what I do, my attempt to call the authenticated service via ajax, I either receive a OPTIONS 404 error or Not Found error, or Origin http // localhost:12345 (pseudo-link) is not allowed by Access-Control-Allow-Origin, etc.
Do I need to go this route?
Sorry if this is confusing. I can provide greater details if required, but think this might be sufficient help the knowledgeable to help my lack of understanding.
function InvokeLogin() {
var Basic = new Object();
Basic.UserName = "MyUser";
Basic.password = "MyPass";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(Basic),
url: "http://localhost:58795/auth/credentials",
success: function (data, textStatus, jqXHR) {
alert('Authenticated! Now you can run Hello Service.');
},
error: function(xhr, textStatus, errorThrown) {
var data = $.parseJSON(xhr.responseText);
if (data === null)
alert(textStatus + " HttpCode:" + xhr.status);
else
alert("ERROR: " + data.ResponseStatus.Message + (data.ResponseStatus.StackTrace ? " \r\n Stack:" + data.ResponseStatus.StackTrace : ""));
}
});
}
EDIT:
Based on the responses and the link provided by Stefan, I've made a couple of changes:
My Config (Note: I'm using custom authentication and session object and that is all working correctly.)
public override void Configure(Funq.Container container)
{
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CustomCredentialsAuthProvider(),
}));
base.SetConfig(new EndpointHostConfig
{
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type, Authorization" },
},
DefaultContentType = "application/json"
});
Plugins.Add(new CorsFeature());
this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
//Handles Request and closes Responses after emitting global HTTP Headers
if (httpReq.HttpMethod == "OPTIONS")
httpRes.EndRequest(); // extension method
});
Routes
.Add<Hello>("/Hello", "GET, OPTIONS");
container.Register<ICacheClient>(new MemoryCacheClient());
var userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(userRep);
}
My Simple Hello Service
[EnableCors]
public class HelloService : IService
{
[Authenticate]
public object GET(Hello request)
{
Looks strange when the name is null so we replace with a generic name.
var name = request.Name ?? "John Doe";
return new HelloResponse { Result = "Hello, " + name };
}
}
After making the login call, above, my subsequent call the Hello service is now yielding a 401 error, which is progress, though not where I need to be. (The Jquery.support.cors= true is set in my script file.)
function helloService() {
$.ajax({
type: "GET",
contentType: "application/json",
dataType: "json",
url: "http://localhost:58795/hello",
success: function (data, textStatus, jqXHR) {
alert(data.Result);
},
error: function (xhr, textStatus, errorThrown) {
var data = $.parseJSON(xhr.responseText);
if (data === null)
alert(textStatus + " HttpCode:" + xhr.status);
else
alert("ERROR: " + data.ResponseStatus.Message +
(data.ResponseStatus.StackTrace ? " \r\n Stack:" + data.ResponseStatus.StackTrace : ""));
}
});
}
Again, this works in the RESTConsole if I first make the call to /auth/credentials properly and then follow that up with a call to /hello.
FINAL EDIT
Following Stefan's advise, below, including many other links, I was finally able to get this working. In addition to Stefan's code, I had to make one additional modification:
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
On to the next challenge: Updating Jonas Eriksson's CustomAuthenticateAttibute code (which appears to be using an older version of ServiceStack as a couple of functions are no longer available.
THANKS AGAIN STEFAN!!
this code works for me, based on the Wiki documentation Custom authentication and authorization
Code is based also in the blog post from Community Resources
CORS BasicAuth on ServiceStack with custom authentication
For Basic Authentication, a custom provider
public class myAuthProvider : BasicAuthProvider
{
public myAuthProvider() : base() { }
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
//Add here your custom auth logic (database calls etc)
//Return true if credentials are valid, otherwise false
if (userName == "admin" && password == "test")
return true;
else
return false;
}
public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
{
//Fill the IAuthSession with data which you want to retrieve in the app
// the base AuthUserSession properties e.g
session.FirstName = "It's me";
//...
// derived CustomUserSession properties e.g
if(session is CustomUserSession)
((CustomUserSession) session).MyData = "It's me";
//...
//Important: You need to save the session!
authService.SaveSession(session, SessionExpiry);
}
}
public class CustomUserSession : AuthUserSession
{
public string MyData { get; set; }
}
In AppHost
using System.Web;
using ServiceStack; // v.3.9.60 httpExtensions methods, before in ServiceStack.WebHost.Endpoints.Extensions;
using ....
AppHost.Configure
public override void Configure(Container container)
{
SetConfig(new ServiceStack.WebHost.Endpoints.EndpointHostConfig
{
DefaultContentType = ContentType.Json
..
// remove GlobalResponseHeaders because CordFeature adds the CORS headers to Config.GlobalResponseHeaders
});
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization")); //Registers global CORS Headers
this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
if (httpReq.HttpMethod == "OPTIONS")
httpRes.EndRequestWithNoContent(); // v 3.9.60 httpExtensions method before httpRes.EndServiceStackRequest();
});
//Register all Authentication methods you want to enable for this web app.
Plugins.Add(new AuthFeature(() => new CustomUserSession(), // OR the AuthUserSession
new IAuthProvider[] {
new myAuthProvider(),
}) { HtmlRedirect = null }); // Redirect on fail
HtmlRedirect answer
Routes.Add<TestRequest>("/TestAPI/{Id}", "POST,GET, OPTIONS");
....
}
In Service
[Authenticate]
public class TestAPI : Service
{
...
}
in javascript
jQuery.support.cors = true;
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
}
Login first
function Authenticate() {
$.ajax({
type: 'Post',
contentType: 'application/json',
url: serverIP + 'Auth',
cache: false,
async: false,
data: {},
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", make_base_auth(username, password));
},
success: function (response, status, xhr) {
localStorage.sessionId = data.SessionId;
var UserName = response.userName;
},
error: function (xhr, err) {
alert(err);
}
});
}
and request
function DoTest() {
var TestRequest = new Object();
TestRequest.name = "Harry Potter";
TestRequest.Id = 33;
var username = "admin";
var password = "test";
$.ajax({
type: 'Post',
contentType: 'application/json',
cache: false,
async: false,
url: serverIP + '/TestAPI/'+ TestRequest.Id,
data: JSON.stringify(TestRequest),
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Session-Id", localStorage.sessionId);
},
success: function (response, status, xhr) {
var s= response.message;
},
error: function (xhr, err) {
alert(xhr.statusText);
}
});
}
these questions here and here are helpful.
Also this answer for CredentialsAuthProvider, in case we can use cookies and sessions.

CORS POST Request is not working in FireFox 21.0 version - It gives HTTP 405 error

Below code is in my website:
function validateRequest() {
var $form = $('form');
if ($form.valid()) {
$.support.cors = true;
var lnkey = $('#txtloan').val();
var psw = $('#txtpsw').val();
var loanServiceUrl = #Html.Raw(Json.Encode(ConfigurationManager.AppSettings["LoanServiceURL"]));
var msg = {"loan": lnkey, "psw": psw};
$.ajax({
cache: false,
async: true,
type: "POST",
url: loanServiceUrl + "ValidateRequest",
data: JSON.stringify(msg),
contentType: "application/json; charset=utf-8",
dataType: "json", //jsonp?
success: function (response) {
$(response).each(function(i, item) {
if (item.Validated.toString().toUpperCase() == 'TRUE') {
// When validation passed
$('#divResult').load('#Url.Action("GetLoanInfo", "Validate")');
$("#btnClearStatus").show();
$('#btnGetStatus').hide();
}
});
},
error: function (errormsg) {
alert("ERROR! \n" + JSON.stringify(errormsg));
}
});
}
}
I have set following setting in IIS where my service is deployed.
When I make a POST call from website, I see two calls (probably one is pre-flight call for CORS) in fiddler. This is working fine in chrome and Safari but not in Firefox. I get HTTP 405 error. I am using Firefox 21.0.
Below is the snap shot from fiddler when service is called from firefox.

getting an error while using window.location.assign()

i want to assign new location but somehow i cant. i got an error while doing this.
Here is my code
jQuery.ajax({
type: "POST",
data: 'name='+ countryname,
url: "master/ValidationCountry.jsp",
// cache: false,
async: false,
success: function(response){
window.location.assign(request.getContextPath() +"/jsp/admin/AdminMaster.jsp?a=1");
// window.location.reload();
// window.location.replace(request.getContextPath() +"/jsp/admin/AdminMaster.jsp?a=1");
check = true;
},
error: function() {
check=false;
}
});
The error i got is:
ReferenceError: request is not defined
plz help me.
It looks like you are trying to access a http servlet requst object using javascript.
request.getContextPath() is a server side object, it is not available in client side.
One possible solution here is to use a global variable like _context = <context-path-from-request> and use it in your script
This need to be done in your view file like jsp/velocity/freemarker/tiles
jQuery.ajax({
type: "POST",
data: 'name='+ countryname,
url: "master/ValidationCountry.jsp",
// cache: false,
async: false,
success: function(response){
window.location.assign(response.d +"/jsp/admin/AdminMaster.jsp?a=1");
// window.location.reload();
// window.location.replace(response.d +"/jsp/admin/AdminMaster.jsp?a=1");
check = true;
},
error: function() {
check=false;
}
});
....................
and from server side web service function ,
[webMethod]
public static string fun()
{
return httpcontext.current.request.getContextPath();
}

401 (Unauthorized) error with ajax request (requires username and password)

I'm making an ajax request to retrieve json data from webtrends - a service that requires a login. I'm passing the username and password in my ajax request, but still gives me a 401 unauthorized error. I've tried 3 different methods - but no luck. Can someone pls help me find a solution?
1. $.getJSON('https://ws.webtrends.com/..?jsoncallback=?', { format: 'jsonp', suppress_error_codes: 'true', username: 'xxx', password: 'xxx', cache: 'false' }, function(json) {
console.log(json);
alert(json);
});
2. $.ajax({
url: "https://ws.webtrends.com/../?callback=?",
type: 'GET',
cache: false,
dataType: 'jsonp',
processData: false,
data: 'get=login',
username: "xxx",
password: "xxx",
beforeSend: function (req) {
req.setRequestHeader('Authorization', "xxx:xxx");
},
success: function (response) {
alert("success");
},
error: function(error) {
alert("error");
}
});
3. window.onload=function() {
var url = "https://ws.webtrends.com/...?username=xxx&password=xxx&callback=?";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
}
function parseRequest(response) {
try {
alert(response);
}
catch(an_exception) {
alert('error');
}
}
Method 3 might work when you use a named callback function and use basic authentication in the url. Mind though that a lot of browsers don't accept url-authentication (or whatever the name is). If you want to try it, you can rewrite it like this:
window.onload = function() {
var url = "https://xxx:xxx#ws.webtrends.com/...?callback=parseRequest";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
}
function parseRequest(response) {
try {
alert(response);
}
catch(an_exception) {
alert('error');
}
}

Resources