MVC 4 Web API 2 ajax call all parameters optional - android

I realy want your option.
We update a .net MVC 3 project to MVC 4 with web api 2, this a web service.
The ajax calls is from android machines with the Devextreme/Phonegap.
After the update the web service when i call login from android i get
"No HTTP resource was found that matches the request URI 'http://www.whatever.gr/MVCService/Actions/Login'"
I want to set the route so that all methods of the MVC service can have parameters optional.
I can't get this work..
We can't change the source on the android app,and ajax call is the code below
function doLogin(username, password, callback) {
loading(true);
var dataStr = "uid=" + uid + "&username=" + username + "&password=" + password;
var success = false;
var token = "";
$.ajax({
type: "POST",
url: registrationServiceUrl + 'Login',
data: dataStr,
beforeSend: function () {
//alert("registration no: " + registrationid);
},
success: function (retval) {
if (retval.indexOf('SUCCESS') == 0) {
success = true;
token = retval.substring(8);
//setTokenToSettings(token);
} else {
success = false;
};
callback(success, token);
loading(false);
},
error: function (retval) {
callback(success, token);
loading(false);
}
});
}
The route in MVC is
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
When i hit like below with parameters in a browser i have a response
'http://www.whatever.gr/MVCService/Actions/Login?param1=1&param=2&param3=3'.
I want to have the behavior, when to hit 'http://www.whatever.gr/MVCService/Actions/Login'
or
'http://www.whatever.gr/MVCService/Actions/Login?param1=1&param=2&param3=3&invalidParamName=x'.
And the web service method to be trigger with empty parameters values.
But without setting optional parameters in the method
public string Login(string pamar1 = "",string param2 = "", string param3 = "")
With MVC 3 this was working fine as I explained before.
Thanks in advance and for your time.

In Web API, it's very simple to remember how parameter binding is happening.
if you POST simple types, Web API tries to bind it from the URL
if you POST complex type, Web API tries to bind it from the body of
the request (this uses a media-type formatter).
This asp.net page explains it all.
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

Related

Google Login/Signin on Yandex Android extension

I'm trying to run my desktop chrome extension on Android, so i tried running it in Yandex browser on my phone. It runs ok except for the google login.(everything works well on desktop Chrome and desktop Yandex).
This code is called by the background scripts:
var url = 'https://accounts.google.com/o/oauth2/auth' +
'?client_id=' + clientId +
'&response_type=id_token' +
'&access_type=offline' +
'&redirect_uri=' + redirectUri +
'&scope=' + scopes;
getIdToken: function (message) {
const _this = this;
var idToken = "";
chrome.identity.launchWebAuthFlow(
{
'url': url,
'interactive': true
},
function (redirectedTo) {
console.log("[2]auth-manager called: "+redirectedTo);
if (chrome.runtime.lastError) {
// Example: Authorization page could not be loaded.
console.log("lastError: "+chrome.runtime.lastError.message);
}
else {
var response = redirectedTo.split('#', 2)[1];
// Example: id_token=<YOUR_BELOVED_ID_TOKEN>&authuser=0&hd=<SOME.DOMAIN.PL>&session_state=<SESSION_SATE>&prompt=<PROMPT>
idToken = (response.split('&')[0]).split('=', 2)[1];
console.log("auth-manager id token", idToken);
if (message != undefined) {
message.data.google_id_token = idToken;
cloudWebSocket.sendMessage(JSON.stringify(message));
_this.isLogged = true;
closePopup();
alert('login successful');
}
}
}
);
}
When I call this function, redirectedTo is undefined, and i get a chrome.runtime.lastError.message:"canceled". That's it.
I use the very same manifest from the desktop apps, with the same clientId,redirectUri and scopes.
I can't figure out, what causes this problem?
If there's another way to perform a google login without this issue it can also help.
see the Web Extensions API ...in particular the platform support table there.
initiating the oAuth2 flow on the server-side should nevertheless be possible.

Getting transactions from WebView with testing credentials (Plaid)

