ServiceStack cache - jQuery ajax and JSONP - web-services

Is there any way to force cache even when using ajax with JSONP?
Please see below three cases and results:
#1. Request from same host (save as page making the request) and with no JSONP - cache works corecctly.
$.ajax({
type: "GET",
url: "http://samehost.com",
data: "{ 'format': 'json' }",
contentType: "application/json",
success: function(data) {
// do stuff with data
}
});
#2. Request from different host with no JSONP, I get same origin policy error.
$.ajax({
type: "GET",
url: "http://differenthost.com",
data: "{ 'format': 'json' }",
contentType: "application/json",
success: function(data) {
// do stuff with data
}
});
#3. Request from different host and with JSONP the cache does not seems to work - it takes 2-3 sec to load, where in case #1 about 70-100ms
$.ajax({
type: "GET",
url: "http://differenthost.com",
data: "{ 'format': 'json' }",
contentType: "application/json",
dataType: "jsonp",
success: function(data) {
// do stuff with data
}
});
Repeating my question, is there any way to force cache even when using ajax with JSONP?
Below you can see my ServiceStack settings.
Globas.asax.vb
Public Class Global_asax
Inherits System.Web.HttpApplication
Public Class HelloAppHost
Inherits AppHostBase
Public Sub New()
MyBase.New("Web Services", GetType(Wrapper).Assembly)
End Sub
Public Overrides Sub Configure(ByVal container As Container)
' Routes
Routes.Add(Of GetData)("/GetData").Add(Of GetData)("/GetData/{*}")
' Cache & Cors
container.Register(Of ICacheClient)(New MemoryCacheClient())
Plugins.Add(New Cors.CorsFeature())
End Sub
End Class
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
Dim apphost = New HelloAppHost()
apphost.Init()
End Sub
End Class
WS.vb
Public Class Wrapper
<EnableCors()>
Public Class WrapperGetData
Inherits Service
Implements IService(Of GetData)
Public Function Execute(ByVal request As GetData) As Object Implements ServiceStack.ServiceHost.IService(Of GetData).Execute
Dim cacheKey As String = "GetDataKey"
Dim expireInTimespan = New TimeSpan(1, 0, 0)
Return Me.RequestContext.ToOptimizedResultUsingCache(
MyBase.Cache,
cacheKey,
expireInTimespan,
Function()
Return request.HandleRequest()
End Function
)
End Function
End Class
End Class

Related

Google Storage + JQuery-File-Upload + Django + Signed URL, how should I change submit() and relevant options?

