I have a WCF Service which returns a string. I am trying to call it using a cross domain JsonP request. This is working in IE but no other browser. I get a parser error back in Firefox and Chrome.
From reading through various articles i seem to think that maybe the service needs to be returning the result back as a different format. Any ideas would be helpful, here is my code.
WCF Service Code
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public string SponsorLayout2(string projectScope, int projectYear, int imageHeight)
{
// Mock data
projectScope = "uk";
projectYear = 2012;
imageHeight = 42;
// Get projectId
var project = Projects.GetProjectByProjectScopeAndYear(projectScope, projectYear);
// Get project sponsor layouts
var projectSponsorLayout = ProjectSponsorLayouts.GetProjectSponsorLayout(project.Id, imageHeight);
// Return the sponsors
if (projectSponsorLayout != null)
return projectSponsorLayout.Body;
return null;
}
Jquery Ajax Call
$.ajax({
cache: false,
type: "GET",
async: false,
data: {},
url: "http://127.0.0.1:8082/HtmlService.svc/SponsorLayout2",
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
alert("success");
},
error: function (xhr) {
alert("error");
alert(xhr.statusText);
},
complete: function(jqXHR, textStatus) {
alert(textStatus);
}
});
I found out why I was getting the problem stated above and thought I would share this with you.
For some reason there was a conflict between this attribute
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
which sits on top of my class
public class MyClass
and this rule in my web.config file
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
I have ended up commenting the rule out in my web.config and everything come to life. Because my service is an AJAX ready service, the attribute is added above the class out of the box. Anyway this worked for me and hope it helps anyone else in the same situation.
Related
I have seen numerous examples, mostly wrong or outdated concepts written a decade ago. I cant seem to find a way to submit multiple variables to the ef core database using Ajax. I can get it to work with one, but cant seem to get it to work with multiple. Not sure if I am doing something wrong? I just get a syntax error on the var dataObjects
Ajax Call
<script type="text/javascript">
$("#cosubmitbutton").click(function () {
if ($('#CompanyId').val() == "-1" || $('#CompanyId').val() == "0") {
toastr.warning("Please select company / Client!");
return false;
}
var dataObjects = {
CompanyId = $("#CompanyId").val();
TechnicalContact = $("#TechnicalContactId").val();
TCEmailAddress = $("#TCEmailAddressId").val();
NumOfWorkstations = $("#NumOfWorkstationsId").val();
NumOfUsers = $("#NumOfUsersId").val();
NumOfServers = $("#NumOfServersId").val();
NumOfFirewalls = $("#NumOfFirewallsId").val();
NumOfSwitches = $("#NumOfSwitchesId").val();
NumOfAps = $("#NumOfApsId").val();
Domain = $("#DomainId").val();
};
//ObjThreadItem = JSON.stringify({ 'ObjThread': ThreadItem});
console.log("Json Stringify CommonPostData: ", JSON.stringify(dataObjects))
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'JSON',
url: '/Onboarding/Client/CreateClientOverview',
type: "post",
data: JSON.stringify(dataObjects),
success: function (result) {
debugger
toastr.success("Information successfully updated on server!");
location.reload();
},
failure: function (response) {
debugger
console.log(response);
}
});
});
</script>
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult CreateClientOverview(ClientOverview Modal)
{
_context.ClientOverview.Add(Modal);
_context.SaveChanges();
return Json(Modal);
}
I am having trouble getting binding to work with a specific set of circumstances. I am using Razor Pages with ASP.NET Core 3.1 to act like a controller for servicing AJAX calls. I have already added the anti-forgery token to the Startup.cs:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
My AJAX calls include the anti-forgery in the calls and look like:
function getTankConfig(tankId) {
var json = { id: tankId };
$.ajax({
cache: false,
type: "GET",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
url: "/Tank/Config",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(json),
success: getTankConfigSuccess
});
}
function getTankConfigSuccess(data) {
if (data !== null) {
// do stuff with data
}
}
I have tried about every combination of binding technique. Using the parameter normally, adding [FromBody], adding a public property and giving it the [BindProperty] attribute, using [BindProperty(SupportsGet = true)]. It seems like it was so simple when using a controller to do this, but I am not finding the magic for making it work with Razor Pages and PageModels.
Here is the simplified version of my PageModel class:
public class TankConfigModel : PageModel
{
public JsonResult OnGet(int id)
{
TankConfigViewModel config = new TankConfigViewModel();
config.Id = id;
return new JsonResult(config);
}
}
Any help or guidance would be greatly appreciated. Thanks.
You have to add this to your razor page
#page "{id}"
and fix ajax
$.ajax({
type: "GET",
url: "/Tank/Config/"+tankId,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (result) {
getTankConfigSuccess(result)
},
error: function (jqXHR) {
}
});
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
A few colleagues and I have a problem whereby the response from an ajax call returns some unexpected content. Rather than getting a simple JSON object back with various properties, the value of result.responseText is the HTML markup of a generic 406 status error page, saying the MIME type is not accepted by the browser.
The call is made like so:
$.ajax({
url: '/promociones/cincogratis/canjear-codigo-promocional',
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('.promotion_banner .loader').hide();
$('.promotion_banner').html(result);
},
error: function (result) {
var obj = result.responseText;
if (obj.isRedirect) {
document.location = obj.redirectUrl;
}
else {
$('.promotion_banner .loader').hide();
$(".error-wrapper").removeClass("hidden");
var generic_error = document.getElementById('generic_error').value;
$(".error-wrapper p").html(generic_error);
}
},
beforeSend: function() {
$('.promotion_banner .loader').show();
}
});
The controller response to the call is like so:
Response.StatusCode = (int)HttpStatusCode.NotAcceptable; // 406
return Json(new { errorMessage = LocalErrorMessages.Website_Promotions_FreeFiver_General_Problem, isRedirect = false } );
We would expect result.responseText to contain key values for errorMessage and isRedirect, but they’re not there.
It’s worth pointing out that this code is multi-tenanted, shared by the current application and another one, where it works absolutely fine.
We’ve tried:
- Configuring IIS to show detailed error responses rather than a custom page for more detail – gives us nothing extra towards solving the problem.
- Allowing all response content types to the call
- Changing the culture of our site (which is currently es-ES)
- Various web.config tweaks
Has anyone ever had this problem?
Simplify your request. Maybe something like:
$.ajax({
url: '/promociones/cincogratis/canjear-codigo-promocional',
type: 'GET',
data: {foo:'bar', one:'two'},
dataType: 'json',
success: function (result) {
console.dir(result);
},
error: function (xhr) {
console.dir(xhr)
}
});
And post the response from the server. This kind of error seems a request problem rather than server configuration issue
Ok this one should be easy for someone who knows this sort of thing better. I am going to limit the scope of the code I provide because this works in one variation (fiddler).
This problem is simple to explain: I have a method in WCF that takes a string as a parameter. The method expects a request with a wrapped body style. If I create a simple object in fiddler and send it over it works. Something like {"submission":"something"}. If I do this in via ajax in JSON it does not work. I get a bad request error saying it is not allowed... this is cross domain but this is not the problem, I add the appropriate headers in the method to handle this. In this case the method is never being called (it is like it is an issue with the signature).
Here is the thing though... if I make a really simple class with one property of a string and pass in an object it works fine. Passing objects in a wrapped body style work fine. Trying to do this with a "primitive type" such as a string does not... any ideas?
THIS DOES NOT WORK (but does work via fiddler)....
var datain = new Object();
datain.submission = "mysubmission";
var dataToSend2 = JSON.stringify(datain);
$.ajax({
type: "POST",
url: "http://localhost:8000/ServiceModelSamples/Service/rest/Reflect",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: dataToSend2,
success: function (item) {
debugger;
alert(item);
},
error: function (xhr) {
debugger;
alert(xhr);
}
});
WITH THIS CONTRACT....
[OperationContract]
[WebInvoke(Method = "*",
RequestFormat = WebMessageFormat.Json,
BodyStyle=WebMessageBodyStyle.WrappedRequest)]
string Reflect(String submission);
THIS DOES WORK....
var spec = new Object();
spec.submission = "mysubmission";
var dataToSend3 = '{"thespecial":' + JSON.stringify(spec) + '}';
$.ajax({
type: "POST",
url: "http://localhost:8000/ServiceModelSamples/Service/rest/Reflecting",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: dataToSend3,
success: function (item) {
debugger;
alert(item);
},
error: function (xhr) {
debugger;
alert(xhr);
}
});
WITH THIS CONTRACT...
[OperationContract]
[WebInvoke(Method = "*",
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string Reflecting(Special thespecial);
Yes, you can't send the primitive data types without wrapping in xml.
you can check the complete request structure after enabling the help in endpoint behavior
suppose you have endpoint name "api" for webHttpBinding then you can enable the help using following
< webHttp helpEnabled = "true " />
After configuring it you can see the help as follow
http://localhost:<port>/test.svc/api/help
This will show the actual request format.
Like to pass string you can use the following format wrapper
<string xmlns="http://schemas.microsoft.com/2003/10/
Serialization/">Hello World</string>
or you can use stream input parameter
Click here to implement streaming