How can I get transactions from WebView with testing credentials on Android?
This is my code:
public class PlaidViewActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plaid_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Initialize Link
HashMap<String, String> linkInitializeOptions = new HashMap<String,String>();
linkInitializeOptions.put("key", "56632c5b63db7b7a155000b7c9507649");
linkInitializeOptions.put("product", "transact`enter code here`ions,auth");
linkInitializeOptions.put("apiVersion", "v2"); // set this to "v1" if using the legacy Plaid API
linkInitializeOptions.put("env", "sandbox");
linkInitializeOptions.put("clientName", "Test App");
linkInitializeOptions.put("selectAccount", "true");
linkInitializeOptions.put("webhook", "http://requestb.in");
linkInitializeOptions.put("baseUrl", "https://cdn.plaid.com/link/v2/stable/link.html");
// If initializing Link in PATCH / update mode, also provide the public_token
// linkInitializeOptions.put("public_token", "PUBLIC_TOKEN")
// Generate the Link initialization URL based off of the configuration options.
final Uri linkInitializationUrl = generateLinkInitializationUrl(linkInitializeOptions);
// Modify Webview settings - all of these settings may not be applicable
// or necesscary for your integration.
final WebView plaidLinkWebview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = plaidLinkWebview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
WebView.setWebContentsDebuggingEnabled(true);
// Initialize Link by loading the Link initiaization URL in the Webview
plaidLinkWebview.loadUrl(linkInitializationUrl.toString());
// Override the Webview's handler for redirects
// Link communicates success and failure (analogous to the web's onSuccess and onExit
// callbacks) via redirects.
plaidLinkWebview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Parse the URL to determine if it's a special Plaid Link redirect or a request
// for a standard URL (typically a forgotten password or account not setup link).
// Handle Plaid Link redirects and open traditional pages directly in the user's
// preferred browser.
Uri parsedUri = Uri.parse(url);
if (parsedUri.getScheme().equals("plaidlink")) {
String action = parsedUri.getHost();
HashMap<String, String> linkData = parseLinkUriData(parsedUri);
if (action.equals("connected")) {
// User successfully linked
Log.d("-->Public token: ", linkData.get("public_token")+"");
Log.d("-->Account ID: ", linkData.get("account_id")+"");
Log.d("-->Account name: ", linkData.get("account_name")+"");
Log.d("-->Institution type: ", linkData.get("institution_type")+"");
Log.d("-->Institution name: ", linkData.get("institution_name")+"");
// Reload Link in the Webview
// You will likely want to transition the view at this point.
plaidLinkWebview.loadUrl(linkInitializationUrl.toString());
} else if (action.equals("exit")) {
// User exited
// linkData may contain information about the user's status in the Link flow,
// the institution selected, information about any error encountered,
// and relevant API request IDs.
Log.d("User status in flow: ", linkData.get("status"));
// The requet ID keys may or may not exist depending on when the user exited
// the Link flow.
Log.d("Link request ID: ", linkData.get("link_request_id"));
Log.d("API request ID: ", linkData.get("plaid_api_request_id"));
// Reload Link in the Webview
// You will likely want to transition the view at this point.
plaidLinkWebview.loadUrl(linkInitializationUrl.toString());
} else {
Log.d("Link action detected: ", action);
}
// Override URL loading
return true;
} else if (parsedUri.getScheme().equals("https") ||
parsedUri.getScheme().equals("http")) {
// Open in browser - this is most typically for 'account locked' or
// 'forgotten password' redirects
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
// Override URL loading
return true;
} else {
// Unknown case - do not override URL loading
return false;
}
}
});
}
// Generate a Link initialization URL based on a set of configuration options
public Uri generateLinkInitializationUrl(HashMap<String,String>linkOptions) {
Uri.Builder builder = Uri.parse(linkOptions.get("baseUrl"))
.buildUpon()
.appendQueryParameter("isWebview", "true")
.appendQueryParameter("isMobile", "true");
for (String key : linkOptions.keySet()) {
if (!key.equals("baseUrl")) {
builder.appendQueryParameter(key, linkOptions.get(key));
}
}
return builder.build();
}
// Parse a Link redirect URL querystring into a HashMap for easy manipulation and access
public HashMap<String,String> parseLinkUriData(Uri linkUri) {
HashMap<String,String> linkData = new HashMap<String,String>();
for(String key : linkUri.getQueryParameterNames()) {
linkData.put(key, linkUri.getQueryParameter(key));
}
return linkData;
}
This is my code and I am getting the result in success
05-09 10:29:32.268 3091-3091/? D/-->Public token:: public-sandbox-2fddfc55-abb1-439d-84e0-6b1207503eb3
05-09 10:29:32.268 3091-3091/? D/-->Account ID:: nordpMwPjZSoVok6XzaeCQArXDjjM4H6Nj3ox
05-09 10:29:32.268 3091-3091/? D/-->Account name:: Plaid Credit Card
05-09 10:29:32.269 3091-3091/? D/-->Institution type:: null
05-09 10:29:32.269 3091-3091/? D/-->Institution name:: Citi
from this, I want to get transaction please help me out
Using postman i did
https://sandbox.plaid.com/transactions/get
{
"client_id": "5ae9627a6c0fcd0012c97bf1",
"secret": "b67ff6d1a462303cf43e2e83edaf33",
"access_token": "public-sandbox-2fddfc55-abb1-439d-84e0-6b1207503eb3",
"start_date": "2017-01-01",
"end_date": "2017-02-01",
"options": {
"count": 250,
"offset": 100
}
}
but i am getting an error response
{
"display_message": null,
"error_code": "INVALID_ACCESS_TOKEN",
"error_message": "provided token is the wrong type. expected \"access\", got \"public\"",
"error_type": "INVALID_INPUT",
"request_id": "bTgTg"
}
like this please help out
Old question, yet still writing this for the records
It looks like you were using public token as stated in your Postman request. You need to exchange the public token with an access token first, which would eliminate the need for direct communication between end user and plaid.
"access_token": "public-sandbox-2fddfc55-abb1-439d-84e0-6b1207503eb3",
For the reference, Plaid access tokens start with access-.. not public-..
For more information you can refer there.
https://plaid.com/docs/quickstart/#rotate-access-token