I have the following js code and it uses the signed-url api to get signed urls for uploading content to google storage via Django api.
When I use it with the following code :
xhr.open("PUT", data.signed_url);
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);
It works fine and I am able to upload to Google Storage very large files. But obviously, when I do that, I cannot use any progress-bar features of jquery-file-upload.
Can you please suggest on how I should alter the data.submit(), where shall I put it, and how should I change the options or settings prior to submitting. Should I be overriding add or submit callback ?
I feel that there is a missing support for Google Storage with Jquery-file-upload as the only example covers only obsolute Google Blobstore in the following link : https://github.com/blueimp/jQuery-File-Upload/wiki/Google-App-Engine
$("#fileupload").fileupload({
dataType: 'json',
type: 'PUT',
sequentialUploads: true,
submit: function(e, data) {
var $this = $(this);
$.each(data.files, function(index, file) {
// pack our data to get signature url
var formData = new FormData();
formData.append('filename', file.name);
formData.append('type', file.type);
formData.append('size', file.size);
// Step 3: get our signature URL
$.ajax({
url: '/api/getsignedurl/',
type: 'POST',
processData: false,
contentType: false,
dataType: 'json',
headers: {
'X-CSRFToken': Cookies.get('csrftoken'),
},
primary_data: data,
data: formData
}).done(function (data) {
// Step 5: got our url, push to GCS
const xhr = new XMLHttpRequest();
if ('withCredentials' in xhr) {
console.log("With credentials");
xhr.open("PUT", data.signed_url, true);
}
else if (typeof XDomainRequest !== 'undefined') {
console.log("With domainrequest");
xhr = new XDomainRequest();
xhr.open("PUT", data.signed_url);
}
else {
console.log("With null");
xhr = null;
}
//What shall I do to make the following work for uploading GS
this.primary_data.url = data.signed_url;
this.primary_data.headers={'Content-Type': file.type};
this.primary_data.submit();
xhr.onload = () => {
const status = xhr.status;
if (status === 200) {
} else {
alert("Failed to upload 1: " + status);
}
};
xhr.onerror = () => {
alert("Failed to upload 2");
};
//When the code below uncommented, it uploads to GS succesfully.
//xhr.setRequestHeader('Content-Type', file.type);
//xhr.send(file);
});
});
},
Also this is my cors setup for the GS Bucket.
[
{
"origin": ["*"],
"responseHeader": ["Content-Type", "Access-Control-Allow-Origin"],
"method": ["GET", "PUT", "OPTIONS"],
"maxAgeSeconds": 60
}
]

Loading Remote Data using Select2 and Webservice

I am using Select2 4.0.3 in my web forms .net application. I am trying to Load Remote data using a webservice, but its not working as expected.
First Issue am facing is that the webservice method is not getting called and am getting a console error:
System.InvalidOperationException: Missing parameter: text.
at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection)
at System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest request)
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
So I tried removing the paremeter from the webservice call
<WebMethod()> _
Public Function GetDataFromService() As String
Doing this the method got fired, but still the items in the select2 did not get populated (screenshot atached).
Can someone help me to figure out where am I making a mistake.
Here are the details:
Select2 Code in the Webform:
$("#ddlEntity").select2({
ajax: {
url: "Service/InvoiceHTMLService.asmx/GetDataFromService",
type: 'POST',
delay: 250,
params: {
contentType: 'application/json; charset=utf-8'
},
dataType: 'json',
data: function (term, page) {
return {
text: term,
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
WebService Method:
<WebMethod()> _
Public Function GetDataFromService(text As String) As String
Return "{['id':1, 'text':'Test1'],['id':2, 'text':'Test2']}"
End Function
Try this please
var fd = new FormData();
fd.append("text",term);
ajax: {
url: "Service/InvoiceHTMLService.asmx/GetDataFromService",
type: 'POST',
delay: 250,
params: {
contentType: 'application/json; charset=utf-8'
},
dataType: 'json',
data: fd
...
I think you did not create template for this select2. since you are using templateResult and templateSelection it requires template or you can remove those two options.
For your reference : https://select2.github.io/examples.html#templating
Updated:
they have changed query callback from
data: function (term, page) {
return {
text: term,
};
},
into
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},

Return Partial View with ajax call

I want to return a Partial View in ajax call in Sitecore, I am already using web APIs, i can return JSON object, but i want to return the view with HTML :
[HttpGet]
public ActionResult StoreSearchResultsPartial()
{
return PartialView("/views/components/StoreSearchResults.cshtml");
}
my ajax call :
var ajaxUrl = "/api/sitecore/components/StoreSearchResultsPartial"
$.ajax({
type: "GET",
url: ajaxUrl,
contentType: "application/json; charset=utf-8",
success: function (result) {
$("#searchResults").html(result);
},
error: function (result) {
}
});
i am using web API for other functionalities, so i added my routing :
public void Process(PipelineArgs args)
{
var config = GlobalConfiguration.Configuration;
RouteTable.Routes.MapHttpRoute(
name: "NamedActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
).RouteHandler = new SessionRouteHandler();
config.Routes.MapHttpRoute("DefaultApiRoute",
"api/{controller}/{id}",
new { id = RouteParameter.Optional });
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
When I comment this routing everything is working fine.
It is working fine now, I changed my routing to start with something not "api", so i changed this api/{controller}/{action}/{id} to be mywebapi/{controller}/{action}/{id}, then i was able to call : /api/sitecore/components/StoreSearchResultsPartial

PhantomJs- Call WebService & Get data from that

I use by PhantomJs for connect to my WebService and Post data to WebService's Function for special computing. But i can't get result from WebService's Function.
bin.js:
var page = require('webpage').create();
var data = {
'str': 'sample string'
};
page.open('http://127.0.0.1/Service.asmx/HelloWorld', 'POST', data, function(status) {
// Get status
console.log('Status: ' + status);
// I want to get result
phantom.exit();
});
webService.asmx:
[WebMethod]
public string HelloWorld(string str)
{
return str;
}
I want something look like this in PhantomJs:
$.ajax({
type: "POST",
url: 'http://127.0.0.1/Service.asmx/HelloWorld',
data: {data: 'somethings'},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
var result= data.d;
}
});
var webPage = require('webpage');
var page = webPage.create();
var postBody = 'param1=value1&param2=value2';
page.open('http:www.myservice.com/service', 'POST', postBody, function(status) {
console.log('Status: ' + status);
console.log('HTML Content: ' + page.content); // in case of an HTML response
console.log('JSON: ' + JSON.parse(page.plainText)); // in case of a JSON response
});
I solved my problem with search about "phantomjs in c#".
My solution is use of NReco.PhantomJS library in c#.

Error when returning from jQuery Ajax call

I have this in my web service;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello Worlds";
}
}
And this as my jQuery;
$(document).ready(function () {
$.support.cors = true;
$.ajax({
type: "POST",
url: "http://localhost:61614/Service1.asmx/HelloWorld",
data: "{}",
dataType: "json",
success: function (msg) {
alert(0);
alert(msg);
}, error: function (a,b,c) { alert(c); }
});
});
When I run, my breakpoint in the web service fires and I return "Hello Worlds".
However, on return back to the jQuery I drop into the error function. Safari simply alerts an empty string and IE alerts "No Transport".
Can anyone see what I'm doing wrong?
You also need to add ScriptMethod attribute:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[WebMethod]
public string HelloWorld()
{
return "Hello Worlds";
}
Also, you need to specify contentType in your ajax call:
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://localhost:61614/Service1.asmx/HelloWorld",
data: "{}",
dataType: "json",
...
Also, a good article on the topic: Here.