public boolean setContacts(String name, String number) {
serviceUrl = "http://...../sample.php?method=setcontacts";
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("name", name));
nameValuePairs.add(new BasicNameValuePair("num", number));
try {
httpClient = new DefaultHttpClient();
httpPost = new HttpPost(serviceUrl);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse httpResponse = httpClient.execute(httpPost);
..................
}
In this code i sending a single row having name and number to server its working fine,
but i want to send a list of name and number like
ArrayList<Strng[]> contactsList =...............;
so how i can implement this
public boolean setContacts(ArrayList<String[]> contactsList) {
}
if you have any alternative way please suggest me thanks in advance.
Serialize the information as a string and send it in the POST body. There are many ways to skin this cat, but the big 3 are:
Form encoding
XML
JSON
Related
Dear all i have the following controller,
[Route("[action]/{phone}/{password}", Name="PhoneLogin")]
[HttpGet]
public async Task<ActionResult<User>> PhoneLogin(string phone, string password)
{
var response = await _repository.PhoneLogin(phone, password);
if (response == null) { return NotFound(); }
return Ok(_mapper.Map<UserReadDto>(response));
}
public async Task<User> PhoneLogin(string phone, string pass)
{
StringCipher s = new StringCipher();
using (SqlConnection sql = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand("spPhoneLogin", sql))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#phone", phone));
cmd.Parameters.Add(new SqlParameter("#password", s.EncryptString(pass)));
User response = null;
await sql.OpenAsync();
using (var reader = await cmd.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
response = MapToValue(reader);
}
}
return response;
}
}
}
i'm new to API's. i'm trying to send two parameters with the request.
and how is the URI constructed in that case.
Based on your routing attribute [Route("[action]/{phone}/{password}", Name="PhoneLogin")], the method can be reached under /PhoneLogin/anyString/anyOtherString where anyString would be bound to phone and anyOtherString to password.
If you have an additional route attribute on the controller class, such as [Route("[controller]")], the name of your controller also needs to be added which results in /MyControllerName/PhoneLogin/anyString/anyOtherString.
Please take a closer look at the documentation on model binding and routing fundamentals. The default model binding follows a predefined order, which (based on the documentation) is
Form fields
The request body (For controllers that have the [ApiController] attribute.)
Route data
Query string parameters
Uploaded files
So since no form fields or request body is provided (which is the most common case for a get-request), the route data is used to bind the two parameters.
I want to setup an endpoint for testing webhooks from third parties. Their documentation is uniformly poor and there is no way ahead of time to tell exactly what I will be getting. What I've done is setup an ApiController that will just take a request and add a row to a table with what they are sending. This lets me at least verify they are calling the webhook, and to see the data so I can program to it.
// ANY api/webook/*
[Route("{*path}")]
public ActionResult Any(string path)
{
string method = Request.Method;
string name = "path";
string apiUrl = Request.Path;
string apiQuery = Request.QueryString.ToString();
string apiHeaders = JsonConvert.SerializeObject(Request.Headers);
string apiBody = null;
using (StreamReader reader = new StreamReader(Request.Body))
{
apiBody = reader.ReadToEnd();
}
Add(method, name, apiUrl, apiQuery, apiHeaders, apiBody);
return new JsonResult(new { }, JsonSettings.Default);
}
This works great, except for this new webhook I am usign that posts as form data so some middleware is reading the body and it ends up null in my code. Is there any way to disable the model processing so I can get at the request body?
You could actually use model binding to your advantage and skip all that stream reading, using the FromBody attribute. Try this:
[Route("{*path}")]
[HttpPost]
public ActionResult Any(string path, [FromBody] string apiBody)
I'm new to Retrofit. I make a POST request to a website. Website returns response as HTML. So I will parse it. However Retrofit try to parse it as JSON. How can do it?
#FormUrlEncoded
#POST("/login.php?action=login")
void postCredentials(#Field("username") String username,
#Field("password") String password);
Should I use a callback?
Retrofit uses a converter to process responses from endpoints and requests as well. By default, Retrofit uses GsonConverter, which encoded JSON responses to Java objects using the gson library. You can override that to supply your own converter when constructing your Retrofit instance.
The interface you need to implement is available here (github.com). Here's a short tutorial as well, although for using Jackson library, many bits are still relevant: futurestud.io/blog
Also note that the converter works both ways, converting requests and responses. Since you want HTML parsing in one direction only, you may want to use GsonConverter in your custom converter, to convert outgoing Java objects to JSON, in the toBody method.
May be not the best solution but this how i managed to get the source of an html page with retrofit:
MainActivity.java
ApiInterface apiService = ApiClient.getClient(context).create(ApiInterface.class);
//Because synchrone in the main thread, i don't respect myself :p
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
//Execution of the call
Call<ResponseBody> call = apiService.url();
response = call.execute();
//Decode the response text/html (gzip encoded)
ByteArrayInputStream bais = new ByteArrayInputStream(((ResponseBody)response.body()).bytes());
GZIPInputStream gzis = new GZIPInputStream(bais);
InputStreamReader reader = new InputStreamReader(gzis);
BufferedReader in = new BufferedReader(reader);
String readed;
while ((readed = in.readLine()) != null) {
System.out.println(readed); //Log the result
}
ApiInterface.java
#GET("/")
Call<ResponseBody> url();
ApiClient.java
public static final String BASE_URL = "https://www.google.com";
private static Retrofit retrofit = null;
public static Retrofit getClient(Context context) {
if (retrofit==null) {
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.client(okHttpClient)
.build();
}
return retrofit;
}
I don't think it have to be in pairs, so if I send a plain text like below:
HttpClient httpClient = new HttpClient();
httpClient.PostAsync("http://hey.com",
new StringContent("simple string, no key value pair."));
Then the FormCollection below doesn't seem to offer a way to read that..
public ActionResult Index(FormCollection collection){
//how to get the string I sent from collection?
}
The FormCollection object is a Key Value pair collection. If you are sending a simple string over then the collection will be empty unless it is formatted as a Key\Value pair.
This can be done in multiple ways.
Option 1: Send Key Value Pairs, where the FormCollection will read your string with the key myString:
HttpClient httpClient = new HttpClient();
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("mystring", "My String Value")
});
httpClient.PostAsync("http://myUrl.com", content);
Option 2: Read the contents directly from the Request. This reads the raw Request.InputStream into a StreamReader into a string
public ActionResult ReadInput()
{
this.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
string myString = "";
using (var reader = new StreamReader(this.Request.InputStream))
{
myString = reader.ReadToEnd();
}
}
There are many more options but either of these methods should do the trick
Have a question I surpsisingly couldnt find an answer to when searching around.
If I request a users email from facebook like:
var scope = new List<string>();
scope.Add("email");
FbClient.RequestUserAuthorization(scope);
How do I retrieve it? I couldnt find a clear option for this in the FacebookGraph.
Near as I can tell, the FacebookGraph object that is in the examples from DotNetOpenAuth does not support changing the fields that you are receiving. However, since WebRequest that it is prompting is returning a JSON string, you can parse it yourself (or use another JSON parser). That's exactly what I did, using the NewtonSoft.Json.dll:
//as part of the uri for the webrequest, include all the fields you want to use
var request = WebRequest.Create("https://graph.facebook.com/me?fields=email,name&access_token=" + Uri.EscapeDataString(authorization.AccessToken));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
System.IO.StreamReader streamReader = new System.IO.StreamReader(responseStream, true);
string MyStr = streamReader.ReadToEnd();
JObject userInfo = JObject.Parse(MyStr);
//now you can access elements via:
// (string)userInfo["name"], userInfo["email"], userInfo["id"], etc.
}
}
Note that you specify what fields you want sent back as part of the WebRequest URI. The fields that are available can be found at https://developers.facebook.com/docs/reference/api/user/
Using DNOA This answer did it for me.
Just added the following:
var scope = new List<string>();
scope.Add("email");
client.RequestUserAuthorization(scope);
and the following to the facebook graph.
[DataMember(Name = "email")]
public string EMail { get; set; }
What you wrote above appears to be requsting authorization from the user to allow your app to get email back when you query the user's object. To query the user's object you do an HTTP Get on https://graph.facebook.com/me. Try it out in the Graph API explorer tool at https://developers.facebook.com/tools/explorer