I have added a service reference to my asp.net web application (originally it was just a straight html site and we converted it to a web application)
We need to access a WCF service via jquery/ajax and not from within any .cs files. So far we haven't been able to get jquery to hit the service by any means, even before it was converted to a web app (converted in hopes that it would be easier to add service reference and call it)
I have the WCF service running in a separate solution running on my desktop and the web app open separately. My service is called SchoolService and is located in the Service References folder.
How in jquery do I call that service reference?
This is what we used from a demo that also did not work:
<script type="text/javascript">
$(document).ready(function () {
var schoolsCache = {}, lendersCache = {}, schoolsXhr, lendersXhr;
$('#Schools').autocomplete({
source: function (request, response) {
var term = request.term;
if (term in schoolsCache) {
response(schoolsCache[term]);
return;
}
if (schoolsXhr != null) {
schoolsXhr.abort();
}
schoolsXhr = $.getJSON('SchoolService.svc/GetSchools', request, function (data, status, xhr) {
schoolsCache[term] = data.d;
if (xhr == schoolsXhr) {
response(data.d);
schoolsXhr = null;
}
});
}
});
});
</script>
I have also tried this line which did not work:
schoolsXhr = $.getJSON('http://localhost:8000/SchoolService/GetSchools', request, function (data, status, xhr) {
Here is the interface in my WCF sdervice:
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using MyApp.DomainModel;
namespace MyAppService
{
[ServiceContract]
public interface ISchoolService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
IList<School> GetSchools(string term);
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
School GetSchool(string schoolName);
}
}
What are the necessary specific steps needed to make this work? The goal is to let user type into textbox, use jquery autocomplete, which uses the ajax call to service to pull back data that contains the typed text... surely this has been done before?
CD
You can take a look at this CodeProject article. The author is discussing exactly this profile a WCF service and JQuery client.
No one was able to answer this but we figured it out. It had nothing to do with jsonp or cross domain.
The call from javascript makes a $.getJSON call to the url. The url is the relative url to a .svc file in the project. The .svc file is nothing more than a passthru which constructs a connection to the referenced service and makes the call and then returns back to the ajax call.
Related
I am looking into Stored Cross-site Scripting vulnerabilities that occur when the data provided by an attacker is saved on the server, and is then displayed upon subsequent requests without proper HTML escaping.
I have NET 5 ASP.NET Core application using MVC. The application is using jQuery and Telerik's ASP.NET Core library. Both use JSON data returned from the server.
The application has several action methods that query stored data in the database and return as JsonResult.
For example, the following action method
[HttpGet]
[Route("items/json/{id}")]
public async Task<ActionResult> GetName([FromRoute] int id)
{
var i = await _itemService.GetWorkItem(id);
return Json(new
{
ItemName = i.Name
});
}
and client side script shows the ItemName in html using jQuery
$.get(url)
.done(function (response, textStatus, jqXHR) {
$("#itemname").html(response);
})
Suppose a user has stored the name as <script>alert('evil');</script> then the code above will execute the evil script on client side.
The application is using Newtonsoft as default serializer. By default the response does not get Html encoded. The response from the server looks like
{"ItemName":"\u003Cscript\u003Ealert(\u0027evil\u0027);\u003C/script\u003E"}
Also setting default JsonSerializerSettings in Startup like below does not work the same way as the Html Encode.
var serializerSettings = new JsonSerializerSettings()
{
StringEscapeHandling = StringEscapeHandling.EscapeHtml
};
Is there any default way in ASP.NET Core (Net 5) to handle html encoding during JSON serialization?
I understand that there is WebUtility.HtmlEncode() and also HtmlEncoder class available which can be used to apply encoding selectively . I am looking for a solution to handle html encoding by default during the JSON serialization.
Is new System.Text.Json by default applies html encoding on property values?
UPDATE 1
The comments below suggest to configure NewtonsoftJson in startup.cs. Note that question is NOT how to configure newtonsoft globally but how to html encode property value during the serialization so client (Browser) wont execute the malicious script.
I have tried Newtonsoft.Json.StringEscapeHandling.EscapeHtml which did not work. The script still executes
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddNewtonsoftJson((options) =>
{
options.SerializerSettings.StringEscapeHandling = Newtonsoft.Json.StringEscapeHandling.EscapeHtml;
});
}
You have to use Newtonsoft.Json if you don't want to create tons of code for each quite simple case. This is working for me
[HttpGet]
public async Task<ActionResult> MyTest ()
{
return new JsonResult(new
{
ItemName = "<script> alert('evil');</script>"
});
}
and use response.itemName on client side
$("#itemname").html(response.itemName);
to use Newtonsoft.Json change your startup code to this
using Newtonsoft.Json.Serialization;
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
I want to know what is the opinion of you fellow Developers regarding WCF WebApi services.
In an N-tier application we can have multiple layers of services. We can have services consuming data from external services. In that scenario its worth to create Async Rest Services using WCF 4.0.
public interface IService
{
[OperationContractAttribute(AsyncPattern = true)]
IAsyncResult BeginGetStock(string code, AsyncCallback callback, object asyncState);
//Note: There is no OperationContractAttribute for the end method.
string EndGetStock(IAsyncResult result);
}
But with the release of WCF WebApi this approach is still required? to create async services?
How to host them in IIS/WAS/Self Hosting
looking forward for suggestion and comments.
Well What i feel,In order to create asynchronous operations in the latest WCF WebAPIs (preview 6) I can still use same pattern (Begin/End), but I can also use the Task programming model to create asynchronous operations, which is a lot simpler.
One example of an asynchronous operation written using the task model is shown below.
[WebGet]
public Task<Aggregate> Aggregation()
{
// Create an HttpClient (we could also reuse an existing one)
HttpClient client = new HttpClient();
// Submit GET requests for contacts and orders
Task<List<Contact>> contactsTask = client.GetAsync(backendAddress + "/contacts").ContinueWith<Task<List<Contact>>>((responseTask) =>
{
return responseTask.Result.Content.ReadAsAsync<List<Contact>>();
}).Unwrap();
Task<List<Order>> ordersTask = client.GetAsync(backendAddress + "/orders").ContinueWith<Task<List<Order>>>((responseTask) =>
{
return responseTask.Result.Content.ReadAsAsync<List<Order>>();
}).Unwrap();
// Wait for both requests to complete
return Task.Factory.ContinueWhenAll(new Task[] { contactsTask, ordersTask },
(completedTasks) =>
{
client.Dispose();
Aggregate aggregate = new Aggregate()
{
Contacts = contactsTask.Result,
Orders = ordersTask.Result
};
return aggregate;
});
}
[WebGet(UriTemplate = "contacts")]
public Task<HttpResponseMessage> Contacts()
{
// Create an HttpClient (we could also reuse an existing one)
HttpClient client = new HttpClient();
// Submit GET requests for contacts and return task directly
return client.GetAsync(backendAddress + "/contacts");
}
WCF Web API comes with an completely async HttpClient implementation and you can host in IIS and also completely sefhost.
For a async REST "service" scenario please read "Slow REST"
I have created a WCF ajax enabled web service named "Service1.svc"
"I have to call this Service In another app's using Jquery."
I have created on method in it :
[OperationContract]
public string GetMarkup()
{
string data = "<div>My HTML markup text here</div>";
return data;
}
Now I have created jquery script in my second application's html page :
var markup = "";
$.ajax({
type: "POST",
url: "http://localhost:1676/MyWCFService.svc/GetMarkup",
contentType: "application/json",
data: "{}",
dataType: "json",
success: callback,
error: function (textStatus) {
alert("ERROR");
}
});
function callback(result) {
alert("Inside Callback");
markup = result.d;
$("#divMyMarkup").html(markup);
alert(markup);
}
NOW, My Problem is that Whenever I execute this page in IE its working fine.
But In Firefox its not working. It giving alert Error Message which defined in
error: function (textStatus) {alert("ERROR");} in above ajax call.
I tried this functionality using $.get(), $("#divMyMarkup").load(serviceUrl, callback).
I also tried this by changing the datatype as json, jsonp, html .
Still I am not getting the exact solution.
Any Expert here?
In another app's using Jquery
In my experience, IE won't respect the cross-domain policy and let you do the call, not a reference...
The only way to find out is to have your html page/JQuery script calling your WCF service from http://localhost:1676/ICallWcfServicesWithJQuery.html on Firefox.
Possible solutions:
[JSONP] how to avoid cross domain policy in jquery ajax for consuming wcf service?
[flXHR][php-proxy] jQuery “getJSON” from an external domain that doesn't support JSON-P output
[JSONP] Accessing web Service from jQuery - cross domain
[.net-proxy] aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript
Test on multiple browsers, add 1oz of gin, a can of tonic and you'll be good!
I started developing an application in Silverlight that was dealing with downloading the HTML of a website and then parsing it. With Silverlight 4 this can be achieved easily by simply requesting elevated permissions. With Silverlight 3, however, the only way to get the HTML of a website is via a WebService call. My initial idea was to do the following:
public class Service1
{
[OperationContract]
public void GetHtml()
{
Uri targetUri = new Uri("http://www.google.com", UriKind.RelativeOrAbsolute);
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += this.WebClient_DownloadStringCompleted;
webClient.DownloadStringAsync(targetUri);
}
private void WebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
}
}
However, I realized that as soon as I make the call, which is async as well, from my Silverlight application, there is no way for me to retrieve the HTML of the website. That is why I changed to the following:
public class Service1
{
[OperationContract]
public string GetHtml()
{
Uri targetUri = new Uri("http://www.google.com", UriKind.RelativeOrAbsolute);
WebClient webClient = new WebClient();
return webClient.DownloadString(targetUri);
}
}
I believe the last approach is not that fine since it will freeze the thread. So, my question, is there a way to achieve the first approach a.k.a. make async call from an async call :). Any help would be greatly appreciated.
Best Regards,
Kiril
You can achieve your goal by implementig a Duplex Service. There is some useful information about it on the msdn site and a wonderful podcast entry by Mike Taulty. In general, you would have to modify your operation contract by splitting it into two parts. First part would initiate your WebClient download on the server. Then, on the server, after the html has been downloaded, the server would call back a contract that is implemented on the client side with the payload consisting of the required html content.
Looking for alternatives to the WCF REST start kit, ideally OSS frameworks.
Anyone got a list?
Cheers
Ollie
OpenRASTA is the most mature
ASP.NET MVC is a good alternative when it comes to generating REST XML and JSON feeds.
To build a rest architecture in .net you can use GenericHandlers. You can create a GenericHandler that will receive a HTTP message (POST, GET or..) and return a message of the content-type you specify.
For example I create a generic handler on the url:
http://site/getpeople.ashx?gender=female
And call it with the parmeter gender=female, as above the handler will return the following
<people>
<person>...</person>
...
<people>
And the content type would be text/xml.
This is the simplest way to implement REST web services in .NET
I also provide ServiceStack, a modern, code-first, DTO-driven, WCF replacement web services framework encouraging code and remote best-practices for creating DRY, high-perfomance, scalable REST web services.
There's no XML config, or code-gen and your one clean C# web service is enabled on all JSON, XML, SOAP, JSV, CSV, HTML endpoints out-of-the-box, automatically. It includes generic sync/async service clients providing a fast, typed, client/server communication gateway end-to-end.
It also includes generic sync/async service clients providing a fast, typed, client/server communication gateway end-to-end.
This is the complete example of all the code needed to create a simple web service, that is automatically without any config, registered and made available on all the web data formats on pre-defined and custom REST-ful routes:
public class Hello {
public string Name { get; set; }
}
public class HelloResponse {
public string Result { get; set; }
}
public class HelloService : IService<Hello> {
public object Execute(Hello request) {
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
Above service can be called (without any build-steps/code-gen) in C# with the line below:
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
Console.WriteLine(response.Result); // => Hello, World
And in jQuery with:
$.getJSON('hello/World!', function(r){
alert(r.Result);
});