How to create a basic web api to get data - asp.net

Trying to create a basic web api for my database table where anyone can view my table data using a URL (JSON format?). My understanding is that I should be able to get my data by typing in table name in URL.
my database table name is myTable which is mapped to model class My_Model
Issue: There are no errors but when i try to type in url https://localhost:7048/myTable/ it return page not found
[Route("[controller]")]
[ApiController]
public class My_Controller : Controller
{
public My_Services _services { get; }
public My_Controller(My_Services services)
{
this._services = services;
}
// Database Table Name = "myTable"
[HttpGet]
public IQueryable<My_Model> Get()
{
return (IQueryable<My_Model>)_services.Get_All_Data();
}
public IActionResult Index()
{
return View();
}
}
My_Services class - where get all data from table
public async Task<IQueryable<My_Model>> Get_All_Data()
{
IQueryable<My_Model> Query = from x in _context.My_DbSet
select x;
return Query;
}

My understanding is that I should be able to get my data by typing in
table name in URL.
No, this is not how it works. You should check Routing to controller actions in ASP.NET Core. In your example you should be able to access your data using this url: https://localhost:7048/My_. The reason is that your controller has the attribute [Route("[controller]")]. [controller] is a special value which means that the route should be the controller class name without the Controller suffix so My_ in this case.
If you want to have access using this url: https://localhost:7048/myTable then you need to either change the attribute to this: [Route("myTable")] or to change the controller class name to MyTableController.
Also your Get method looks wrong. You should await the _services.Get_All_Data method instead of casting to IQueryable<My_Model>:
[HttpGet]
public async Task<IQueryable<My_Model>> Get()
{
return await _services.Get_All_Data();
}

Related

.Net: Does controller have to have file name corresponding to URL?

I'm following this tutorial on .Net controllers, and it says "imagine that you enter the following URL into the address bar of your browser: http://localhost/Product/Index/3. In this case, a controller named ProductController is invoked."
What I Want To Know:
In order to successfully hit http://localhost/Product/Index/3, do you need a controller called ProductController specifically?
No, it is not necessary. You can use Route Attribute.
[Route("new-name-for-product")]
public class ProductController{
}
now you have to use http://localhost/new-name-for-product/Index/ this URL to invoke ProductController.
If you want to use one or more parameters with this URL you have to use different route templates for ActionMethod. Example below.
[Route("new-name-for-product")]
public class ProductController
{
// http://localhost/new-name-for-product/3/ will show product details based on id
// http://localhost/new-name-for-product/Index/3/ will show product details based on id
[HttpGet]
[Route("/{id}")]
public IActionResult Index(int id)
{
// your code
}
// you can use a different action method name.
// http://localhost/details/3/ will show product details based on id
// but parameter name (Ex: id) and the id inside route template the spelling must be the same.
[HttpGet]
[Route("details/{id}")]
public IActionResult GetById(int id)
{
// your code
}
}
It depends. In ASP.Net Core, routing can be configured either as conventional routing or as attribute routing.
Conventional routing is configured as below:
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
Here, the first path segment maps to the controller name,
the second maps to the action name,
the third segment is used for an optional id used to map to a model entity.
As a convention, controller file name is usually same as controller class name.
Hence, In conventional routing, url will match with filename.
The URL http://localhost/Products/Index matches below action method in ProductsController.
[Route("[controller]")]
public class ProductsController : Controller
{
[HttpPost("Index")] // Matches 'Products/Index'
public IActionResult Index()
{
return View();
}
}
Attribute Routing
With attribute routing the controller name and action names play no role in which action is selected.
Hence, it is independent of file name.
The URL http://localhost/Items/All matches below action method in ProductsController.
public class ProductsController : Controller
{
[Route("Items/All")]
public IActionResult Index()
{
return View();
}
}
Similarly, [Route] attribute can be added at both Controller and action methods. The same URL http://localhost/Items/All matches the action method shown below:
[Route("Items")]
public class ProductsController : Controller
{
[Route("All")]
public IActionResult Index()
{
return View();
}
}
For more details, you can refer to microsoft docs at https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.1

What's the difference between [HttpGet] and [HttpGet("{id}")]?

What are the differences between HTTPGET method and HTTPGET("{id}") method?
What is the API method that is used to update table columns?
[HttpGet]
public IActionResult Get()
{
return new JsonResult(users);
}
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id)
{
return new JsonResult(response);
}
You should take a look at Attribute Routing in Web API.
The first method is routing to a clean api:
/api/controller
The second specifies route value in the attribute and will be called via the following url:
/api/controller/5
The second one is normally used to update existing queries, as you specify specific value in the route whilst the first specifies nothing.

ASP.Net Model without DbContext?

