How to get customers details using Quickbooks QBXML - quickbooks

I used QuickBooks API. Through this API i try to get all customer details like FullName, Addresses(Addr1,Addr2....), City, State, PostalCode etc.
Below is my code:
RequestProcessor2Class rp = new RequestProcessor2Class();
public void connectToQB()
{
rp = new RequestProcessor2Class();
rp.OpenConnection(appID, appName);
ticket = rp.BeginSession(companyFile, mode);
string[] versions = rp.get_QBXMLVersionsForSession(ticket);
maxVersion = versions[versions.Length - 1];
}
public string processRequestFromQB(string request)
{
try
{
return rp.ProcessRequest(ticket, request);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return null;
}
}
string request = "CustomerQueryRq";
objConnect.connectToQB();
int count = objConnect.getCount(request);
string response = objConnect.processRequestFromQB(objConnect.buildCustomerQueryRqXML(new string[] { "FullName", "City" }, null));
string[] customerList = objConnect.parseCustomerQueryRs(response, count);
objConnect.disconnectFromQB();
Let me know if you want more information.
Thanks,

This is a sample code for get customer name.
ICustomerRetList customerRetList = (ICustomerRetList)response.Detail;
ICustomerRet customerRet = customerRetList.GetAt(0);
textBox1.Text = customerRet.Name.GetValue().ToString();
Please learn more.
->> for get other detail.

Related

How to refactor the connectionString in my Entity Framework & ASP.NET MVC project?

