This question is specific to Asp.Net WebApi.
In my global file, I've put:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
JsonpMediaTypeFormatter is custom Jsonp formatter that I have.
After this, when i call,
function jsonpCallback(data) {
alert('in' + data);
var list = $('#courses');
for (var i = 0; i < data.length; i++) {
var course = data[i];
list.append('<li>' + course.name + '</li>');
}
}
$.getJSON("http://localhost:64009/api/courses?callback=?", null, jsonpCallback);
It worked.
But, from my global file, if I remove
GlobalConfiguration.Configuration.Formatters.Clear();
Then it doesn't work.
What if i want to support multiple formatters?
As I can use HttpClient for CORS and ask for xml or json or jsop?
Can someone please advice?
Related
I am able to initiate asynchronous uploads to S3, however they are somehow not ending up as a file inside my S3 bucket and I see an error 'WithPartETags cannot be empty'. Here is the complete code
InitiateMultipartUploadRequest initRequest =
new InitiateMultipartUploadRequest()
.WithBucketName(existingBucketName)
.WithKey(Path.Combine(S3Path + "/", finfo.Name));
InitiateMultipartUploadResponse initResponse =
s3Client.InitiateMultipartUpload(initRequest);
// 2. Upload Parts.
long contentLength = finfo.Length;
long partSize = 15728640;//52428800-50MB 104857600- 100 MB - 5242880 - 5 MB
try
{
long filePosition = 0;
for (int i = 1; filePosition < contentLength; i++)
{
// Create request to upload a part.
UploadPartRequest uploadRequest = new UploadPartRequest()
.WithBucketName(existingBucketName)
.WithKey(Path.Combine(S3Path + "/", finfo.Name))
.WithUploadId(initResponse.UploadId)
.WithPartNumber(i)
.WithPartSize(partSize)
.WithFilePosition(filePosition)
.WithFilePath(finfo.FullName);
// Upload part and add response to our list.
//uploadResponses.Add(s3Client.UploadPart(uploadRequest));
IAsyncResult ar = s3Client.BeginUploadPart(uploadRequest, null, null);
ListObj.Add(new ThreadList() { _iasyncResult = ar });
filePosition += partSize;
Console.WriteLine("Length Written - " + filePosition + " .Content Length - " + contentLength);
}
bool uploadsComplete = false;
while (!uploadsComplete)
{
bool individualuploadscomplete = true;
foreach (var obj in ListObj)
{
if (!obj._iasyncResult.IsCompleted)
{
individualuploadscomplete = false;
break;
}
}
if (individualuploadscomplete)
{
uploadsComplete = true;
}
}
foreach (var obj in ListObj)
{
s3Client.EndUploadPart(obj._iasyncResult);
}
//// Step 3: complete.
CompleteMultipartUploadRequest compRequest =
new CompleteMultipartUploadRequest()
.WithBucketName(existingBucketName)
.WithKey(Path.Combine(S3Path + "/", finfo.Name))
.WithUploadId(initResponse.UploadId);
//.WithPartETags(uploadResponses);
CompleteMultipartUploadResponse completeUploadResponse =
s3Client.CompleteMultipartUpload(compRequest);
Not sure why you have the setting of the PartETags commented out for the complete multipart upload call but you need to add that code back in. Also when you are calling the EndUploadPart method you need to capture that UploadResponse that comes back from that.
You also might want to look into the TransferUtility found in the Amazon.S3.Transfer namespace. Its upload methods are designed to handle what you are attempting to accomplish for large objects, see Using the High-Level .NET API for Multipart Upload for details and example snippets.
I've had several cases where I had a page with several query parameters - most recently a search results page - and needed to create a link to the same page with one or more query parameters changed in the URL. This seems like such a common use case that I feel as though there must be some simple built-in way of doing it.
Right now, I'm using a function I wrote which takes in a dictionary of parameters and values and merges them with the params and values from Request.QueryString. Parameters given with a null value are removed. It works, but I'm open to simpler methods.
Minor improvements I'd suggest:
//...
{
UriBuilder ub = new UriBuilder(Request.Url);
//...
ub.Query = string.Join("&", parameters.Select(kv => string.Format("{0}={1}", Server.UrlEncode(kv.Key), Server.UrlEncode(kv.Value))));
return ub.ToString();
}
Edit
Actually the return value should also be a Uri type but I didn't want to introduce any breaking changes.
The function I'm using now:
public string ThisPageWithParams(IDictionary<string, string> newParameters)
{
string url = Request.Url.AbsolutePath + "?";
var parameters = new Dictionary<string, string>();
foreach (string k in Request.QueryString)
{
parameters[k] = Request.QueryString[k];
}
foreach (var kv in newParameters)
{
if (newParameters[kv.Key] == null)
{
parameters.Remove(kv.Key);
}
else
{
parameters[kv.Key] = kv.Value;
}
}
url += string.Join("&", parameters.Select(kv => Server.UrlEncode(kv.Key) + "=" + Server.UrlEncode(kv.Value)));
return url;
}
I'm trying to port an existing AJAX app to Flex, and having trouble with the encoding of parameters sent to the backend service.
When trying to perform the action of deleting a contact, the existing app performs a POST, sending the the following: (captured with firebug)
contactRequest.contacts[0].contactId=2c33ddc6012a100096326b40a501ec72
So, I create the following code:
var service:HTTPService;
function initalizeService():void
{
service = new HTTPService();
service.url = "http://someservice";
service.method = 'POST';
}
public function sendReq():void
{
var params:Object = new Object();
params['contactRequest.contacts[0].contactId'] = '2c33ddc6012a100097876b40a501ec72';
service.send(params);
}
In firebug, I see this sent out as follows:
Content-type: application/x-www-form-urlencoded
Content-length: 77
contactRequest%2Econtacts%5B0%5D%2EcontactId=2c33ddc6012a100097876b40a501ec72
Flex is URL encoding the params before sending them, and we're getting an error returned from the server.
How do I disable this encoding, and get the params sent as-is, without the URL encoding?
I feel like the contentType property should be the key - but neither of the defined values work.
Also, I've considered writing a SerializationFilter, but this seems like overkill - is there a simpler way?
Writing a SerializtionFilter seemed to do the trick:
public class MyFilter extends SerializationFilter
{
public function MyFilter()
{
super();
}
override public function serializeBody(operation:AbstractOperation, obj:Object):Object
{
var s:String = "";
var classinfo:Object = ObjectUtil.getClassInfo(obj);
for each (var p:* in classinfo.properties)
{
var val:* = obj[p];
if (val != null)
{
if (s.length > 0)
s += "&";
s += StringUtil.substitute("{0}={1}",p,val);
}
}
return s;
}
}
I'd love to know any alternative solutions that don't involve doing this though!
I am calling a web Method from javascript. The web method returns an array of customers from the northwind database. The example I am working from is here: Calling Web Services with ASP.NET AJAX
I dont know how to write this javascript method: CreateCustomersTable
This would create the html table to display the data being returned. Any help would be appreciated.
My javascript
function GetCustomerByCountry() {
var country = $get("txtCountry").value;
AjaxWebService.GetCustomersByCountry(country, OnWSRequestComplete, OnWSRequestFailed);
}
function OnWSRequestComplete(results) {
if (results != null) {
CreateCustomersTable(results);
//GetMap(results);
}
}
function CreateCustomersTable(result) {
alert(result);
if (document.all) //Filter for IE DOM since other browsers are limited
{
// How do I do this?
}
}
else {
$get("divOutput").innerHTML = "RSS only available in IE5+"; }
}
My web Method
[WebMethod]
public Customer[] GetCustomersByCountry(string country)
{
NorthwindDALTableAdapters.CustomersTableAdapter adap =
new NorthwindDALTableAdapters.CustomersTableAdapter();
NorthwindDAL.CustomersDataTable dt = adap.GetCustomersByCountry(country);
if (dt.Rows.Count <= 0)
{
return null;
}
Customer[] customers = new Customer[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
NorthwindDAL.CustomersRow row = (NorthwindDAL.CustomersRow)dt.Rows[i];
customers[i] = new Customer();
customers[i].CustomerId = row.CustomerID;
customers[i].Name = row.ContactName;
}
return customers;
}
Try to look what is the result variable value in debug mode. If the structure seems the structure that i'm imagining, something like this could work:
function CreateCustomersTable(result) {
var str = '<table>';
str += '<tr><th>Id</th><th>Name</th></tr>';
for ( var i=0; i< result.length; i++){
str += '<tr><td>' + result[i].CustomerId + '</td><td>' + result[i].Name + '</td></tr>';
}
str += '</table>';
return str;
}
And then You can do somethig like this:
var existingDiv = document.getElementById('Id of an existing Div');
existingDiv.innerHTML = CreateCustomersTable(result);
I wish this help you.
Something like this, assuming you have JSON returned in the "result" value. The "container" is a div with id of "container". I'm cloning nodes to save memory, but also if you wanted to assign some base classes to the "base" elements.
var table = document.createElement('table');
var baseRow = document.createElement('tr');
var baseCell = document.createElement('td');
var container = document.getElementById('container');
for(var i = 0; i < results.length; i++){
//Create a new row
var myRow = baseRow.cloneNode(false);
//Create a new cell, you could loop this for multiple cells
var myCell = baseCell.cloneNode(false);
myCell.innerHTML = result.value;
//Append new cell
myRow.appendChild(myCell);
//Append new row
table.appendChild(myRow);
}
container.appendChild(table);
You should pass the array as JSON or XML instead of just the toString() value of it (unless that offcourse is returns either JSON oR XML). Note that JSOn is better for javascript since it is a javascript native format.
Also the person who told you that browser other then IE can not do DOM manipulation should propably have done horrible things to him/her.
If your format is JSON you can just for-loop them and create the elements and print them. (once you figured out what format your service returns we can help you better.)
How do I create an ASP.NET web service that returns JSON formatted data?
The most important thing to understand is to know how to represent data in JSON format.
Please refer http://www.json.org/ to know more about it.
Once you understand this, then the rest part is pretty straight forward.
Please check the following URL for an example of the same.
http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=264
http://code.msdn.microsoft.com/JSONSampleDotNet
http://www.phdcc.com/xml2json.htm
I recommend Jquery library for this. It's a lightweight rich library which supports calling web services, handle json data format output etc.
Refer www.jquery.com for more info.
.NET 3.5 has support built-in. For .NET 2.0, extra libraries are needed. I used the Jayrock library.
I recently delivered an application that uses pure Javascript at the browser (viz. using AJAX technology, but not using Microsoft AJAX or Scriptaculous etc) which marries up to Microsoft webservices at the back end. When I started writing this I was new to the world of .NET, and felt overwhelmed by all the frameworks out there! So I had an urge to use a collection of small libraries rather than very large frameworks.
At the javascript application, I call a web service like this. It directly reads the output of the web service, cuts away the non JSON sections, then uses https://github.com/douglascrockford/JSON-js/blob/master/json2.js to parse the JSON object.
This is not a standard approach, but is quite simple to understand, and may be of value to you, either to use or just to learn about webservices and JSON.
// enclosing html page has loaded this:
<script type="text/javascript" src="res/js/json2.js"></script>
// Invoke like this:
// var validObj = = callAnyWebservice("WebServiceName", "");
// if (!validObj || validObj.returnCode != 0) {
// alert("Document number " + DocId + " is not in the vPage database. Cannot continue.");
// DocId = null;
// }
function callAnyWebservice(webserviceName, params) {
var base = document.location.href;
if (base.indexOf(globals.testingIPaddr) < 0) return;
gDocPagesObject=null;
var http = new XMLHttpRequest();
var url = "http://mywebserver/appdir/WebServices.asmx/" + webserviceName;
//alert(url + " " + params);
http.open("POST", url, false);
http.setRequestHeader("Host", globals.testingIPaddr);
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http.setRequestHeader("Content-Length", params.length);
// http.setRequestHeader("Connection", "close");
//Call a function when the state changes.
http.onreadystatechange = function() {
if (http.readyState == 4 ) {
if (http.status == 200) {
var JSON_text = http.responseText;
var firstCurlyQuote = JSON_text.indexOf('{');
JSON_text = JSON_text.substr(firstCurlyQuote);
var lastCurlyQuote = JSON_text.lastIndexOf('}') + 1;
JSON_text = JSON_text.substr(0, lastCurlyQuote);
if (JSON_text!="")
{
//if (DEBUG)
// alert(url+" " +JSON_text);
gDocPagesObject = eval("(" + JSON_text + ")");
}
}
else if (http.readyState == 4)
{alert(http.readyState + " " + http.status + " " + http.responseText)}
}
}
http.send(params);
if (gDocPagesObject != null) {
//alert(gDocPagesObject.returnCode + " " + gDocPagesObject.returnString);
return gDocPagesObject;
}
else
return "web service unavailable: data not ready";
}
In our project the requirements were as follow -- ASP.NET 2.0 on the server, and pure Javascript on the browser (no JQuery libs, or .NET AJAX)
In that case on the server side, just mark the webmethod to use JSON. Note that both input and output params are json formatted
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public String Foo(String p1, String p2)
{
return "Result: p1= " + p1 + " p2= " + p2;
}
On the javascript side, use the regular XmlHttpRequest object, make sure you format your input params as JSON and do an 'eval' on output parms.
var httpobj = getXmlHttpRequestObject();
//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject()
{
if (window.XMLHttpRequest)
return new XMLHttpRequest();
else if(window.ActiveXObject)
return new ActiveXObject("Microsoft.XMLHTTP");
}
CallService()
{
//Set the JSON formatted input params
var param = "{'p1' : 'value1', 'p2' : 'value2'}";
//Send it to webservice
if(httpobj.readyState == 4 || httpobj.readyState == 0)
{
httpobj.open("POST", 'service.asmx/' + 'Foo', true);
//Mark the request as JSON and UTF-8
httpobj.setRequestHeader('Content-Type','application/json; charset=utf-8');
httpobj.onreadystatechange = OnSuccess;
httpobj.send(param);
}
}
OnSuccess()
{
if (httpobj.readyState == 4)
{
//Retrieve the JSON return param
var response = eval("(" + httpobj.responseText + ")");
}
}