I am new to ASP.Net, if my question sounds very basic, please be polite.
I have created a ASP.Net MVC4 project. A page in the application will display names of the files in tabular form.
The names of the files are obtained by finding files in a particular folder on the server. So there is no need for me to have a database for model.
When user opens the page, the server side code will list all the files in the directory and should return a list of Strings.
I am following ASP.Net MVC tutorial here and it appears I have to have a DBContext class and also a database. In my case that's not needed
So that question is can I add my model without having to add code like below and still be able to use the feature of model ? any simple example would be great.
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
Any class can serve as a model in this case. For example, if you just want to have a Movie model, you can have something as simple as this:
public class Movie
{
public string Title { get; set; }
}
A view can bind to that model, to an enumeration of that model, etc.
For fetching your data from the file system, one approach could be a simple factory method on that model. Maybe something like this:
public class Movie
{
public string Title { get; set; }
public static IEnumerable<Movie> GetMovies()
{
// get the list of movies from the file system, for example as a list of strings
var movies = SomeFileSystemInteraction();
return movies.Select(m => new Movie { Title = m });
}
}
Then in your controller you can get the list of movies to bind to the view:
public ActionResult Index()
{
return View(Movie.GetMovies());
}
There's no need for a database, it's just used in tutorials because it's the most common case. But you can bind your views to any object you'd like.
You do not need that MovieDBContext class if you are not dealing with database. But having a model is a good idea to represent your entity(in this case the Folder). It is just a POCO class.
public class Folder
{
public string Name { set;get;}
public int NumberOfchilds { set;get;}
//Other properties as needed.
}
Now you can use the Model class to pass data between differnt places. For example. You can move the code which reads the data from file system to a Service class method and the method can return a list of this class/A single instance of this class as needed. Your controller action method can call the service method.
public class FolderService
{
public Folder GetRecentlyCreatedFolder()
{
var folder=new Folder();
//Set the properties of this object
// folder.Name="MySecret";
return folder;
}
}
and in your Action method
public ActionResult Items()
{
var srv=new FolderService();
var recentFolder=srv.GetRecentlyCreatedFolder();
return View(recentFolder);
}
Yes, you can use a model which is not stored in a database at all. Your case sounds like an obvious example.
Model, View, Controller makes database access easily abstractable but doesn't necessitate a database.
As much as I like entity framework I've never loved how most tutorials for MVC seem to marry the two - They are essentially unrelated and I think it really muddies the waters for a lot of programmers new to the framework.
All you need for a model is just a plain old class. Instead of using the dbcontext you'd simply use whatever code you need to load your data.

Pass Multiple params in ASP.NET MVC

First of all, I'm still a beginner in MVC
Obviously anyone knows that we can pass by /CONTROLLER/METHOD/ID, but in some cases, like I need to pass 3-4 params into the controller, how should I do? Is there a good way of passing them all?
The code below is a controller dealing with post request, why I cannot use the "temp1"? it said that one should be declared before use, what that means?
[HttpPost]
public ActionResult Payment_Home(Wires_SWIFT temp1){
string str = temp1.BENEFICIARY_NAME;
DbQuery<Wires_SWIFT> dbq = db.Wires_SWIFT.Where(d => d.BENEFICIARY_NAME LIKE temp1.);
return View();
}
Use a ViewModel.
This is a class that contains all the values you need - you populate it in the controller action and pass it in to the view (helps if the view is strongly typed to the model.
public class MyModel
{
public string SomeValue { get; set; }
public string SomeOtherValue { get; set; }
}
// controller
var myModel = new MyModel...
return View(myModel);
// view
#model MyModel
#Model.SomeValue
You need to make sure you have a route set correctly.
so to match dothis/action/param1/param2 you'd want a route like:
routes.MapRoute(
"MyRoute", // Route name
"{controller}/{action}/{param1}/{param2}", // URL with parameters
new { controller = "Surveys", action = "Index", param1 = "param1", param2 = "param2" } // Parameter defaults
);
For the above route to actually work, you'll need a controller and action such as
public class DoThisController : Controller
....
public ActionResult Action(int param1, int param2)
....
The type of the action parameters doesn't matter, but the name should match the name defined in the rule to allow the action to be located by ASP.Net
In your case, the error is because your parameter is called temp1 & in the route data there is nothing called that.

ASP.net MVC create model with value with multiple options

I am wanting to create a Model that has a property of Service which then has multiple options that can either be true or false. So my Contact Class:
public class Contact
{
//My Properties
}
I want the Contact class to have a property of Services. I have a list of services available. How can I reference my services from my Contact class. I would like be able to access it in my view like: model.services.MyCustomService if it's even possible. I come from a javascript background so this is what I mean but written in javascript if it helps.
Javascript Example
var Contact = {
property: "",
services: {
MyCustomService: "",
MyCustomService2: "",
}
}
Here's how I'd do it:
In your Model:
public class Contact
{
//My Properties
public List<Service> Services
{
get;
set;
}
}
In your Controller:
public ActionResult Index()
{
var model = new Contact(); // Create model
// Create some sample services
var service = new Service();
var service2 = new Service();
// Add the services
model.Services.Add(service);
model.Services.Add(service2);
// Pass the model to the view
return View(model);
}
Then, in your view:
#model MySite.Models.Contact
#foreach (var service in Model.Services)
{
<text>Here's my service: #service.MyCoolProperty.ToString()</text>
}
In that simple example, I first declared the Services property of your Contact class as a List<Service>. That allows you to combine many Services into one property - perfect for passing along to a view.
Next, in the Controller, I added some Services to the List by using the Add() method. Therefore, in the View, you're now able to access those Services through Model.Services.
To me, that looks like one of the simplest ways to approach this common problem. Hope that helped!
In C#, every object has a type so Services property has to have an actual type if you want to reference MyCustomService and MyCustomService2 through dot notation:
class Contact {
public ServiceContainer Services { get; set; }
}
class ServiceContainer {
public Service1 Service1 { get; set; }
public Service2 Service2 { get; set; }
}
However, if container serves for no other purpose but to store a service (assuming it's some object), you should probably store them in a list or array (access by index) or in a dictionary (access by string).
To give you more information, I'll need to know what exactly these services are, whether you expect their set to change, do they have different types, etc.
To bind to a collection all you need is this:
<%# Page Inherits="ViewPage<IList<Book>>" %>
A complete explanation can be found here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Resources