List all Azure DevOps Projects with Reactjs - c#

I want to list all the projects that were returned from my API call with React. I currently only have the C# code that gets all the projects that the user has authorization for and displays it in JSON format. Hardcoded the personalaccesstoken in the code (because I don't know how else to do it tbh). Now, I wish to list all the projects returned with React so that the user can select the desired project they want to work on from a dropdown menu.
I have little experience with React and have never used it with REST API's.
( If someone has the answer to the question above, I would greatly appreciate the help with another problem. I'm also trying to create a new repository in the project that the user has selected, and I want them to be able to specify the name of this repository with an input field. Once the user has specified the desired repository name and chosen the project from the dropdown menu, they should be able to hit "Submit" in order to start a POST Request to the REST API and create the new repository in the project. This will also be done with React. )

You may need check this code repos: azure-devops-node-api-sample. We have done provide the sample code in that repo.
Get project:
public async getProjects(
stateFilter?: any,
top?: number,
skip?: number,
continuationToken?: string,
getDefaultTeamImageUrl?: boolean
): Promise<CoreInterfaces.TeamProjectReference[]> {
return new Promise<CoreInterfaces.TeamProjectReference[]>(async (resolve, reject) => {
let routeValues: any = {
};
let queryValues: any = {
stateFilter: stateFilter,
'$top': top,
'$skip': skip,
continuationToken: continuationToken,
getDefaultTeamImageUrl: getDefaultTeamImageUrl,
};
try {
let verData: vsom.ClientVersioningData = await this.vsoClient.getVersioningData(
"6.0-preview.4",
"core",
"603fe2ac-9723-48b9-88ad-09305aa6c6e1",
routeValues,
queryValues);
let url: string = verData.requestUrl!;
let options: restm.IRequestOptions = this.createRequestOptions('application/json',
verData.apiVersion);
let res: restm.IRestResponse<CoreInterfaces.TeamProjectReference[]>;
res = await this.rest.get<CoreInterfaces.TeamProjectReference[]>(url, options);
let ret = this.formatResponse(res.result,
CoreInterfaces.TypeInfo.TeamProjectReference,
true);
resolve(ret);
}
catch (err) {
reject(err);
}
});
}
You can continue to check this sample page, it shows you many samples including create project.

Related

Get data from a table after having closed the session

In this moment I´m try to get a List of users and checks if the user is in the BD or not
I´m using Web API Net 6 and Sql Server
This is the code
[HttpPost("login")]
public async Task<ActionResult<string>> Login(LoginDto request)
{
//In this line I´m try to get the list of users (this bottom line doesn't work)
await _context.Users.ToListAsync();
if(user.UserName != request.UserName)
{
return BadRequest("User Not Found");
}
// ...
Here the problem is that the program has been running for 1 time until it works normally but when I end the session and come back again there is an application on the 2nd time it can no longer find the user in the database. My idea then is to add that line of code that just doesn't work (I don't know if it's due to await or if it's wrong to get through ListAsync() or if it's due to the user inside the if not being connected with the _context of the database )
By the way, that user is static having declared it like this
-> public static User user = new User();
Can anyone help me with this problem or tell me better solutions on how to get data from a table
If you just want to search your Users table for a user record with the name passed in the LoginDTO instance, then you just ask it to the database context to search for that name.
var userInDb = await _context.Users.FirstOrDefaultAsync(x => x.UserName == request.UserName);
if(userInDb == null)
... not found ....
But let me understand better your problem. If you are implementing your custom authorization and verification infrastructure for users, then think twice becase is not as simple as it looks. (For example, how do you store passwords in that table?) There is a dedicated library for that from Microsoft and is called ASP.NET Identity

How do I Display a Message across projects?

We have one Visual Studio 2019 ASP.NET solution with 22 projects, one of which is called BusinessLogic and one which is called Web.
In BusinessLogic, we have code to log errors, and it used by all projects in the solution.
public static Guid? StartDebugLog(String module, String method, String message)
{
if (ApplicationSettings.IsDebugLogActive)
{
using (BPIContext context = SessionManager.CreateNewBPIContext)
{
DebugLog debugLogObject = new DebugLog();
debugLogObject.ID = Guid.NewGuid();
debugLogObject.Module = module;
debugLogObject.Method = method;
debugLogObject.StartTime = DateTime.Now;
if (message == null)
debugLogObject.Message = "(NULL)";
else
debugLogObject.Message = message;
context.AddToDebugLog(debugLogObject);
context.SaveChanges();
return debugLogObject.ID;
}
}
return null;
}
The problem is that this routine is hiding important errors from our customers. Yes, they can go into the application logs, but simply starting the application creates over 100 entries in the application log. Finding errors would be a daunting task to ask of our customers.
I need a way for this routine to be able to display a basic message so that customers do not continue on, thinking everything is OK. Something like alert("An error has occurred."), but the *BusinessLogic project does not have access to the Web project.
Is there a recommended way to create a CALLBACK or something? Most of my background is in Windows Forms where this would be simple. Something like this:
...
context.AddToDebugLog(debugLogObject);
context.SaveChanges();
if (WebCallback != null)
{
WebCallback(debugLogObject);
}
return debugLogObject.ID;
...
I'm not even sure if this is possible in a Web environment. If it is not possible, that's an answer too.
For a "Part 2", some of our newer modules are displayed by dropping them into an iFrame. Is there a way to create something that will allow information from the iFrame to pass to the parent? Currently, all messages that are sent in the iFrame appear to get lost.

How to properly load heavy collection?

I'm learning ASP.NET Core and I have some doubts about the loading of an heavy collection of records, let me explain better.
What I'm trying to do
In my application, after the login execution, the user will redirected to the Dashboard Home View. The Dashboard is the place that contains all the functions for an user. The Dashboard Controller have also other Views like:
Home
Analysis
Performance
Now each View need to display to the user a Table which contains a list of Products, at the bottom of this Table there is the content of the View.
Problem
First problem: is the Table redundancy code, which I solved creating a _PartialView that contains the html of the Table that contains the products to display. Coming from c# + WPF I used the same logic of UserControl, so this is a good solution for me.
Second problem: the products to display inside the Table, these products are downloaded from an API, now as I said before, these records must be always displayed in the products Table (which is available in different View using the _PartialView). Imagine that every time the user click on a Dashboard item (which load a Dashboard View), the Dashboard Controller will call this method:
public async Task<List<Products>> GetProducts(string date)
{
var client = new RestClient(Url);
var request = new RestRequest("product/get_products/{date}", Method.GET);
request.AddUrlSegment("date", date);
var cancellationTokenSource = new CancellationTokenSource();
var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
List<Products> products = JsonConvert.DeserializeObject<List<Product>>(response.Content);
return products;
}
For me, this is not a really good practice because each time the _PartialView will call this method and reload the data, so I need to store somehow this data (a temp store). How can I store these records to the user session without reload each time the _PartialView being called?
Between, I have some doubts about the API method:
Should I place all the API calls inside the Service folder? Repository folder? Or Controller folder?
Folder tree
View <- Folder
Dashboard <- Folder
Home
Analysis
Performance
_ProductsTable
The View Home, Analysis, Performance load _ProductsTable in the following way:
#await Html.PartialAsync("_LeftSidebar")
Use view components. They're essentially self-contained modules of functionality that return views, which you can embed in other views, without main view or action having to know about any of it.
First, create a directory call ViewComponents. Inside add new class, like ProductsViewComponent. Then, you'll want something like:
public class ProductsViewComponent : ViewComponent
{
private readonly HttpClient _client;
public ProductsViewComponent(HttpClient client)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
}
public async Task<IViewComponentResult> InvokeAsync(string date)
{
using (var response = await _client.GetAsync($"/"product/get_products/{date}"))
{
response.EnsureSuccessStatusCode();
var products = await response.Content.ReadAsAsync<List<Product>>();
return View(products);
}
}
}
Then, create the view, Views\Shared\Components\Products\Default.cshtml. Inside, add the HTML to render your list of products. Finally, where you want the product table to appear add:
#await Component.InvokeAsync("Products", new { date = myDate })
The above code uses HttpClient rather than RestClient, since honestly, it's completely unnecessary at this point to have a separate library for making HTTP calls. HttpClient is built-in and has been extended with functionality in Core to make this much easier, such as the ReadAsAsync method used above, which transparently deserializes your JSON response into the generic type argument. Additionally, you now have things like IHttpClientFactory which ensures that you have properly scoped HttpClient instances. As a result, the above code also assumes adding something like the following to your Startup.cs:
services.AddHttpClient<ProductsViewComponent>(c =>
{
c.BaseAddress = new Uri('https://api.myservice.com');
// add default headers and such if you need them
});
You can also then use the Polly integration to setup automatic retries, circuit breakers, etc., allowing you handle all sorts of API scenarios such as temporarily unavailable, rate limits, etc. See the full documentation for both IHttpClientFactory and its Polly integration for more info.
Lastly, if this is a scenario where you don't need realtime data, you can also inject an instance of IDistributedCache into your view component and add logic to set the result of your API call in that, and retrieve it from there first, before making the call again, allowing you to significantly reduce the load both on your app and the API (especially if do have something where rate limits apply).

Angular Material AutoComplete Not Loading Options MVC

I am working on my AutoComplete widget, using Angular JS - Material, in C# ASP.NET MVC.
In this example, I'm trying to get an AutoComplete of States to work. I started with this tutorial, but need to have the options come from the database (at this point, just static list of options in the controller).
Here is a link to my current code (relevant files).
When I run the code, I can see that the list of objects from the controller are pulling through properly - an array of 4 objects, each with an Id and a Name (as shown in my controller method). However, the options are not being loaded into the input form.
When I click into the textbox, I get an "option" that says No states matching "" were found. If I type in 'a', I get the "option" that says No states matching "a" were found. This is what I would expect to happen if there actually were no matching results.
My question: How do I change my code to load the options with what I'm pulling from the controller?
Thanks in advance!
Here's a screen shot of the results:
Here's the key JavaScript/AngularJS code:
//TODO: Replace data.json with /Home/GetStates
$http.get('data.json')
.then(function(response) {
self.states = response.data.map(function(state) {
return {
value: state.Name.toLowerCase(),
display: state.Name
};
});
});
You'll need to replace 'data.json' with '/Home/GetStates' for it to call your backend MVC JSON RESTful API Service. Note that I also left the functions querySearch(query) and createFilterFor(query) in place and changed self.states=loadStates() to self.states=null since the $http.get() service will now load the states.
I did test your C# MVC controller code and everything looks good with it.
Here's a working Plunker, http://plnkr.co/edit/tDC6KcO1O8VSGwVghBo7?p=preview.
Hope this helps. Let me know if you need anything else.
Here's what I did to fix the problem:
Changed to POST
Set variable = result, then returned the results
Here's the code:
function querySearch(query) {
if (query == undefined) {
console.log("invalid");
return;
}
$http({
method: 'POST',
url: self.URL_Get + query,
searchTerm: query
}).then(function(response) {
self.states = response.data;
});
return self.states;
}

ajax submit to WebAPI controller

I'm not sure of the best way to accomplish my goal. Looking for insight. I'm familiar with WebAPI services consumed through WPF and Silverlight but this is my first run at ASP and MVC.
I am building a site to verify contents of a shipment against an electronic manifest (EDI 856). I have a page that displays the shipping data and I need the users to scan each item barcode in the container. I would then like to pass that barcode to a service, verify the item belongs in that shipment and then update the page to show as much.
My plan was to have a single text box into which the user could scan/type the barcode and then submit that data to a WebAPI service which would verify the information and then probably use SignalR to send a message back to the page and update a grid with the item data.
If this is a decent way to go, I'm just not quite sure how to use ajax to call the WebAPI endpoint and provide the data I need.
I would advise against using SignalR in this situtation. What you need, judging from your description, is the most basic use case of submitting an ajax request and receiving a response.
You are not designing a system where you need the server to initiate communication with the browser or anything like that, where sockets (and SignalR as an abstraction over sockets with fallbacks to less suitable protocols) is a huge overkill.
Don't worry, your use case is rather simple.
It's a little out of scope to describe how to setup a WebApi project, how to configure routing, action names, etc. Simple google searches will surely provide ample quality tutorials on getting started.
I'll just try to explain what the general idea is, with some code samples, to get you thinking in the right direction.
You need to create an ApiController.
The simplest version of that Controller will probably look something like this:
public class ShipmentVerificationController : ApiController
{
//this is the response object you will be sending back to the client website
public class VerificationResult
{
public bool Valid;
}
public VerificationResult GetIsItemValid(string BarCode)
{
bool itemIsValid;
// Implement checks against the BarCode string here
itemIsValid = true;
return new VerificationResult { Valid = itemIsValid };
}
}
Note that the inner class represents the response you will be sending back. It should be properly filled out with additional info if needed and probably put into a separate .cs file in the "Models" folder or where ever you see fit.
I have declared it inside the controller for demonstration purposes only
Once you have a WebApi service deployed, it's really easy to send it data from your website and receive the feedback.
To simplify Ajax requests, jQuery is often used.
Once the user inputs the barcode into a textbox, you can hook up an event to check for return key being pressed (most barcode scanners send the return key command after they input the barcode data) and then write something along the lines of:
var barcode = $("#input-field").val();
$.getJSON( "<url_to_your_webapi_service>/api/ShipmentVerification/GetIsItemValid/" + barcode, function( data ) {
if (data.Valid) {
// great, highlight the item as valid
}
else {
//better indicate an error with the scanned item
}
});
Please note that for simplicity I have not included any error handling, url parameter encoding, and most importantly, zero authorization.
Authorization is very important if you deploy the web service to the open web but still do not want anyone to be able to call it.
You will have to research these topics yourself, but I hope I have presented you the core concepts and logic behind a simple service such as this, so you have a base to start with.
If you come up with specific problems and questions post a new question.
I actually found a more simple way to do this. I nixed the idea of using a WebAPI endpoint and just went with a normal controller. I used ajax to prevent the page from refreshing with the new view, since that view is actually just json data with my return values in it.

Categories

Resources