I have a situation where I am accessing an ASP.NET Generic Handler to load data using JQuery. But since data loaded from JavaScript is not visible to the search engine crawlers, I decided to load data from C# and then cache it for JQuery. My handler contains a lot of logic that I don't want to apply again on code behind. Here is my Handler code:
public void ProcessRequest(HttpContext context)
{
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
string jsonString = string.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new System.IO.StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
}
ContentType contentType = jsonSerializer.Deserialize<ContentType>(jsonString);
context.Response.ContentType = "text/plain";
switch (contentType.typeOfContent)
{
case 1: context.Response.Write(getUserControlMarkup("SideContent", context, contentType.UCArgs));
break;
}
}
I can call the function getUserControlMarkup() from C# but I will have to apply some URL based conditions while calling it. The contentType.typeOfContent is actually based on URL parameters.
If possible to send JSON data to this handler then please tell me how to do that. I am trying to access the handler like this:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Common.host + "Handlers/SideContentLoader.ashx?typeOfContent=1&UCArgs=cdata");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
But its giving NullReferenceException in Handler code at line:
ContentType contentType = jsonSerializer.Deserialize<ContentType>(jsonString);
A nice way of doing it is to use Routing.
In the Global.asax
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
private void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpHandlerRoute("MyRouteName", "Something/GetData/{par1}/{par2}/data.json", "~/MyHandler.ashx");
}
This is telling ASP.Net to call your handler on /Something/GetData/XXX/YYY/data.json.
You can can access Route Parameters in the handler:
context.Request.RequestContext.RouteData.Values["par1"].
The crawler will parse URLs as long as they are referenced somewhere (i.e. robots file or links)
Not sure why you want to do it, but to add a content to an HTTP request use:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Common.host + "Handlers/SideContentLoader.ashx?typeOfContent=1&UCArgs=cdata");
var requestStream = request.GetRequestStream();
using (var sw = new StreamWriter(requestStream))
{
sw.Write(json);
}
Your Problem is
Load Content into Div using Javascript in ASP.NET using C#.
Visible to Search Engines
My Opinion
When You want Update Partial Page there are some handler or service to communicate between server and client You can Using Ajax for Request to server.
if you use jquery you can try this function jQuery.ajax(); example:
$.ajax({
url:"/webserver.aspx",
data:{id:1},
type:'POST',
success: function(data) {
//do it success function
}
}) ;
Next Step is Generate Web Service in Code behind Your ASP.NET that should be result as JSON or XML format, whatever you use make sure you can parse easily in success function of jQuery.ajax();
Here some Reference for Generate Web Service on ASP.NET
Generate JSON Web Service ASP.NET
Parse Json on Code Behind Parse JSON Code Behind
Generate JSON RESULT and Parse using Client Side Javascript Web Services ASP.NET Json
2.Visible to Search Engine actually
I think if You allow Search engine to Index your page it's no problem , Even if You have some Ajax Code , Search engine will be indexing your page.
I've found this article, I believe this will help you.
http://www.overpie.com/aspnet/articles/csharp-post-json-to-generic-handler
Related
In an application I am developing RESTful API and we want the client to send data as JSON. Part of this application requires the client to upload a file (usually an image) as well as information about the image.
I'm having a hard time tracking down how this happens in a single request. Is it possible to Base64 the file data into a JSON string? Am I going to need to perform 2 posts to the server? Should I not be using JSON for this?
As a side note, we're using Grails on the backend and these services are accessed by native mobile clients (iPhone, Android, etc), if any of that makes a difference.
I asked a similar question here:
How do I upload a file with metadata using a REST web service?
You basically have three choices:
Base64 encode the file, at the expense of increasing the data size by around 33%, and add processing overhead in both the server and the client for encoding/decoding.
Send the file first in a multipart/form-data POST, and return an ID to the client. The client then sends the metadata with the ID, and the server re-associates the file and the metadata.
Send the metadata first, and return an ID to the client. The client then sends the file with the ID, and the server re-associates the file and the metadata.
You can send the file and data over in one request using the multipart/form-data content type:
In many applications, it is possible for a user to be presented with
a form. The user will fill out the form, including information that
is typed, generated by user input, or included from files that the
user has selected. When the form is filled out, the data from the
form is sent from the user to the receiving application.
The definition of MultiPart/Form-Data is derived from one of those
applications...
From http://www.faqs.org/rfcs/rfc2388.html:
"multipart/form-data" contains a series of parts. Each part is
expected to contain a content-disposition header [RFC 2183] where the
disposition type is "form-data", and where the disposition contains
an (additional) parameter of "name", where the value of that
parameter is the original field name in the form. For example, a part
might contain a header:
Content-Disposition: form-data; name="user"
with the value corresponding to the entry of the "user" field.
You can include file information or field information within each section between boundaries. I've successfully implemented a RESTful service that required the user to submit both data and a form, and multipart/form-data worked perfectly. The service was built using Java/Spring, and the client was using C#, so unfortunately I don't have any Grails examples to give you concerning how to set up the service. You don't need to use JSON in this case since each "form-data" section provides you a place to specify the name of the parameter and its value.
The good thing about using multipart/form-data is that you're using HTTP-defined headers, so you're sticking with the REST philosophy of using existing HTTP tools to create your service.
I know that this thread is quite old, however, I am missing here one option. If you have metadata (in any format) that you want to send along with the data to upload, you can make a single multipart/related request.
The Multipart/Related media type is intended for compound objects consisting of several inter-related body parts.
You can check RFC 2387 specification for more in-depth details.
Basically each part of such a request can have content with different type and all parts are somehow related (e.g. an image and it metadata). The parts are identified by a boundary string, and the final boundary string is followed by two hyphens.
Example:
POST /upload HTTP/1.1
Host: www.hostname.com
Content-Type: multipart/related; boundary=xyz
Content-Length: [actual-content-length]
--xyz
Content-Type: application/json; charset=UTF-8
{
"name": "Sample image",
"desc": "...",
...
}
--xyz
Content-Type: image/jpeg
[image data]
[image data]
[image data]
...
--foo_bar_baz--
Here is my approach API (i use example) - as you can see, you I don't use any file_id (uploaded file identifier to the server) in API:
Create photo object on server:
POST: /projects/{project_id}/photos
body: { name: "some_schema.jpg", comment: "blah"}
response: photo_id
Upload file (note that file is in singular form because it is only one per photo):
POST: /projects/{project_id}/photos/{photo_id}/file
body: file to upload
response: -
And then for instance:
Read photos list
GET: /projects/{project_id}/photos
response: [ photo, photo, photo, ... ] (array of objects)
Read some photo details
GET: /projects/{project_id}/photos/{photo_id}
response: { id: 666, name: 'some_schema.jpg', comment:'blah'} (photo object)
Read photo file
GET: /projects/{project_id}/photos/{photo_id}/file
response: file content
So the conclusion is that, first you create an object (photo) by POST, and then you send second request with the file (again POST). To not have problems with CACHE in this approach we assume that we can only delete old photos and add new - no update binary photo files (because new binary file is in fact... NEW photo). However if you need to be able to update binary files and cache them, then in point 4 return also fileId and change 5 to GET: /projects/{project_id}/photos/{photo_id}/files/{fileId}.
I know this question is old, but in the last days I had searched whole web to solution this same question. I have grails REST webservices and iPhone Client that send pictures, title and description.
I don't know if my approach is the best, but is so easy and simple.
I take a picture using the UIImagePickerController and send to server the NSData using the header tags of request to send the picture's data.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"myServerAddress"]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:UIImageJPEGRepresentation(picture, 0.5)];
[request setValue:#"image/jpeg" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"myPhotoTitle" forHTTPHeaderField:#"Photo-Title"];
[request setValue:#"myPhotoDescription" forHTTPHeaderField:#"Photo-Description"];
NSURLResponse *response;
NSError *error;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
At the server side, I receive the photo using the code:
InputStream is = request.inputStream
def receivedPhotoFile = (IOUtils.toByteArray(is))
def photo = new Photo()
photo.photoFile = receivedPhotoFile //photoFile is a transient attribute
photo.title = request.getHeader("Photo-Title")
photo.description = request.getHeader("Photo-Description")
photo.imageURL = "temp"
if (photo.save()) {
File saveLocation = grailsAttributes.getApplicationContext().getResource(File.separator + "images").getFile()
saveLocation.mkdirs()
File tempFile = File.createTempFile("photo", ".jpg", saveLocation)
photo.imageURL = saveLocation.getName() + "/" + tempFile.getName()
tempFile.append(photo.photoFile);
} else {
println("Error")
}
I don't know if I have problems in future, but now is working fine in production environment.
FormData Objects: Upload Files Using Ajax
XMLHttpRequest Level 2 adds support for the new FormData interface.
FormData objects provide a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest send() method.
function AjaxFileUpload() {
var file = document.getElementById("files");
//var file = fileInput;
var fd = new FormData();
fd.append("imageFileData", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", '/ws/fileUpload.do');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert('success');
}
else if (uploadResult == 'success')
alert('error');
};
xhr.send(fd);
}
https://developer.mozilla.org/en-US/docs/Web/API/FormData
Since the only missing example is the ANDROID example, I'll add it.
This technique uses a custom AsyncTask that should be declared inside your Activity class.
private class UploadFile extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
// set a status bar or show a dialog to the user here
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
// progress[0] is the current status (e.g. 10%)
// here you can update the user interface with the current status
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
private String uploadFile() {
String responseString = null;
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://example.com/upload-file");
try {
AndroidMultiPartEntity ampEntity = new AndroidMultiPartEntity(
new ProgressListener() {
#Override
public void transferred(long num) {
// this trigger the progressUpdate event
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
File myFile = new File("/my/image/path/example.jpg");
ampEntity.addPart("fileFieldName", new FileBody(myFile));
totalSize = ampEntity.getContentLength();
httpPost.setEntity(ampEntity);
// Making server call
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
responseString = EntityUtils.toString(httpEntity);
} else {
responseString = "Error, http status: "
+ statusCode;
}
} catch (Exception e) {
responseString = e.getMessage();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
// if you want update the user interface with upload result
super.onPostExecute(result);
}
}
So, when you want to upload your file just call:
new UploadFile().execute();
I wanted send some strings to backend server. I didnt use json with multipart, I have used request params.
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public void uploadFile(HttpServletRequest request,
HttpServletResponse response, #RequestParam("uuid") String uuid,
#RequestParam("type") DocType type,
#RequestParam("file") MultipartFile uploadfile)
Url would look like
http://localhost:8080/file/upload?uuid=46f073d0&type=PASSPORT
I am passing two params (uuid and type) along with file upload.
Hope this will help who don't have the complex json data to send.
You could try using https://square.github.io/okhttp/ library.
You can set the request body to multipart and then add the file and json objects separately like so:
MultipartBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uploadFile", uploadFile.getName(), okhttp3.RequestBody.create(uploadFile, MediaType.parse("image/png")))
.addFormDataPart("file metadata", json)
.build();
Request request = new Request.Builder()
.url("https://uploadurl.com/uploadFile")
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
logger.info(response.body().string());
#RequestMapping(value = "/uploadImageJson", method = RequestMethod.POST)
public #ResponseBody Object jsongStrImage(#RequestParam(value="image") MultipartFile image, #RequestParam String jsonStr) {
-- use com.fasterxml.jackson.databind.ObjectMapper convert Json String to Object
}
Please ensure that you have following import. Ofcourse other standard imports
import org.springframework.core.io.FileSystemResource
void uploadzipFiles(String token) {
RestBuilder rest = new RestBuilder(connectTimeout:10000, readTimeout:20000)
def zipFile = new File("testdata.zip")
def Id = "001G00000"
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>()
form.add("id", id)
form.add('file',new FileSystemResource(zipFile))
def urld ='''http://URL''';
def resp = rest.post(urld) {
header('X-Auth-Token', clientSecret)
contentType "multipart/form-data"
body(form)
}
println "resp::"+resp
println "resp::"+resp.text
println "resp::"+resp.headers
println "resp::"+resp.body
println "resp::"+resp.status
}
As soon as my page loads I would like to make a web request so that its response can be accessed via JavaScript. I have written a c# class that makes the requests to the server. This class is invoked by a controller in my MVC application. I can confirm that the client class is functioning properly & returns a string representation of the JSON.
My question is this. How should I call the controller so that I can use the response in my javascript? The #http.Action simply returns a txt file containing the html of the whole page with the response in the place that i make the call. I would like to instead store this as a variable and maintaining the initial Index view..
Code Bellow has been modified to only include essentials.
Controller
public ActionResult getMeterConfig () {
string scheme = "http";
string host = "*****";
int port = ****;
string dataset = "*****";
string db = "****";
string method = "GET";
var request = new client();
request.setProps(scheme, host, port, dataset, db, method);
request.makeRequest();
var response = request.getResponse();
return Json (response,JsonRequestBehavior.AllowGet);
}
Then to call the controller on page load:
$(window).load(function(){
var json = #Html.Action("actionName","contollerName";
});
EDIT For Clarification
Ive changed the javascript to be :
$(window).load(function () {
$.get('#Html.Action("getMeterConfig", "GetMeterConfig")', function (response) {
var meters = response;
});
});
This returns a download entitled Index.json rather than store the response in the variable meters.
To make this even more peculiar the .json document reads as follows... It includes my index view HTML and substitutes the #Html.Action("getMeterConfig", "GetMeterConfig") with the actual response.
You would make an AJAX request to that controller action. Assuming jQuery, since ASP.NET MVC comes with it:
$(window).load(function(){
$.get('#Url.Action("getMeterConfig", "contollerName")', function (response) {
var json = response;
});
});
So when your client-side page loads, that client-side code would make a separate request to this getMeterConfig action. The JSON returned by that request would be available in the callback function. (I named the variable response but you can call it whatever you like.)
Hi am working on a windows application in which i have to call a aspx page which read values from database and convert it into an XML.I have no clue how to call a aspx page and make it return a value to the calling windows application.I tried using Web request method it doesnot return anything.Please suggest me a idea how to do this
You can use WebClient, something like this :
this is a sitemap XML generated by HttpModule that intercepts requests for XML files:
WebClient wc = new WebClient();
string smap = wc.DownloadString("http://www.antoniob.com/sitemap.xml");
And this is a theoretical aspx that returns XML
WebClient wc = new WebClient();
string smap = wc.DownloadString("http://www.somesite.com/GetXml.ashx");
There is no difference in the call, except of course in address
On Server side (asp.net app), it would be better to use ASHX handler since is more suited for returning XML, In your ASP.NET application add new item, and choose generic handler :
and here is the code for GetXml.ashx handler that will return sample XML from App_Data folder :
public class GetXml : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/xml";
string xml = File.ReadAllText(context.Server.MapPath("~/App_Data/sample.xml"));
context.Response.Write(xml);
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
I'm trying to handle a JSONP request server side for a form submission ie.
var myJSONP = new Request.JSONP({
url: 'http://mysite.../handlers/FormHandler.ashx',
callbackKey: 'jsoncallback',
data: {
partTag: 'mtvo',
iod: 'hlPrice',
viewType: 'json',
results: '100',
query: 'ipod'
},
onRequest: function(url){
// etc
},
onComplete: function(data){
// etc
}
}).send();
public class FormHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string json = ??
JObject j = JObject.Parse(json);
context.Response.ContentType = "text/json";
context.Response.Write("Hello World");
}
I'm not sure how to deserialize in the ashx ie. I use Json.Net but how to get from context
Do I have to use context.Request to retrieve values individually or can I decode directly from context?
thanks
I am not sure which JSONP you are using, but using MooTools Request.JSON, the data is delivered in context.Request.Form:
?context.Request.Form.ToString()
"partTag=mtvo&iod=hlPrice&viewType=json&results=100&query=ipod"
So you can access each of the form elements in code:
?context.Request.Form["partTag"]
"mtvo"
Based on this, I believe that you will have to assemble the object yourself using the form elements.
To answer your question, yes, you need to use Context.Request to read the data from your client side.
BTW. if you can use RESTful web service instead of implement your own http handler, it will be much easier, RESTful web service which JSON serialize and deserialize is handled by the WCF framework.
I'm trying to test web service calls using an ASP.NET page that creates a form with username and password fields and a "Submit" button. (Both jQuery and the .js file I'm using are included in script tags in the head element.)
The "Submit" button calls a function created in the C# code behind file that makes a call to a separate JavaScript file.
protected void mSubmit_Click(object sender, EventArgs eventArgs)
{
String authenticate = String.Format("Authentication(\"{0}\",\"{1}\");", this.mUsername.Text,this.mPassword.Text);
Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", authenticate, true);
}
The JavaScript function, Authenticate, makes web service call, using jQuery and Ajax, to a different server, sending JSON parameters and expecting back JSON in response.
function Authentication(uname, pwd) {
//gets search parameters and puts them in json format
var params = '{"Header":{"AuthToken":null,"ProductID":"NOR","SessToken":null,"Version":1},"ReturnAuthentication":true,"Password":"' + pwd + '","Username":"' + uname + '",ā€¯ReturnCredentialsā€¯:false }';
var xmlhttp = $.ajax({
async: false,
type: "POST",
url: 'https://myHost.com/V1/Identity/Authenticate',
data: params,
contentType: 'application/json'
});
alert(xmlhttp.statusText);
alert(xmlhttp.responseText);
return;
}
However, because the web service I'm calling is on a different server than the ASP.NET, C# and JavaScript files, I'm not getting a statusText or responseText alert.
Somehow, nothing is being sent to the web service and I'm not getting anything back, not even an error. I tried putting a function in the beforeSend attribute, but that didn't fire. Is there a special way I need to handle calling an off-server web service?
UPDATE!
At the advice of jjnguy, Janie and Nathan, I'm now trying a server side call to the web service using HttpWebRequest. Using some of jjnguy's code as well as code from this question, I've come up with this.
public static void Authenticate(string pwd, string uname)
{
string ret = null;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://myhost.com/V1/Identity/Authenticate");
request.ContentType = "application/json";
request.Method = "POST";
string data = "{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":false }'";
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
request.ContentLength = byteData.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (response)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
ret = reader.ReadToEnd();
}
Console.WriteLine(ret);
}
However, I'm getting a (400) Bad Request error from the remote server when I try to get the response from my HttpWebRequest. The value of the Response property of the exception says {System.Net.HttpWebResponse} and the value of the Status property is ProtocolError. I'm pretty sure this is because the URL is using HTTP SSL protocol. What can I do to get around that, other than having the ASP.NET page URL start with HTTPS (not an option)?
Turns out the code that I posted in my update was correct, I just had a typo and one setting incorrect in the data string.
string data = "{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":true}";
For simplicity's sake, why don't you write the call to the webservice in C# on the Server Side?
You have the same abilities to send requests and get responses in C# as you do with Javascript.
Here is a crack at your function in C#:
public static string Authenticate(string pwd, string uname)
{
HttpWebRequest requestFile = (HttpWebRequest)WebRequest.Create("https://myHost.com/V1/Identity/Authenticate");
requestFile.ContentType = "application/json";
requestFile.Method = "POST";
StreamWriter postBody = new StreamWriter(requestFile.GetRequestStream())
using (postBody) {
postBody.Write("{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":false }'");
}
HttpWebResponse serverResponse = (HttpWebResponse)requestFile.GetResponse();
if (HttpStatusCode.OK != serverResponse.StatusCode)
throw new Exception("Url request failed. Connection to the server inturrupted");
StreamReader responseStream = new StreamReader(serverResponse.GetResponseStream());
string ret = null;
using (responseStream) {
ret = responseStream.ReadLine();
}
return ret;
}
Disclaimer This has not been tested.
Instead of using the client script to make the request from the server; use server side code to make the request
EDIT to expand answer:
From your web project in visual studio, click add web reference, and point to the service you were originally accessing via your client script: (I believe it was 'https://myHost.com/V1/Identity/Authenticate)
You can now talk to the service using c# code instead of js (and pass in the users provided credentials.)
Also, since the request against the service is coming from a server, rather than a browser; you bypass the cross-domain restrictions that apply.
FURTHER EDIT to show additional technique:
If you don't like the idea of using Visual Studio to generate a service proxy for you, then you can handcraft the request yourself using WebClient or HttpRequest
WebClient:
http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.80).aspx
HttpWebRequest:
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(VS.80).aspx
Seems like you're running into the same origin policy
http://en.wikipedia.org/wiki/Same_origin_policy
I believe there are ways to circumvent it, but I think the other posters are right. On the server, write methods that use a HttpWebRequest to call the web service, and then use JavaScriptSerializer to parse out the JSON. I spent most of the afternoon researching this cause I'll have to write something similar myself.
>>>> Nathan
P.S. I like #Janie's plan better... Can you do that with a web service that returns JSON as well as one that would pass back XML?