I have a large number of stored procedures to work with and I have to work with Entity Framework.
I got for example this controller where I'm just calling the database to show my table:
public class CarguioController : Controller
{
public ActionResult Index(int? page)
{
string cs = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (SqlConnection conn = new SqlConnection(cs))
{
// establece conneción
SqlParameter param1 = new SqlParameter();
param1.ParameterName = "#MODO";
param1.SqlDbType = SqlDbType.Int;
param1.Value = 2;
SqlCommand cmdProcedure = new SqlCommand(#"Almacen.[PRC_Carguio]", conn);
cmdProcedure.Parameters.Add(param1);
conn.Open();
cmdProcedure.CommandType = CommandType.StoredProcedure;
SqlDataReader dr = cmdProcedure.ExecuteReader();
List<CarguioViewModel> lst = new List<CarguioViewModel>();
int pageNumber = page ?? 1;
int pageSize = 8;
if (dr.HasRows)
{
while (dr.Read())
{
lst.Add(new CarguioViewModel
{
Carguio_ID = dr.GetInt32(0),
Vehiculos_ID = dr.GetInt32(1),
ManifiestoCarga_ID = dr.GetInt32(2),
Guia_ID = dr.GetInt32(3),
Programaciones_ID = dr.GetInt32(4),
Numero = dr.GetInt32(5),
NroMobil = dr.GetString(6),
Fecha = dr.GetDateTime(7),
Usuarios_ID = dr.GetInt32(8),
Sucursales_IS = dr.GetInt32(9)
});
//display retrieved record
}
return View(lst.ToPagedList(pageNumber, pageSize));
}
else
{
Console.WriteLine("No data found.");
}
dr.Close();
conn.Close();
}
return View();
}
}
As you can see, I have to connect with the SQL Server database many times. Maybe you have done a similar job with ASP.NET MVC projects or have any idea to refactor my code?
I have more than 30 tables and everyone has more a Crud and other functions.
I've been searching for this but there is just the same example.
string cs = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
You can get create in General Utility class to read the connection, so that It is stay in one place in the code and read connection value from the Genral Utility class wherever you need it.
void Main()
{
string cn = GeneralUtility.getConnectionString();
}
public class GeneralUtility
{
public static string getConnectionString()
{
string cs = "";
try
{
cs = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
}
catch (Exception ex)
{
throw new Exception("Connection String Error " + ex.Message.ToString());
}
return cs;
}
}
I added a new element called ADO.Net Entity Data Model, where I retrieve all my Stored Procedures, It is helpful
I added a new element called ADO.Net Entity Data Model
Well, now my code is shorter than before:
public ActionResult Index(int? page)
{
List<CarguioModel> lst = new List<CarguioModel>();
int pageNumber = page ?? 1;
int pageSize = 8;
using (MarviBKPEntities prcAlm = new MarviBKPEntities())
{
List<PRC_Carguio_Result> prc = prcAlm.PRC_Carguio(2, null, null, null, null, null, null, null, null, null, null).ToList();
return View(prc.ToPagedList(pageNumber, pageSize));
}
return View();
}
Whta do you think? Could it cause some bad performance?

Not receiving access_token in three-legged oauth 2.0 flow in asp.net mvc (Blackboard Learn)

I have to implement three-legged authentication in ASP.NET MVC. I have followed the steps according to the Blackboard documentation, especially the link https://community.blackboard.com/docs/DOC-3976-three-legged-oauth
I have received authorization code by calling the REST API /learn/api/public/v1/oauth2/authorizationcode.After that according to the documentation (I followed the documentation exactly but I don't know what am I have been missing ), I built a POST request to /learn/api/public/v1/oauth2/token to get access_token but I am unable to get access_token.
Instead, access_token, I have been receiving a BadRequest. This means I am making a mistake to build my second request but I am unable to fix the problem. I haven't found any code sample in .NET to implement three legged authentication for Blackboard Learn. Could you please help me to resolve the issue?
This is my code to call both APIs to receive access_token.
public class HomeController : Controller
{
public ActionResult Index()
{
// GET /learn/api/public/v1/oauth2/authorizationcode
Guid stateId = Guid.NewGuid();
string applicationKey = "Application key goes here";
string redirectUrl = string.Format("https://Blackboard Learn URL goes here/learn/api/public/v1/oauth2/authorizationcode" +
"?redirect_uri=https://localhost:44300/Home/OAuth2Response&response_type=code&client_id={0}&scope=read&state={1}",
applicationKey, stateId);
Response.Redirect(redirectUrl, true);
return View();
}
public async Task<bool> OAuth2Response(string code = null, string state = null, string error = null, string error_description = null)
{
bool success = true;
string json = string.Empty;
string urlCommand = string.Format("/learn/api/public/v1/oauth2/token?code={0}&redirect_url=https://localhost:44300/Home/OAuth2Response", code);
try
{
using (HttpClient client = new HttpClient())
{
var endpoint = new Uri("Blackboard Learn URL goes here" + urlCommand);
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
HttpContent body = new FormUrlEncodedContent(postData);
// POST /learn/api/public/v1/oauth2/token
using (HttpResponseMessage response = await client.PostAsync(endpoint, body)) // Problem is here
{
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
}
else
{
success = false;
}
}
}
}
catch (Exception err)
{
//hopefully we never end up here, log this exception for forensics
success = false;
}
return success;
}
}
NOTE: I can successfully receive an access_token in Postman tool.
Finally, the below code works perfectly for 3 legged authentications in ASP.NET MVC.
public class HomeController : Controller
{
//https://blackboard.jiveon.com/docs/DOC-3976-three-legged-oauth
public ActionResult Index()
{
// GET /learn/api/public/v1/oauth2/authorizationcode
Guid stateId = Guid.NewGuid();
string applicationKey = "Application key goes here";
string redirectUrl = string.Format("Blackboard Learn URL goes here/learn/api/public/v1/oauth2/authorizationcode" +
"?redirect_uri=https://localhost:44300/Home/OAuth2Response&response_type=code&client_id={0}&scope=read&state={1}",
applicationKey, stateId);
Response.Redirect(redirectUrl, true);
return View();
}
public async Task<bool> OAuth2Response(string code = null, string state = null, string error = null, string error_description = null)
{
bool success = true;
string json = string.Empty;
string urlCommand = string.Format("/learn/api/public/v1/oauth2/token?code={0}&redirect_uri=https://localhost:44300/Home/OAuth2Response", code);
try
{
using (HttpClient client = new HttpClient())
{
var endpoint = new Uri("Blackboard Learn URL goes here" + urlCommand);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("client_id:client_secret")));
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
HttpContent body = new FormUrlEncodedContent(postData);
using (HttpResponseMessage response = await client.PostAsync(endpoint, body))
{
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
dynamic oauth2Result = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
string access_token = oauth2Result.access_token;
string refresh_token = oauth2Result.refresh_token; }
else
{
success = false;
}
}
}
}
catch (Exception err) {
//hopefully we never end up here, log this exception for forensics
success = false;
}
return success;
}
}

Google OAuth 2 Error: redirect_uri_mismatch random url parameter ASP.NET

