Working example of AJAX file upload to WCF service - c#

I'm looking for an example of an ajax call for streaming data to a WCF service. I am always getting an error.
Any help appreciated, or even links to blogs with a solution.
This is my WCF service class
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Images : IImages
{
string IImages.UploadImage(string fileKey, Stream imageStream)
{
using (var fileStream = File.Create(#"Images\" + fileKey))
{
imageStream.CopyTo(fileStream);
}
return "done";
}
}
and my contract is
[OperationContract(Name = "UploadImage")]
[WebInvoke(UriTemplate = "?file_key={fileKey}", Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
string UploadImage(string fileKey, Stream imageStream);
I have web.config stream binding
<binding name="PublicStreamBinding"
maxReceivedMessageSize="2000000000" transferMode="Streamed">
<security mode="None" />
</binding>
my ajax client call is like this
var data = '{"image":"' + uri + '"}'
$.ajax({
url: GetServerUrl()+"images.svc/?file_key="+options.fileKey,
type: "POST",
contentType: "application/json",
data: data,
success: function (result) {
console.log("SUCCESS");
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("error in transfer::" + jqXHR.responceText);
}
});

I can't comment on the server-side code, but client-side :
the data variable should be a plain javascript object, not a JSON representation
url shouldn't need the GetServerUrl() prefix; try a leading "/" instead
for a POST request it's more normal to include all parameters in the data object rather than tacking them onto the URL, which is the GET approach. It depends what the server-side code is set up to expect but as far as I can tell, it expects file_key to be in the POST.
You should end up with something like this :
var data = {
image: uri,
file_key: options.fileKey
};
$.ajax({
url: "/images.svc/",//probably
type: "POST",
contentType: "application/json",
data: data,
success: function (result) {
console.log("SUCCESS");
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("errror in transfer::" + jqXHR.responceText);
}
});

Install Fiddler ( www.telerik.com/fiddler ). Launch it. Make the web service call. Click on the record of the call in Fiddler. Click on the 'Raw' tabs for request and response. It will be enlightening and you will see exactly what is passed between server and client. Perhaps some addition WCF troubleshooting data as well in the response.
Also, don't forget to check your Application event log on the machine running the WCF service. You can also add a Global.asax to the WCF project (if its a web project) and put logging code in the Application_Error method. Something like this:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is ThreadAbortException)
{
// Nothing to do here. The thread abended.
}
else
{
activityMgr.Add(System.Reflection.MethodBase.GetCurrentMethod(), ex);
}
}

Related

Error connecting to WCF Service c#

I'm developing a SOAP software for a customer. We are migrating to SOAP because we'll do a mobile app soon.
I alread did the .svc file and connects with IE. But, if I try to connect with Firefox, Opera, GC or any other browser, it says "Method not allowed".
I alread tried to insert a header on AJAX/JSON to allow 'Access-Control-Allow-Origin'. I also insert on server side, on the interface the webinvoke header, and nothing works.
This is my first question on stack overflow, so I do not know how asking works.
Thanks to all!
Header Code of AJAX/JSON:
function SendToService(urlSvc, objDTO) {
var bk = null;
var item = {
info: objDTO
};
$.ajax({
url: urlSvc,
type: 'POST',
data: JSON.stringify(item),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
async: false,
headers: {
'Access-Control-Allow-Origin': 'http://localhost:16587',
},
success: function (msg) {
bk = msg.d;
},
error: function (msg) {
bk = false;
}
});
return bk;
};
It looks like your method doesn't allow POST requests. Try allowing for POST on the destination method or test by changing your ajax request to GET instead. If the GET succeeds, you know where your problem is.

WCF Rest with PUT method on calling from client side changes to GET method in header request and fails to perform operation

I have a Restfull WCF service running.
All the operation works perfect and tested.
But when I try to call one of the PUT operation from client side using jquery JSON the header request changes to GET() method though I have mentioned PUT as method.
Tested on fiddler same 405 method not allowed error.
I know as it is a PUT method we can not apply GET but on client side if I use PUT() it automatically changes to GET in header request and fails.
Why it is happening can't get to fix it.Any help or ideas?
My client code for service request is as follows:
function UpdateRating(radioValue) {
jQuery.support.cors = true;
var star = (Math.floor(radioValue * 2) / 10).toFixed(2);
$.ajax({
type: "PUT",
url: ServiceURL + "xxx.svc/xml/updatescoreforvideo?vid=" + videoId + "&uid=" + userId + "&score=" + star,
data: "{}",
contentType: "application/json; charset=utf-8",
async: false,
dataType: "jsonp",
success: function (data, status, jqXHR) {
alert("you rated : "+ star + "star");//show alert on success //test
},
error: function () {
alert('Service call error occured');
}
});
}
My fiddler /firebug error reports :

How to make a proper authentication with an ASHX Handler

I am using ASP.NET's generic handler (ASHX files) to make server-side pages that can return data to mobile apps and so on. Some of this data is ment to be private. I am using JSON & the POST method as of now.
However, anyone with access to a client-side code (for example the code of the Mobile App), would be able to see what keywords he has to send to the "unpredictable" URL in order to make changes or get data.
I've been doing research for hours and couldn't find a proper way to authenticate that the one sending the JSON request is indeed an approved mobile app.
Example of sending a request to the server with AJAX:
function login()
{
var jsonParam = { name: "test", aname: "secret", pass: "1234", type: "login" }
$.ajax({
url: "AppDatabase.ashx",
type: "post",
data: JSON.stringify(jsonParam),
dataType: "json",
contentType: 'application/json; charset=utf-8',
async:false,
success: function (response) {
alert(response.userEmail);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus + "\r\n" + "Error: " + errorThrown);
}
});
}
Example of receiving the request on the server side:
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "application/json";
JavaScriptSerializer jss = new JavaScriptSerializer();
context.Request.InputStream.Position = 0;
string json;
using (var reader = new StreamReader(context.Request.InputStream))
{
json = reader.ReadToEnd();
}
Dictionary<string, object> dict = jss.Deserialize<Dictionary<string, object>>(json);
if(dict["aname"].ToString() == "secret")
{
// The best security I have right now is a "secret keyword" within the request
}
}
Your current way is very dangerous.
You can use another page that needs username & password to authenticate (for ex. using Session) and then let client to request your ashx file and your ashx should check Session for authentication.
Just a thought:
Are clients (e.g. mobile app) "yours" or is this meant to be some sort of API (for x clients)?
Either way, maybe worth looking into JWT? The idea is that the "payload" (data) is signed (e.g. HMAC SHA-256) and has protections against "replays".
This way, you're not just looking to the auth part - re: both ends need to verify the data so both can ensure such data came from the "right origin" and is (still) valid.
Hth...

WCF webservice is not returning the correct status code when the response header is modified

I have a very simple WCF web service which I call on the client side using Ajax:
Here is my web service:
public string TestService() {
throw new Exception();
return "";
}
Here is what my client side Ajax call looks like:
var mySuccess = function(result,statuscode,xhr){
alert('success');
}
var myFail = function(result,statuscode,xhr){
alert('failure');
}
$.ajax({
type: 'Post'
contentType: "application/json; charset=utf-8",
url: '../myService.svc/TestService',
data: '',
dataType: "json",
success: mySuccess,
error: myFail
});
This web service fails every time (as it should!), returning a status and code of '500: internal server error'. The 'myFail' callback function is fired as it should.
However, if I modify the response header within my web service, like so:
public string TestService() {
WebOperationContext.Current.OutgoingResponse.Headers.Add("token", "1");
throw new Exception();
return "";
}
then the status/code returned is '200: OK', every time!
This means that the 'mySuccess' function is fired every time, even when the web service should be failing. I can't figure out why simply adding my own custom header to the response would overwrite the return status in this way.
Is there something I am missing?
An option would be to throw a WebFaultException with a meaningful HTTP status and message.
Example: throw new WebFaultException("Invalid request received.", HttpStatusCode.BadRequest);BadReuqest code is 400.

asp.net pass sender to server with jquery

I want to call a C# function in my aspx.cs file with jQuery. The function looks like:
protected void Fill(object sender, EventArgs e) { ...do s.th. with sender... }
in the function im getting my control I want to work with by doing a cast on the sender. How to pass the sender to server with jquery?
Check this : Implementing Client Callbacks Programmatically Without Postbacks in ASP.NET Web Pages
OR
Hi you can check this article : http://pranayamr.blogspot.com/2012/01/calling-server-side-function-from.html which dicuss about calling server method with the jQuery function.
cs file i.e serverside code
[WebMethod]
public static string IsExists(string value)
{ return "True"; }
Client script
function IsExists(pagePath, dataString, textboxid, errorlableid) {
//alert(pagePath);
$.ajax({
type: "POST",
url: pagePath,
data: dataString,
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function(XMLHttpRequest, textStatus, errorThrown) {
$(errorlableid).show();
$(errorlableid).html("Error");
},
success:
function(result) {
var flg = true;
if (result != null) {
debugger;
flg = result.d;
if (flg == "True") {
$(errorlableid).show();
}
else {
$(errorlableid).hide();
}
}
}
});
}
function focuslost() {
var pagePath = window.location.pathname + "/IsExists";
var dataString = "{ 'value':'" + $("#<%= txtData.ClientID%>").val() + "' }";
var textboxid = "#<%= txtData.ClientID%>";
var errorlableid = "#<%= lblError.ClientID%>";
IsExists(pagePath, dataString, textboxid, errorlableid);
}
You can't call functions just like that with jQuery. jQuery is a client scripting technology based on javascript that runs on the client browser. It doesn't know what ASP.NET is. It even less knows what a server side, ASP.NET code behind method is.
This being said, you could send an AJAX request to a server side script which in your case could be either a generic handler (.ASHX) or an .ASPX page. In this second case you could use Page Methods.

Categories

Resources