Answer the question
In order to leave comments, you need to log in
How to send data to RestFul service using ajax?
Hello. I'm not very good with the web. Therefore, please explain in more detail.
There is a WCF restful service (i.e. accepting http requests). So, I get data from the service without problems (using ajax), but I can’t send it to it, a 405 error pops up, I don’t know, maybe I’m not making the right request. Through the console, by the way, everything is fine, I send data, I receive it, everything is ok.
here is the service config
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="CORSWebHttpBinding" crossDomainScriptAccessEnabled="True" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="TZ.Host.TzService" behaviorConfiguration="CORSServiceBehavior">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="CORSWebHttpBinding" behaviorConfiguration="EndpBehavior"
contract="TZ.Host.ITzService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CORSServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
protected void Application_BeginRequest(object sender, EventArgs e)
{
EnableCrossDomainAjaxCall();
}
private void EnableCrossDomainAjaxCall()
{
String corsOrigin, corsMethod, corsHeaders;
corsOrigin = HttpContext.Current.Request.Headers["Origin"];
corsMethod = HttpContext.Current.Request.Headers["Access-Control-Request-Method"];
corsHeaders = HttpContext.Current.Request.Headers["Access-Control-Request-Headers"];
if (corsOrigin == null || corsOrigin == "null")
{
corsOrigin = "*";
}
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", corsOrigin);
if (corsMethod != null)
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", corsMethod);
if (corsHeaders != null)
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", corsHeaders);
}
[ServiceContract]
public interface ITzService
{
[OperationContract()]
[WebInvoke(Method = "GET", UriTemplate = "/GetTestData", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
List<TZ.Data.Test> GetTestData();
[WebInvoke(Method = "POST")]
void AddTestData(TZ.Data.Test value);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TzService : ITzService
{
private static List<TZ.Data.Test> TData = new List<Test>(){new Test(){ID = 0,Name = "a"}, new Test(){ID = 1,Name = "B"}};
public List<TZ.Data.Test> GetTestData()
{
return TData;
}
public void AddTestData(TZ.Data.Test value)
{
TData.Add(value);
}
}
[DataContract]
public class Test
{
[DataMember(Name = "id")]
public int ID { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
}
static void Main(string[] args)
{
SendData();
GetData();
Console.ReadKey();
}
private static void SendData()
{
string url = @"http://localhost:2337/TzService.svc/AddTestData";
WebClient client = new WebClient();
client.Credentials = System.Net.CredentialCache.DefaultCredentials;
client.Headers["Content-type"] = "application/json";
TzService.Test employee = new TzService.Test() { id = 11, name = "oooooo11" };
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(TzService.Test));
serializer.WriteObject(stream, employee);
client.UploadData(url, "POST", stream.ToArray());
}
private static void GetData()
{
string url = @"http://localhost:2337/TzService.svc/GetTestData";
WebClient client = new WebClient();
client.Credentials = System.Net.CredentialCache.DefaultCredentials;
byte[] data = client.DownloadData(url);
Stream stream = new MemoryStream(data);
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(List<TzService.Test>));
List<TzService.Test> result = obj.ReadObject(stream) as List<TzService.Test>;
foreach (var p in result)
{
Console.WriteLine(p.id + "||" + p.name);
}
}
function Start() {
$.ajax({
type: 'GET',
url: "http://localhost:2337/TzService.svc/GetTestData",
async: false,
cache: false,
dataType: 'json',
crossDomain: true,
success: function (data) {
ShowData(data);
},
error: function (e) {
console.log(e.message);
}
});
};
function SendData() {
var Json = { 'id': 9, 'name': "z" };
$.ajax({
url: url,
data: JSON.stringify(Json),
type: "POST",
processData: false,
async: false,
contentType: "application/json",
dataType: "text",
success:
function (response) {
},
error: function (er) {
}
});
}
Answer the question
In order to leave comments, you need to log in
The problem is that you are trying to make a cross-domain request, which is also not safe (not a GET or a simple POST). It's probably because you specified the Content-Type.
In order for such a request to be made by the browser, the server must be able to process the OPTIONS request by responding with the correct Access-Control-Allow-Headers header (and Access-Control-Allow-Origin, of course).
On the request "wcf rest options request" in Google, the very first link leads to this one . Not the neatest solution (I'd rather hang the processing of the OPTIONS request and the issuance of CORS headers on some class-level attribute) - but it will do.
PS be careful with this solution - in fact, it turns off the protection against CORS. You should not keep a private API and "regular" web pages in the same project as a public API.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question