I am developing some client side Javascript that is using some JSON web services on a different domain. I have read that some browsers do not allow cross-domain scripting and that I should create a proxy on my local server to serve the data.
Can someone please point me to a simple example of how to do this in ASP.Net?
Generally speaking, the proxy runs on your web server - most likely IIS in your case - and 'relays' the requests to another server on a different domain.
Here's an example of one implemented in C# .NET
Fast, Streaming AJAX proxy
You may be able to avoid a proxy by using a technique like JSONP. Assuming the web service you're talking to supports JSONP (for example, Flickr or Twitter both offer a JSONP API) or you have control over the data the web service sends back, you can send JSON data between domains using a library that features JSONP.
For example, in jQuery, you can make a remote JSON call:
jQuery.getJSON("http://www.someothersite.com/webservice?callback=?", function(result)
{
doStuffWithResult(result);
});
Because the call is to another domain, jQuery automatically uses some trickery to make a cross domain call. jQuery will automatically replace the ? in the url with a callback function name that the web service can use to format the JSON data being returned.
If you're the one controlling the web service, you can handle the JSONP request by getting the request parameter called "callback" which will be set to the callback function name you need to use. The callback function takes one parameter, which is the JSON data you want to send back. So, if the callback parameter is set to "jsonp2342342", you'll want the web service to respond like this:
jsonp2342342({key: value, key2: value});
If the web service you're using already supports JSONP, you won't have to worry about doing the formatting yourself.
You can write a simple .NET page to retrieve the remote page and display it on your site:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
namespace Proxy
{
public partial class _Proxy : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string proxyURL = string.Empty;
try
{
proxyURL = HttpUtility.UrlDecode(Request.QueryString["u"].ToString());
}
catch { }
if (proxyURL != string.Empty)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(proxyURL);
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode.ToString().ToLower() == "ok")
{
string contentType = response.ContentType;
Stream content = response.GetResponseStream();
StreamReader contentReader = new StreamReader(content);
Response.ContentType = contentType;
Response.Write(contentReader.ReadToEnd());
}
}
}
}
}
See my post about it: http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
No browsers allow cross-domain scripting, and although w3c has left space for this in its recommendation on the xmlHTTPRequest-object, we still have to wait for some time to see it implemented in a secure way ...
I'll give a pseudocode version for people seeking a general answer to the question.
SomeAjaxAbstraction.Request('proxyScript', {
parameters: {
address: 'http://somewhere.com/someapi?some=query'
}
});
Then in proxyScript:
var address = GET['address'];
if(ValidUrl(address) && ConnectionAllowed(address)) {
// Validating address and whitelisting services is an exercise to the reader
var response = SomeHttpGetFunction(address);
echo XssAndBadStuffFilter(response);
} else {
// Handle errors
}
Related
We have a simple application in ASP.NET Core which calls a website and returns the content. The Controller method looks like this:
[HttpGet("test/get")]
public ActionResult<string> TestGet()
{
var client = new WebClient
{
BaseAddress = "http://v-dev-a"
};
return client.DownloadString("/");
}
The URL which we call is just the default page of an IIS. I am using Apache JMeter to test 1000 requests in 10 seconds. I have always the same issue, after about 300-400 requests it gets stuck for a few minutes and nothing works. The appplication which holds the controller is completely frozen.
In the performance monitor (MMC) I see that the connection are at 100%.
I tried the same code with ASP.NET 4.7.2 and it runs without any issues.
I also read about that the dispose of the WebClient does not work and I should make it static. See here
Also the deactivation of the KeepAlive did not help:
public class QPWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
((HttpWebRequest)request).KeepAlive = false;
}
return request;
}
}
The HttpClient hast the same issue, it does not change anything
With dependency injection like recommended here there is an exception throw that the web client can't handle more request at the same time.
Another unsuccessful try was to change ConnectionLimit and SetTcpKeepAlive in ServicePoint
So I am out of ideas how to solve this issue. Last idea is to move the application to ASP.NET. Does anyone of you have an idea or faced already the same issue?
I am using ASP.NET 4.7 and MVC5 with C# with IIS Express locally and published to Azure App Services.
I want to add something like:
Response.AppendToLog("XXXXX Original IP = 12.12.12.12 XXXXX");
Which adds an Original IP address to the request string in the "request" column in the web server log.
If I add this to a specific "get" Action this works fine. However I do not want to add this code to every Action. Is it possible to place it more centrally such that it gets executed on every "Get" / Request. This may be a simple question, but the answer alludes me at present
Thanks for any wisdom.
EDIT: Is this via Custom Action Filters?
if (filterContext.HttpContext.Request.HttpMethod=="GET")
{
Response.AppendToLog... //I know this will not work as Response not known.
}
You almost know the answer. Try handling OnActionExecuted that gets you the Response.
public class CustomActionFilter : ActionFilterAttribute, IActionFilter
{
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
if(filterContext.HttpContext.Request.Method == HttpMethods.Get)
{
}
}
void IActionFilter.OnActionExecuted(ActionExecutedContext context)
{
var response = context.HttpContext.Response;
}
}
My solution to write out text:
filterContext.RequestContext.HttpContext.Response.AppendToLog("OrigIP");
is it possible to execute a server side program and get the output asynchronously.
i have this code that doing the job but synchronously:
suppose a c# program "program.exe" like this :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace testconsole
{
class Program
{
static void Main(string[] args)
{
for (int k = 0; k < 10; k++ )Console.WriteLine(k);
}
}
}
some view in the asp.net app like this :
<script >
function go()
{
var options = {
url: '/excute',
type: 'GET',
dataType: 'json'
}
//make call
$.ajax(options)
.then(function (data) {
console.log(data);
});
}
</script>
<input type="submit" onclick="go();" value="Go">
and the excute controller looks like this :
namespace myApp.Controllers
{
public class ExecuteController : Controller
{
//
// GET: /Execute
[HttpGet]
public JsonResult Index()
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "program.exe";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
return Json(new { op = output }, JsonRequestBehavior.AllowGet);
}
}
}
All this is working fine, But ... from the client have to wait till the end of the program to display its outputs, is there any way to get those outputs as soon as they r created?
im sur i need to make some changes in the controller to make it possible, but how ???
Asp.Net MVC has the concept of an Async Controller that is suited to perform long-running tasks. It will help you by not locking a thread while you wait for out program to execute.
But to do what you are after I think you need to create you own Http Handler (probaby by implementing the IHttpHandler interface) that wraps the process and returns the results incrementally. This will not be trivial to do, but it should be possible.
A third viable alternative might be to use SignalR. That would be a fun project, but would still require much work I think.
The problem is primarily with communication between the IIS host process and your external process. You would need to facilitate some sort channel of communication to send "progress" events from the console application into the ASP.NET application.
A WCF client sending information via named pipes to a service hosted in the ASP.NET application would enable you to send messages into the application. You would host the service when the request is made and dynamically generate the name of pipe as a way to correlate to the initial request.
Once you get the updates in the application, you could then use something like SignalR to allow you to push the information back up the client.
Im back finally with an answer (not perfect i suppose). I used SignalR to get this done.
i created a messenger program (with c#) that will be the bridge between an asp.net mvc4 application and any console program that displays outputs.
the messenger will execute the program , then redirect his outputs to be send trough SignalR to the client.
if you are interested i've created a repo at github for this ,check this code here. I hope it will help someone one day.
i will be happy to talk about this code with you.
I have an ASP.net Webservice (asmx) which returns some secure stuff from my application. I want to create a client application which uses a certificate to connect to this service and calls this method. Using a certificate I want to ensure only this special client application can call this webservice method.
I've read hundreds of complicated articles how to setup the infrastructure but I quited because of annoying setups and very complicated parts (i.E. certificate store setups,...). I decided to manually do the certificate validation within my service method. This way I know what's going on and I don't have to rely on complicated server setups.
But the question is: How can I do that?
This stubs represent what I want to do:
[WebMethod]
public string GetSecureData() {
if(!ValidateClientCertificate()) {
throw new HttpException((int) (HttpStatusCode.BadRequest), "Bad Request");
}
return "i am secure";
}
private bool ValidateClientCertificate() {
HttpClientCertificate cert = HttpContext.Current.Request.ClientCertificate;
if (!cert.IsPresent || !HttpContext.Current.Request.IsSecureConnection) {
return false;
}
bool isValid = /* is cert the almighty client certificate? */
return isValid;
}
On client side I do something like this:
X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\\secure.cer");
ServicePointManager.CertificatePolicy = new CertPolicy();
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://myserver/Secure.asmx/GetSecureData");
Request.ClientCertificates.Add(Cert);
Request.Method = "GET";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
It would be awesome if I can put some sort of "public key" into the application (App_Data) and check if the client certificate received is the one represented by this public key.
The problems are:
How do I do the magic shown as comment in the first code piece?
I guess the IIS and ASP.net will block the unknown/unverified client certificate. I would need to disable this check for this special service method.
Please don't blame me if the answer is easy and already answered thousands of times. There are thousands of articles about this topic with 100 different solutions and variants. I couldn't find the matching one for my problem.
I heard SignalR is a good messaging library. I got some code for SignalR but I am not able to understand how it works.
JS
var hooking;
$(function() {
hooking = $.connection.hooking;
hooking.removeLead = function(ref) {
$("lead" + ref).remove();
};
$.connection.hub.start();
});
C#
// Hooking.cs (placed in application root)
public class Hooking : Hub
{
public void Submit(string jsonString)
{
var serializer = new JavaScriptSerializer();
var json = serializer.Deserialize<HookingLeadResult>(jsonString);
Clients.removeLead(json.Ref); // Remove lead from client hooking windows
// update lead gen
}
}
I have questions about the above code.
What does hooking mean ins $.connection.hooking;
Where is removeLead in hooking.removeLead
What will this do $.connection.hub.start(); ? What does it start? Which method it will invoke at the server side?
Who & how Submit method will be called at the server side? how to pass data from client side to server side. If possible please give me a url for good start for SignalR library.
The Javascript function hooking.removeLead will be invoked whenever you call Clients.removeLead(). All the bindings are done dynamically, between Javascript to C# and between C# and Javascript.
$.connection.hub.start() is actually the connect function. It will connect your client to the server. No messages can be sent or received until you do. The start function allows you to define a callback to be called when it's done connecting.
The Submit method at the server will be called whenever you do a hooking.submit(json) call on your client. For instance, as a result of the user filling in some form and clicking a button.
I recommend starting with the SignalR official wiki: http://www.asp.net/signalr