I've done authentication via VK, Instagram, Facebook in my site by template below.
However google requires "Redirect URL".
My redirect URL is like this:
http://localhost:4588/main/AuthenticationCallback?__provider__=google%2B&__sid__=6f3cc5957e4742758719f9b7decc2c09
Parameter "sid" is random every time. So I can't give google precise URL. I tried to input http://localhost:4588/main/AuthenticationCallback as I did for Instagram and it worked for Instagram but Google keeps showing me "400 Error: redirect_uri_mismatch"
I've also tried to pass http://localhost:4588/main/AuthenticationCallback as URL parameter in authorization url to google below. But in this case method "IAuthenticationClient.RequestAuthentication" is not called at all.
Can you advise me what should I input as "Redirect URL" for my Google app?
Template class working with OAuth2:
public class GoogleAuthenticationClient : IAuthenticationClient
{
public string appId;
public string appSecret;
private string redirectUri;
public GoogleAuthenticationClient(string appId, string appSecret)
{
this.appId = appId;
this.appSecret = appSecret;
}
string IAuthenticationClient.ProviderName
{
get { return "google+"; }
}
void IAuthenticationClient.RequestAuthentication(HttpContextBase context, Uri returnUrl)
{
var APP_ID = this.appId;
this.redirectUri = context.Server.UrlEncode(returnUrl.ToString());
var address = String.Format(
"https://accounts.google.com/o/oauth2/auth?client_id={0}&redirect_uri={1}&response_type=code&scope={2}",
APP_ID, this.redirectUri, "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
);
HttpContext.Current.Response.Redirect(address, false);
}
class AccessToken
{
public string access_token = null;
public string user_id = null;
}
class UserData
{
public string uid = null;
public string first_name = null;
public string last_name = null;
public string photo_50 = null;
}
class UsersData
{
public UserData[] response = null;
}
AuthenticationResult IAuthenticationClient.VerifyAuthentication(HttpContextBase context)
{
try
{
string code = context.Request["code"];
var address = String.Format(
"https://accounts.google.com/o/oauth2/token?client_id={0}&client_secret={1}&code={2}&redirect_uri={3}",
this.appId, this.appSecret, code, this.redirectUri);
var response = GoogleAuthenticationClient.Load(address);
var accessToken = GoogleAuthenticationClient.DeserializeJson<AccessToken>(response);
address = String.Format(
"https://www.googleapis.com/plus/v1/people/{0}?access_token=1/fFBGRNJru1FQd44AzqT3Zg",
accessToken.user_id);
response = GoogleAuthenticationClient.Load(address);
var usersData = GoogleAuthenticationClient.DeserializeJson<UsersData>(response);
var userData = usersData.response.First();
return new AuthenticationResult(
true, (this as IAuthenticationClient).ProviderName, accessToken.user_id,
userData.first_name + " " + userData.last_name,
new Dictionary<string, string>());
}
catch (Exception ex)
{
return new AuthenticationResult(ex);
}
}
public static string Load(string address)
{
var request = WebRequest.Create(address) as HttpWebRequest;
using (var response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
}
public static T DeserializeJson<T>(string input)
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<T>(input);
}
}
Code in my Controller:
public void ExternalLogin(string provider)
{
OAuthWebSecurity.RegisterClient(
client: new GoogleAuthenticationClient(
"APP_ID", "APP_CODE"),
displayName: "google+", // надпись на кнопке
extraData: null);
ExternalLoginCallback(provider);
}
public void ExternalLoginCallback(string provider)
{
OAuthWebSecurity.RequestAuthentication(provider, Url.Action("AuthenticationCallback"));
}
public ActionResult AuthenticationCallback()
{
var result = OAuthWebSecurity.VerifyAuthentication();
if (result.IsSuccessful == false)
{
return null;
}
else
{
var provider = result.Provider;
var uniqueUserID = result.ProviderUserId;
return RedirectToAction("Main", "Main");
}
}
You can authorise a redirect URI as explained below, but you can't add any parameters to the redirect uri, please see this answer on how the parameters can be passed to Google google oauth2 redirect_uri with several parameters
The authorised redirect URI needs to be set when you created your client ("APP_ID", "APP_CODE") on the Google Cloud Console. Simply navigate to the API console for your project and edit the Web client to set the correct redirect URI you would like to use.

IMAP Response limited size

