Creating a new invoice - xero-api

I can see list of all invoices for organisations using the Xero OAuth 2 sample from Xero-NetStandard. I want to create a new invoice for a particular tenant/organisation, how do I create an invoice object and what should the POST Method look like? Below code is what I have so far :
public async Task<string> InvoicesPostAsync()
{
var token = await _tokenStore.GetAccessTokenAsync(User.XeroUserId());
var connections = await _xeroClient.GetConnectionsAsync(token);
List<string> allinvoicenames = new List<string>();
foreach (var connection in connections)
{
var tenantID = connection.TenantId.ToString();
var request = (HttpWebRequest)WebRequest.Create("https://api.xero.com/api.xro/2.0/Invoices");
var postData = "thing1=hello";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.Headers.Add("Authorization" , "Bearer "+ token);
request.Headers.Add("Xero-tenant-id" , tenantID);
request.ContentType = "application/x-www-form-urlencoded";
request.Credentials = CredentialCache.DefaultCredentials;
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
}

Out of curiosity, which OAuth2.0 sample are you referring to?
This sample app that I put together makes use of our new OAuth2.0 SDK - https://github.com/XeroAPI/xero-netstandard-oauth2-samples/tree/master/XeroOAuth2Sample
The same SDK can be used to create invoices. Below is a bit of sample code to do so
var invoice = new Invoice
{
Type = Invoice.TypeEnum.ACCREC,
Contact = new Contact
{
Name = "Some contact name"
},
Date = DateTime.Today,
DueDate = DateTime.Today.AddDays(7),
Status = Invoice.StatusEnum.DRAFT,
LineItems = new List<LineItem>
{
new LineItem
{
Description = "Manchester United Scarf",
Quantity = 1,
UnitAmount = 24.99,
AccountCode = "200"
}
}
};
var createdInvoice = await _accountingApi.CreateInvoiceAsync(accessToken, tenantId, invoice);

Related

The server committed a protocol violation. Section=ResponseStatusLine : Issue

I created ASP.NET core 6 API project and used JWT authentication for each API end point.
But while executing in some physical system works fine but some other physical system and server throws below error
The server committed a protocol violation. Section=ResponseStatusLine
Sample Code
var request = (HttpWebRequest)WebRequest.Create(endpoint);
var token = System.Threading.Tasks.Task.Run(async() => await new Token("URL", "username", "pwd"])).Result;
request.Headers.Add("Authorization", "Bearer " + token);
request.Method = "POST";
var postData = JsonConvert.SerializeObject(Details, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var data = Encoding.ASCII.GetBytes(postData);
request.ContentType = "application/json";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var responses = (HttpWebResponse)request.GetResponse();
Sample code based on HTTP Client
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), endpoint))
{
string token = SalesOperationAPIToken("url", "usertest", "pwd");
request.Headers.TryAddWithoutValidation("accept", "*/*");
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + token);
string json = JsonConvert.SerializeObject(Details);
request.Content = new StringContent(json);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = httpClient.SendAsync(request).Result;
var responseMessage = response.Content.ReadAsStringAsync().Result;
}
}
I am not sure what configuration need to be changed to get this worked in all system.
Thanks in advance.

Upload CSV data into SQL database using ASP.NET Core MVC