getting HTTP response headers with getAllResponseHeaders

I'm trying to get the http response headers every time I visit some site. I thought that using an observer like the following is enough to do it:
const OBS = Cc['#mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
let httpRequestObserver ={
observe: function(subject, topic, data){
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
if (topic == "http-on-examine-response") {
headers=httpChannel.getAllResponseHeaders();
}
}
};
And in the startup method I add it then in the shutdown I remove it:
OBS.addObserver(httpRequestObserver, "http-on-examine-response", false);//startup methode
OBS.addObserver(httpRequestObserver, "http-on-examine-response", false);//shutdown
But I'm getting this in the log:
JavaScript Error: "httpChannel.getAllResponseHeaders is not a function"
Am I taking the wrong way and the operation is more complicated than it seem? this is for an extension for firefox for android and i'm not using sdk. Thanks for your help.
nsIHttpChannel is not XMLHttpRequest. Instead XMLhttpRequest is a nice wrapper class around channels - not just http ones -, which also adds convenience functions such as getAllResponseHeaders().
You may use nsIHttpChannel.visitResponseHeaders to simulate getAllResponseHeaders.
if (subject instanceof Ci.nsIHttpChannel) {
var headers = "";
subject.visitResponseHeaders(function(header, value) {
headers += header + ": " + value + "\r\n";
});
}

Android- Sharing local storage on multiple WebViews/Windows

I'm developping a mobile application, which should connect to a web server. The application is written with jQM and simply imported in an android web view. I tried to solve this problem using the jStorage plugin, but it seems that it's impossible to share the local storage between the different pages. So I tried to implement this, but it does not work and continues sending null.
Here are my code samples:
Javascript:
function getToken(authCode) {
var jsonUrl = mainUrl + "/auth/authorizeToken?grant_type=authorization_code&client_id=bc89fb879a64eb8e422b94d5c39&client_secret=b5c2974b78f7f3f7aee2bed182&redirect_uri=redirection&code="+authCode;
$.ajax({
url: jsonUrl,
type: "GET",
dataType: "jsonp",
success: function(data) {
localStorage.setItem( "access_token", data.access_token);
localStorage.setItem( "refresh_token", data.refresh_token);
localStorage.setItem( "logged", "true");
}
});
}
function valTokens() {
access_token = localStorage.getItem("access_token");
refresh_token = localStorage.getItem("refresh_token");
}
After that the values are set to null. The .java files are the same as in the sample from the link given.

How do I enable Third-Party Cookies under Phonegap and Android 3.2?

I am using $getJSON to hit a node.js endpoint under Phonegap and Android. The code looks like this
$.getJSON(
serverURL + "/login?callback=?",
"playerId=" + playerId + "&pwd=" + pwd,
function(data){
theCallbackFunction.call(null, JSON.parse(data));
},
function(jqXHR, textStatus, errorThrown) {
alert('error ' + textStatus + " " + errorThrown);
}
);
In response to the login request, my server sends back a session cookie. This cookie is only accepted and returned in subsequent AJAX requests if 'Third-Party Cookies' are enabled in the browser. I have found that older Android devices (e.g. 2.2) allow this by default but new ones (3.2) do not.
Is it possible to force Phonegap to enable Third-Party Cookies for my Android application?
I had a similar problem when trying to authenticate with my server. I instead resorted to the use of localStorage. See the code below or here.
var store = window.localStorage,
request = {
url: {SERVER_URL},
headers : {
Cookie: store.getItem('session')
},
complete: function (jqXHR, status){
if (status != 'success') {
console.log('ajax status: failure');
} else if (store.getItem('session') != null) {
console.log('ajax status: session exists');
} else {
console.log('ajax status: saving cookie');
var header = jqXHR.getAllResponseHeaders();
var match = header.match(/(Set-Cookie|set-cookie): (.+?);/);
if (match) {
session = match[2];
store.setItem("session", session);
}
}
}
}
$.ajax(request);
In the above, I'm checking for the localStorage variable 'session' and if it exists, it will send the stored cookie. If it doesn't exist, it will take the 'set-cookie' paramater sent in the headers by the server, match the pertinent part and store it in the 'session' variable of localStorage.
Phonegap does not support cookie abstraction. Never really needed to as there are already apps/plug-ins that do. Plus it is intended to wrap up the functionality of the phone/device, not the browser. You CAN however do this with a jQuery plug-in.
https://github.com/carhartl/jquery-cookie

Categories

Resources