I'm developing a SOAP software for a customer. We are migrating to SOAP because we'll do a mobile app soon.
I alread did the .svc file and connects with IE. But, if I try to connect with Firefox, Opera, GC or any other browser, it says "Method not allowed".
I alread tried to insert a header on AJAX/JSON to allow 'Access-Control-Allow-Origin'. I also insert on server side, on the interface the webinvoke header, and nothing works.
This is my first question on stack overflow, so I do not know how asking works.
Thanks to all!
Header Code of AJAX/JSON:
function SendToService(urlSvc, objDTO) {
var bk = null;
var item = {
info: objDTO
};
$.ajax({
url: urlSvc,
type: 'POST',
data: JSON.stringify(item),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
async: false,
headers: {
'Access-Control-Allow-Origin': 'http://localhost:16587',
},
success: function (msg) {
bk = msg.d;
},
error: function (msg) {
bk = false;
}
});
return bk;
};
It looks like your method doesn't allow POST requests. Try allowing for POST on the destination method or test by changing your ajax request to GET instead. If the GET succeeds, you know where your problem is.
Related
I would like to understand a little better about WebApi in Net and how is the correct way to called it with ajax. Little of info about my development environment: I am using .net 4.0 and visual studio 2010 and Jquery.
Model:
public class TestForm
{
public string FirstName { get; set; }
}
WebApi:
public class TestpController : ApiController
{
[HttpPost]
public HttpResponseMessage Post(TestForm form)
{
string jose = "jose";
return Request.CreateResponse(HttpStatusCode.OK, "yay");
}
}
Client side:
V1 (doesnt work, return error 405 ):
$.ajax({
url: "http://xxx/api/Testp",
type: "POST",
data: JSON.stringify({ FirstName: "Jose" }),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(data) {
console.log("success");
},
error: function (xhr, errorType, exception) {
console.log("error");
}
});
V2 (works):
$.ajax({
url: "http://xxx/api/Testp",
type: "POST",
data: { FirstName: "Jose" },
dataType: 'json',
success: function(data) {
console.log("success");
},
error: function (xhr, errorType, exception) {
console.log("error");
}
});
Why do I get an error when I add contentType: "application/json; charset=utf-8" and change the data to JSON.stringify({ FirstName: "Jose" }), but it works when I removed the content type and send a object in data option.
Short answer lies in the output of these alerts:
alert(JSON.stringify({FirstName :"Jose"}));
alert({FirstName :"Jose"});
The first one gives you a string, the second one gives you an object.
Your method:
public HttpResponseMessage Post(TestForm form)
Accepts an object and not a string. So when you post a string, .NET Framework is not able to find a method which can process a string, hence returns 405.
The Problem you are encountering seems to be jQuery preflight.
If you take a look at the Headers of your request you'll see that in V1 the Http Method used is actually OPTIONS. That is because jQuery does only allow certain values for the Content-Type Header.
#McBoman gave a good overview on this, at the linked source. You may also want to read up on Cross Origin Resource Sharing (Cors) for example this.
You need to add a Function that answers to [HttpOptions] and explicitly tells the preflight-request that a certain "custom"-Header is allowed or in the case of cross-origin request allowing the originating domain.
You would need to adapt the below Function to your needs, taking the info preflight provides you with.
[HttpOptions]
public HttpResponseMessage Options() {
var response = request.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("access-control-allow-origin", "*");
response.Headers.Add("access-control-allow-headers", "content-type");
return response;
}
Hope that helps you.
I make a total of four Ajax calls in my .NET application. Three of them work without a hitch except the last one.
Note: I HAVE to use .aspx for these calls and not mypage.aspx/mymethod because of our architectural constraints.
Ajax call that works:
$.ajax({
type: "POST",
url: "myaddress/GenerateOpinionHTML.aspx",
data: JSON.stringify({ id: featureId, pageNumber: pageNumberIndex }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
SOME PROCESSING (IT WORKS)
},
error: function (xhr, status, error) {
var err = xhr.responseText;
console.log(err);
}
});
and
[WebMethod]
public static string GenerateOpinionHTML(int id, int pageNumber)
{
// ...
}
Ajax call that does not work:
console.log("SUBMITOPINIONCLICK");
var param = " ";
$.ajax({
type: "POST",
url: "myaddress/SaveOpinion.aspx",
data: JSON.stringify({ parameter: param}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log("SAVE OPINION SUCCESSFUL");
console.log(msg.d);
CloseLB('GiveOpinionLB');
},
error: function (xhr, status, error) {
var err = xhr.responseText;
console.log("ERROR " + "STATUS: " + status);
}
});
and
[WebMethod]
public static string SaveOpinion(string parameter)
{
// ...
}
The web method SaveOpinion is never called according to the logs. Do you have any ideas or suggestions? I tried adding parameters, without parameters, checking my web.config file (though I shouldn't have since the other calls work)...
The error I get on the browser console is a "parseerror". I'm certain I wouldn't be getting an error if the method was called.
I think your URL should be like
url: "Your FolderName/PageName/Function Name",
Like
url: "myaddress/SaveOpinion.aspx/SaveOpinion"
but in your code this is different so that please check.
Have you checked if method SaveOption return something to the client?
If you specify dataType as json, you should return (at least): {}
Ok so we "solved" it. We just found a very dirty band-aid workaround that works.
We made a custom handler (.ashx) that we defined in our architecture as a SaveOpinion.aspx page.
We then called this custom handler page with jQuery and voilĂ it works, we had to obviously pass all necessary parameters manually, ie. fetching all values from textBoxes etc with jQuery and not from the context as we did before.
Since this is run in some sort of thread (I don't really know the details) we had to configure it so that it simulates the same user authentification.
Anyway I hope this provides some measure of guidance for those with this kind of obscure problems.
I have a Restfull WCF service running.
All the operation works perfect and tested.
But when I try to call one of the PUT operation from client side using jquery JSON the header request changes to GET() method though I have mentioned PUT as method.
Tested on fiddler same 405 method not allowed error.
I know as it is a PUT method we can not apply GET but on client side if I use PUT() it automatically changes to GET in header request and fails.
Why it is happening can't get to fix it.Any help or ideas?
My client code for service request is as follows:
function UpdateRating(radioValue) {
jQuery.support.cors = true;
var star = (Math.floor(radioValue * 2) / 10).toFixed(2);
$.ajax({
type: "PUT",
url: ServiceURL + "xxx.svc/xml/updatescoreforvideo?vid=" + videoId + "&uid=" + userId + "&score=" + star,
data: "{}",
contentType: "application/json; charset=utf-8",
async: false,
dataType: "jsonp",
success: function (data, status, jqXHR) {
alert("you rated : "+ star + "star");//show alert on success //test
},
error: function () {
alert('Service call error occured');
}
});
}
My fiddler /firebug error reports :
I am using JQuery to make a AJAX to a local service. My local service is a HttpHandler (e.g., Request.ashx). Within Request.ashx, it's responsiblity is to make a call to an external website (e.g., CallExternalWebsite()). CallExternalWebsite() uses .NET's System.Net.WebRequest() to initiate a request. When the external website is accessed, neither the success or error events are fired. (NOTE: I have also tried this a WCF service hosted in IIS. I am seeing the same results)
Here are two scenarios:
This scenario works:
In ProcessRequest(), comment out callExternalWebsite().
For object o, intialize with data to simulate results.
Click on myButton
The success event fires on the client.
In Fiddler, I can see the header info. I see Json result, etc.
This scenario does not work:
In ProcessRequest(), enable the call for callExternalWebsite().
For object o, callExternalWebsite() will return an appropriate object.
Click on myButton
The success event does not fires on the client.
In Fiddler, I can see the header info. I see Json result, etc.
I know the callExternalWebsite() is working because I have it sending results to my phone.
To sum it up, the external http call within the HttpHandler is effecting the Ajax success event.
Here is a snippet from AJAX call:
(I was trying different interations)
$(document).ready(function () {
$("#myButton").click(function (event) {
$.ajax({
cache: false,
type: "POST",
url: "http://localhost/Service/Request.ashx",
data: '{"id" : "053252f3"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
timeout: 20000,
success: function (msg) {
AjaxSucceeded(msg);
},
error: AjaxFailed
});
});
});
In the HttpHandler Request.ashx,
public Void ProcessRequest(httpContent context)
{
// Do some stuff....
// Make call to external web site
object o = callExternalWebsite (Uri, Data, "POST");
// Return results from callOtherWebsite
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string json = javaScriptSerializer.Serialize(o);
context.Response.ContentType = "application/json";
context.Response.Write(json);
}
Any thoughts?
Thanks.
Steve
What happens if you do this, msg vs msg.d:
$(document).ready(function () {
$("#myButton").click(function (event) {
$.ajax({
cache: false,
type: "POST",
url: "http://localhost/Service/Request.ashx",
data: '{"id" : "053252f3"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
timeout: 20000,
success: function (msg) {
AjaxSucceeded(msg.d);
},
error: AjaxFailed
});
});
});
Simply put I want to call public static methods decorated with WebMethod attribute inside my code-behind C# file from jquery.ajax to get some json and other simple stuff (in different functions). But instead I'm getting whole page :'(
I'm not using asp.net AJAX though I'm developing for .NET 3.5 framework and using VS 2008. (There are some restrictions from client)
Please let me know if I can use page-methods with using asp.net ajax or If not what is other simple solution?
After much deliberations I found the problem. I was using jquery's editable plugin. This was source of the problem. When jeditable calls jquery's ajax it sets ajax options like this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
success: function(result, status) {
if (ajaxoptions.dataType == 'html') {
$(self).html(result);
}
self.editing = false;
callback.apply(self, [result, settings]);
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
},
error: function(xhr, status, error) {
onerror.apply(form, [settings, self, xhr]);
}
};
so it was sending the things as simple html and to use this with page methods we need to setup the things so that it sends as json. So we need to add something to the settings like this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
dataType: 'json', //Data Type
contentType: 'application/json; charset=utf-8', //Content Type
//....other settings
};
So I put two new properties in settings dataType and contentType and changed above to this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
dataType: settings.dataType,
contentType: settings.contentType,
//....other settings
};
Now another problem arised :( it was sending data (from submitdata property) as normal query-string which asp.net does not accept with json requests. So I had to use jquery's json plugin and change the way data is sent in ajax using following test on dataType:
if (settings.dataType == "json") {
if ($.toJSON) {
submitdata = $.toJSON(submitdata);
}
}
and it works like breeze!!!
Russ Cam posted this link in response to another question (so if this helps, go up vote his answer ;)):
Using jQuery to directly call ASP.NET AJAX Page Methods
Dave Ward has a series of posts that use jQuery directly with ASP.Net PageMethods, no MS Ajax UpdatePanel required. In particular this post will get you started.
I am not sure but i think WebMethods are accessible only through asp.net AJAX. I may be wrong though, because we dont use it that way at all. We do it in a slightly different way.
We have built a aspx page which accepts all our AJAX requests and passes them to the subsequent methods.
Server side code
If Not (Request("method") Is Nothing) Then
method = Request("method")
username = HttpContext.Current.User.Identity.Name.ToString
Select Case UCase(method)
Case "GETPROJECTS"
Response.ContentType = "text/json"
Response.Write(GetProjects(Request("cid"), Request("status")))
Exit Select
end select
end if
Client Side code [using jquery]
$.ajaxSetup({
error: function(xhr, msg) { alert(xhr, msg) },
type: "POST",
url: "Ajax.aspx",
beforeSend: function() { showLoader(el); },
data: { method: 'GetProjects', cid: "2", status:"open"},
success: function(msg) {
var data = JSON.parse(msg);
alert(data.Message);
},
complete: function() { hideLoader(el); }
});
Hope this helps.