I am trying to insert data from a .csv file into my database, but anytime I upload data, the record is empty.
This is my code so far:
[HttpPost]
public async Task<IActionResult> ImportFromExcel(IFormFile formFile)
{
var data = new MemoryStream();
await formFile.CopyToAsync(data);
data.Position = 0;
TextReader reader = new StreamReader(data);
var csvReader = new CsvReader(reader, new CsvConfiguration(System.Globalization.CultureInfo.CurrentCulture)
{
HasHeaderRecord = true,
HeaderValidated = null,
MissingFieldFound = null
});
var Name = csvReader.GetField(0).ToString();
var dep = "cccccccccc";
var pos = "bbbbbbbbbbb";
await dcx.Participants.AddAsync(new Participant
{
Name = Name,
Position = pos,
Department = dep,
});
dcx.SaveChanges();
return ViewComponent("ViewParticipants");
}
This is the sample data in my database table:
As long as the headers of your CSV match up to the names of the columns in your database, you should be able to do something like this. If the names don't match, you can use .Name("CsvColumnName") in ParticipantMap to add the name of the column in the CSV file. Example: Map(r => r.Description).Name("MyCsvDescription");.
[HttpPost]
public async Task<IActionResult> ImportFromExcel(IFormFile formFile)
{
var data = new MemoryStream();
await formFile.CopyToAsync(data);
data.Position = 0;
var conf = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = true,
HeaderValidated = null,
MissingFieldFound = null,
BadDataFound = context =>
{
bad.Add(context.RawRecord);
}
};
using (TextReader reader = new StreamReader(data))
using (var csvReader = new CsvReader(reader, config)) {
csvReader.Context.RegisterClassMap<ParticipantMap>();
var records = csvReader.GetRecords<Participant>().ToList();
var dep = "cccccccccc";
var pos = "bbbbbbbbbbb";
records.ForEach(r =>
{
r.Department = dep;
r.Position = pos;
});
await dcx.Participants.AddRangeAsync(records);
dcx.SaveChanges();
}
return ViewComponent("ViewParticipants");
}
public class ParticipantMap : ClassMap<Participant>
{
public ParticipantMap()
{
AutoMap(CultureInfo.InvariantCulture);
Map(r => r.Department).Ignore();
Map(r => r.Position).Ignore();
}
}
In my opinion, you should call csvReader.Read() to read the file row first.
You can refer to the following test code, it works fine.
[HttpPost]
public async Task<IActionResult> ImportFromExcel(IFormFile formFile)
{
var data = new MemoryStream();
await formFile.CopyToAsync(data);
data.Position = 0;
using (var reader = new StreamReader(data))
{
var bad = new List<string>();
var conf = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = true,
HeaderValidated = null,
MissingFieldFound = null,
BadDataFound = context =>
{
bad.Add(context.RawRecord);
}
};
using (var csvReader = new CsvReader(reader, conf))
{
while (csvReader.Read())
{
var Name = csvReader.GetField(0).ToString();
var pos = csvReader.GetField(1).ToString();
var dep = csvReader.GetField(2).ToString();
await dcx.Participants.AddAsync(new Participant
{
Name = Name,
Position = pos,
Department = dep,
});
dcx.SaveChanges();
}
}
}
return ViewComponent("ViewParticipants");
}
Test Result:

GetDiscoveryDocumentAsync can not find the authority url - IdentiyServer4

I was trying to replace obsolete IdentityServer methods and types and as I had been warned about, I tried to replace DiscoveryClient() and TokenClient() with appropiate methods like in the examples of the latest identity server docs. When I try to get related endpoints by GetDiscoveryDocumentAsync it returns null even though I could read those values with current code and also get those values on browser.
Besides, when I by-pass the step of discovery and supplying the direct token endpoint RequestTokenAsync returns null because of Not Found exception.
For the sake of clearity of the question I should say that I have not changed anything (its settings or endpoints) in my Identity server project (from which I try to get access token).
Followings are my previous and updated code to achieve what I've described. Any help or suggestion is appreciated. Thanks in advance.
Previous Code (Working):
var testServer = new TestServer(builder);
var client = testServer.CreateClient();
client.BaseAddress = new Uri("http://localhost:5000");
var discoClient = new DiscoveryClient(AuthorityUrl) {Policy = {RequireHttps = false}};
var disco = discoClient.GetAsync().Result;
var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, ClientSecret);
var tokenResponse = tokenClient.RequestClientCredentialsAsync(Scope).Result;
client.SetBearerToken(tokenResponse.AccessToken);
Updated Code (Not Working):
var testServer = new TestServer(builder);
var client = testServer.CreateClient();
client.BaseAddress = new Uri("http://localhost:5000");
//var discoClient = new DiscoveryClient(AuthorityUrl) {Policy = {RequireHttps = false}};
var disco = client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest()
{ Address = AuthorityUrl, Policy = new DiscoveryPolicy() { RequireHttps = false, Authority = AuthorityUrl} }).Result;
;
if (disco.IsError)
{
throw new Exception(disco.Error);
}
//var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, ClientSecret);
var tokenClient = client.RequestTokenAsync(new TokenRequest()
{ Address = disco.TokenEndpoint, ClientId = ClientId, ClientSecret = ClientSecret, GrantType = GrantType}).Result;
//var tokenResponse = tokenClient.RequestClientCredentialsAsync(Scope).Result;
client.SetBearerToken(tokenClient.AccessToken);
return client;
Edit:
Updated my code as shown below and still getting the same error.
var testServer = new TestServer(builder);
var client = testServer.CreateClient();
client.BaseAddress = new Uri("http://localhost:5000");
//var discoClient = new DiscoveryClient(AuthorityUrl) {Policy = {RequireHttps = false}};
var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest()
{ Address = AuthorityUrl, Policy = new DiscoveryPolicy() { RequireHttps = false, Authority = AuthorityUrl } });
;
if (disco.IsError)
{
throw new Exception(disco.Error);
}
//var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, ClientSecret);
var tokenClient =await client.RequestTokenAsync(new ClientCredentialsTokenRequest()
{ Address = disco.TokenEndpoint, ClientId = ClientId, ClientSecret = ClientSecret, GrantType = GrantType , Scope = Scope});
client.SetBearerToken(tokenClient.AccessToken);
return client;
Error:
"Error connecting to AuthorityUrl/.well-known/openid-configuration: Not Found"