I am working on an email client that will connect to Gmail mailbox and retrieve a specific email.
Now i can connect to my mailbox and can retrieve part of the emails not all of it and no matter how large is my buffer still i get only 1400 char from my email and then Null for the rest of the mail body.
You can find a screen shot for the email body in this link
http://www.elzouhery.com/Mail%20Snapshot.png
Thanks in Advance
EDIT
See below the Full Code
static void Main(string[] args)
{
TcpIMAP imap = ConnectToEmail();
Console.WriteLine("Total Messages " + imap.MailCount());
Console.WriteLine("Total Unread Messages " + imap.MailUnreadCount());
Console.WriteLine("******************************************************");
imap.SelectInbox();
StreamWriter writer = null;
int mailCount = imap.MailCount();
var mailSize = string.Empty;
var content = string.Empty;
var subject = string.Empty;
for (int i = 1; i < mailCount; i++)
{
try
{
writer = new StreamWriter(#"c:\Mails\" + i + ".txt", true);
content = imap.GetMessage(i).ToString();
writer.Write(content);
writer.Close();
}
catch(Exception ex)
{
writer.Write(content);
Console.Write(ex.Message);
writer.Close();
}
}
}
private static TcpIMAP ConnectToEmail()
{
string host = "imap.gmail.com";
string username = "************";
string password = "************";
TcpIMAP imap = new TcpIMAP();
imap.Connect(host, 993);
imap.AuthenticateUser(username, password);
return imap;
}
public static string GetMailSubject(string Header)
{
var headerLines = Header.Split(Environment.NewLine.ToCharArray());
foreach (var line in headerLines)
{
if (line.IndexOf("Subject") > -1)
{
return line.Replace("Subject: ", "");
}
}
return "";
}
/***************************************************/
class TcpIMAP
{
private TcpClient _imapClient;
private Stream _imapNs;
private StreamWriter _imapSw;
private StreamReader _imapSr;
public TcpIMAP()
{
}
public TcpIMAP(string hostname, int port)
{
InitializeConnection(hostname, port);
}
public void Connect(string hostname, int port)
{
InitializeConnection(hostname, port);
}
private void InitializeConnection(string hostname, int port)
{
try
{
_imapClient = new TcpClient(hostname, port);
System.Net.Security.SslStream sslstream = new System.Net.Security.SslStream(_imapClient.GetStream());
sslstream.AuthenticateAsClient("imap.gmail.com");
_imapNs = sslstream;
_imapSw = new StreamWriter(_imapNs);
_imapSr = new StreamReader(_imapNs);
Console.WriteLine("*** Connected ***");
Response();
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
}
public void AuthenticateUser(string username, string password)
{
_imapSw.WriteLine("$ LOGIN " + username + " " + password);
_imapSw.Flush();
Response();
}
public int MailCount()
{
_imapSw.WriteLine("$ STATUS INBOX (messages)");
_imapSw.Flush();
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
return Convert.ToInt32(m.ToString());
}
public int MailUnreadCount()
{
_imapSw.WriteLine("$ STATUS INBOX (unseen)");
_imapSw.Flush();
string res = Response();
Match m = Regex.Match(res, "[0-9]*[0-9]");
return Convert.ToInt32(m.ToString());
}
public string SelectInbox()
{
_imapSw.WriteLine("$ SELECT INBOX");
_imapSw.Flush();
return Response();
}
public object GetMessageHeaders(int index)
{
_imapSw.WriteLine("$ FETCH " + index + " (body[header.fields (from subject date)])");
_imapSw.Flush();
return Response();
}
public object GetMessage(int index)
{
_imapSw.WriteLine("$ FETCH " + index + " BODY.PEEK[]");
_imapSw.Flush();
return Response();
}
private string Response()
{
byte[] data = new byte[_imapClient.ReceiveBufferSize];
int ret = _imapNs.Read(data, 0, data.Length);
string output = Encoding.ASCII.GetString(data).TrimEnd().Replace("\0", "");
return output;
}
public void Disconnect()
{
_imapSw.WriteLine("$ LOGOUT");
_imapSw.Flush();
_imapClient.Close();
}
public string SendCommand(string command)
{
_imapSw.WriteLine("$ " + command);
_imapSw.Flush();
return Response();
}
It looks like you are using code from here, or similar:
http://www.codeproject.com/Articles/29594/How-to-Access-Emails-Using-the-IMAP-Protocol
That code as written is wrong and won't work for larger messages. The Response() call needs to loop over calls to .Read(), appending the results until the method returns 0 (which indicates there is no more data available.) Look at the documentation for NetworkStream.Read.
Also, you'd be much better off using an IMAP library (see Accessing Imap in C#).
You Just Have To Change Your Receive Buffer Size

Why am I not receiving a RefreshToken from a Google OAuth request?

I am attempting to integrate Google Calendar into my application and I am having some problems with the OAuth authorization passing off a RefreshToken. I receive an AccessToken with no issue, but the RefreshToken property is null. See the line marked "ERROR HERE:" for where I am having the issue
My Asp.Net MVC controller (named OAuthController) looks like the following:
public ActionResult Index()
{
var client = CreateClient();
client.RequestUserAuthorization(new[] { "https://www.googleapis.com/auth/calendar" }, new Uri("http://localhost/FL.Evaluation.Web/OAuth/CallBack"));
return View();
}
public ActionResult CallBack()
{
if (string.IsNullOrEmpty(Request.QueryString["code"])) return null;
var client = CreateClient();
// Now getting a 400 Bad Request here
var state = client.ProcessUserAuthorization();
// ERROR HERE: The RefreshToken is NULL
HttpContext.Session["REFRESH_TOKEN"] = Convert.ToBase64String(Encoding.Unicode.GetBytes(state.RefreshToken));
return JavaScript("Completed!");
}
private static WebServerClient CreateClient()
{
return
new WebServerClient(
new AuthorizationServerDescription()
{
TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"),
ProtocolVersion = ProtocolVersion.V20
}
, _GoogleClientId, _GoogleSecret);
}
I see in Google's API documents, that I need to ensure that the access_type requested is set to offline for a RefreshToken to be sent. How do I set this value in my Authenticator request?
After hours of fiddling with DotNetOpenAuth and the Google APIs published for .Net, I got nowhere fast. I decided to circumvent the libraries and went directly at the Google REST API with native HttpRequest and HttpResponse objects. My sanitized code for my MVC controller follows:
private static string _GoogleClientId = "CLIENT_ID";
private static string _GoogleSecret = "SECRET";
private static string _ReturnUrl = "http://localhost/OAuth/CallBack";
public ActionResult Index()
{
return Redirect(GenerateGoogleOAuthUrl());
}
private string GenerateGoogleOAuthUrl()
{
//NOTE: Key piece here, from Andrew's reply -> access_type=offline forces a refresh token to be issued
string Url = "https://accounts.google.com/o/oauth2/auth?scope={0}&redirect_uri={1}&response_type={2}&client_id={3}&state={4}&access_type=offline&approval_prompt=force";
string scope = UrlEncodeForGoogle("https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.readonly").Replace("%20", "+");
string redirect_uri_encode = UrlEncodeForGoogle(_ReturnUrl);
string response_type = "code";
string state = "";
return string.Format(Url, scope, redirect_uri_encode, response_type, _GoogleClientId, state);
}
private static string UrlEncodeForGoogle(string url)
{
string UnReservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
var result = new StringBuilder();
foreach (char symbol in url)
{
if (UnReservedChars.IndexOf(symbol) != -1)
{
result.Append(symbol);
}
else
{
result.Append('%' + String.Format("{0:X2}", (int)symbol));
}
}
return result.ToString();
}
class GoogleTokenData
{
public string Access_Token { get; set; }
public string Refresh_Token { get; set; }
public string Expires_In { get; set; }
public string Token_Type { get; set; }
}
public ActionResult CallBack(string code, bool? remove)
{
if (remove.HasValue && remove.Value)
{
Session["GoogleAPIToken"] = null;
return HttpNotFound();
}
if (string.IsNullOrEmpty(code)) return Content("Missing code");
string Url = "https://accounts.google.com/o/oauth2/token";
string grant_type = "authorization_code";
string redirect_uri_encode = UrlEncodeForGoogle(_ReturnUrl);
string data = "code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type={4}";
HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest;
string result = null;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
string param = string.Format(data, code, _GoogleClientId, _GoogleSecret, redirect_uri_encode, grant_type);
var bs = Encoding.UTF8.GetBytes(param);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
result = sr.ReadToEnd();
sr.Close();
}
var jsonSerializer = new JavaScriptSerializer();
var tokenData = jsonSerializer.Deserialize<GoogleTokenData>(result);
Session["GoogleAPIToken"] = tokenData.Access_Token;
return JavaScript("Refresh Token: " + tokenData.Refresh_Token);
}
Big thanks to Kelp for a bit of the code in this snippet.
Adjust GoogleAuthenticationServer.Description to have an authorization endpoint URI that includes ?access_type=offline in the query string.
Simply add
AccessType = "offline",
to GoogleOAuth2AuthenticationOptions() object.

Resources