register user to .net core from mobile

i try to register user from xamarin in .net core with enabled Identity and membership system it return true but no user registered in database.
also i check with MVC web site and all things is Ok
my code is
using (var client = new HttpClient())
{
var model = new RegisterBindingModel
{
Email = email,
Password = password,
ConfirmPassword = confirmPassword
};
var json = JsonConvert.SerializeObject(model);
HttpContent httpContent = new StringContent(json);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync(
Constants.SignalrEndpointAddress + "Account/Register", httpContent);
if (response.IsSuccessStatusCode)
{
return true;
}
}
problem is in StringContent and my code ended up to this:
using (var client = new HttpClient())
{
var model = new Dictionary<string, string>
{
{"Email", email },
{"Password", password},
{"ConfirmPassword", confirmPassword},
};
var httpContent = new FormUrlEncodedContent(model);
var response = await client.PostAsync(
Constants.EndpointAddress + "Account/Register", httpContent);
if (response.IsSuccessStatusCode)
{
return true;
}
}
thanks

How can I upload a file to rackspace using RESTSharp and .net 4.0?

Here is what i have so far and it's not working:
private void _send1(string file)
{
var client = new RestClient("https://identity.api.rackspacecloud.com/v2.0");
var request = new RestRequest("tokens", Method.POST);
request.RequestFormat = DataFormat.Json;
string test = "{\"auth\":{\"RAX-KSKEY:apiKeyCredentials\"{\"username\":\"";
test += UserName;
test += "\",\"apiKey\":\"";
test += MyToken;
test += "\"}}}";
request.AddBody(serText);
request.AddParameter("application/json", test, ParameterType.RequestBody);
RestResponse response = (RestResponse)client.Execute(request);
// Content = "{\"badRequest\":{\"code\":400,\"message\":\"java.lang.String cannot be cast to org.json.simple.JSONObject\"}}"
}
note: UserName and apiKey are valid RackSpace credentials :-)
Thanks
In advance
Try 2: ( found this on the web ) and it gives me a token... now what do I do with it?
private void _send2(string file)
{
Dictionary<string, object> dictAuth = new Dictionary<string, object>();
dictAuth.Add("RAX-KSKEY:apiKeyCredentials", new { username = UserName, apiKey = MyToken });
var auth = new
{
auth = dictAuth
};
RestClient client = new RestClient("https://identity.api.rackspacecloud.com");
RestSharp.RestRequest r = new RestRequest("/v2.0/tokens", Method.POST);
r.AddHeader("Content-Type", "application/json");
r.RequestFormat = DataFormat.Json;
r.AddBody(auth);
RestResponse response = (RestResponse)client.Execute(r);
// Content = "{\"access\":{\"token\":{\"id\":\"AACCvxjTOXA\",\"expires\":\"2016-04-09T21:12:10.316Z\",\"tenant\":{\"id\":\"572045\",\"name\...
}
moving just a bit further:
I have create a class that parses out the URL, tenantID and token from Step 2 above
This data is passed to the PostFile call:
private void PostFile(string url, string tenantID, string token, string file)
{
string fName = Path.GetFileName(file);
RestClient client = new RestClient(url);
string baseURL = string.Format("v1/{0}/Support/{1}", tenantID, fName);
RestRequest r = new RestRequest(baseURL, Method.POST);
r.AddHeader("Content-Type", "text/plain");
r.AddParameter("X-Auth-Token", token);
r.AddFile(fName, file);
RestResponse response = (RestResponse)client.Execute(r);
if( response.StatusCode == System.Net.HttpStatusCode.OK)
{
int x = 0;
}
}
Here is what finally worked:
bool bRetval = false;
string fName = Path.GetFileName(file);
RestClient client = new RestClient(url);
string baseURL = string.Format("/Support/{0}", fName);
RestRequest r = new RestRequest(baseURL, Method.PUT);
r.AddHeader("Content-Type", "text/plain");
r.AddHeader("X-Auth-Token", token);
r.AddFile(fName, file);
RestResponse response = (RestResponse)client.Execute(r);
See the above post for the supporting functions that lead up to this one
private bool PostFile(string url, string token, string file)
{
bool bRetval = false;
string fName = Path.GetFileName(file);
RestClient client = new RestClient(url);
string baseURL = string.Format("/Support/{0}", fName);
RestRequest r = new RestRequest(baseURL, Method.PUT);
r.AddHeader("Content-Type", "text/plain");
r.AddHeader("X-Auth-Token", token);
r.AddFile(fName, file);
RestResponse response = (RestResponse)client.Execute(r);
if ( response.StatusCode == System.Net.HttpStatusCode.Created)
{
bRetval = true;
}
return bRetval;
}