Multiple Endpoints in same controller with different parameter - asp.net-core-mvc

Been years since I had to do this and the heat must be getting to me!
I have my home controller:
public ActionResult Index(string param1, string param2, string param3)
{
return View();
}
public IActionResult Index()
{
return View();
}
I have 1 Index.cshtml page.
In my startup,cs:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}");
endpoints.MapControllerRoute(
name: "default2",
pattern: "{controller=Home}/{action=Index}/{param1}/{param2}/{param3}");
});
The error I get is:
**{"error":"APP: The request matched multiple endpoints.

public class HomeController : Controller
{
// hits when navigating to https://localhost:5001/one/two/three
[HttpGet("{param1}/{param2}/{param3}")]
public IActionResult Index(string param1, string param2, string param3)
{
return View();
}
// hits when navigating to https://localhost:5001/
public IActionResult Index()
{
return View();
}
}
and in Startup#Configure
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});

I tried this,
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
namespace RouteTemplateProvider.Controllers
{
public class RouteWithParamAttribute : Attribute, IRouteTemplateProvider
{
public string Template => "{param1}/{param2}/{param3}";
public int? Order { get; set; }
public string Name { get; set; }
}
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
[RouteWithParam]
public string Index(string param1, string param2, string param3)
{
return "Index with param";
}
public string Index()
{
return "Index no param";
}
}
}

Related

Web API PUT 400 Bad Request

I have a HttpPut annotated Insert method in a controller and when I want to insert a new dto with it it returns a Bad Request 400 error.
public class BaseDto
{
public int Id { get; set; }
...
}
public class ModelDto : BaseDto
{
public string Name { get; set; }
...
}
[Produces("application/json")]
[Route("api/[controller]")]
public class ExampleController : MyControlle
{
...
[HttpPut]
public IActionResult Insert([FromBody] ModelDto model)
{
_service.Insert(model, _user);
return Ok();
}
}
I tried it with an API client in Edge with this URL:
http://localhost:52073/api/Example
with this JSON:
``
{
"award_Id":1,
"nameOfTheAwardee":"zgghjggf",
"titleOfTheAwardee":"XXX",
"reasonForAwarding":"zzhfhf",
"numberOfDecision":"876",
"yearOfAwarding":"2022"
}
``

Web Api take an array from front

The question is very simple :-).
I'm a beginner.
Data comes to the controller (WebApi).
If you put an object.
[HttpPost]
public async Task<IActionResult> AddOrder(Object [] orderR)
ValueKind = Object : "{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-
08d8db1aac26","code":"666666","name":"test6","price":6,"category":"test6","orrderItems":"320d57eb-
3333-45d2-f497-08d8d66a0d39"},"quality":1}"
ValueKind = Object : "{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-
08d8db1aac26","code":"666666","name":"test6","price":6,"category":"test6","orrderItems":"320d57eb-
3333-45d2-f497-08d8d66a0d39"},"quality":1}"
ValueKind = Object : "{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-
08d8db1aac26","code":"666666","name":"test6","price":6,"category":"test6","orrderItems":"320d57eb-
3333-45d2-f497-08d8d66a0d39"},"quality":1}"
I created a class.
public class OrderR
{
public Guid ID { get; set; }
public Guid orrderItems { get; set; }
public string CODE { get; set; }
public string NAME { get; set; }
public int PRICE { get; set; }
public string CATEGORY { get; set; }
}
I am trying to get an array.
[HttpPost]
public async Task<IActionResult> AddOrder(OrderR[] orderR)
But get null.
What am I doing wrong?
How is it correct?
Create new class:
public class Order
{
public OrderR Product { get; set; }
public int Quality { get; set; }
}
and change your action to this:
[HttpPost]
public async Task<IActionResult> AddOrder(Order[] orders)
{
.... your code
}
it was tested in Postman using this data:
[
{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-08d8db1aac26","code":"666666","name":"test1","price":6,"category":"test6","orrderItems":"320d57eb-3333-45d2-f497-08d8d66a0d39"},"quality":1},
{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-08d8db1aac26","code":"666666","name":"test2","price":6,"category":"test6","orrderItems":"320d57eb-3333-45d2-f497-08d8d66a0d39"},"quality":1},
{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-08d8db1aac26","code":"666666","name":"test3","price":6,"category":"test6","orrderItems":"320d57eb-3333-45d2-f497-08d8d66a0d39"},"quality":1}
]
and everything works fine. If you want to test it in Postman too, add [FromBody] to the action input parameter:
[HttpPost]
public async Task<IActionResult> AddOrder([FromBody] Order[] orders)
{
return Ok(orders);
}

InvalidOperationException While Using the Existing DB in MVC Core

I tried to use the existing database in my application but every time I hit the view it says
An unhandled exception occurred while processing the
InvalidOperationException: Unable to resolve service for type
'BookStore.Models.BookStoreContext' while attempting to activate
'BookStore.Models.UsersRepo'
Context
namespace BookStore.Models
{
public partial class BookStoreContext : DbContext
{
public BookStoreContext()
{
}
public BookStoreContext(DbContextOptions<BookStoreContext> options)
: base(options)
{
}
public virtual DbSet<Users> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\V11.0;Database=BookStore;Trusted_Connection=True;");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("ProductVersion", "2.2.3-servicing-35854");
modelBuilder.Entity<Users>(entity =>
{
entity.HasKey(e => e.UserId);
entity.Property(e => e.UserId).HasColumnName("User_ID");
entity.Property(e => e.Password)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.UserName)
.IsRequired()
.HasColumnName("User_Name")
.HasMaxLength(50);
});
}
}
}
User Repository
namespace BookStore.Models
{
public class UsersRepo : IUser
{
private readonly BookStoreContext _bookStoreContext;
public UsersRepo(BookStoreContext bookStoreContext)
{
_bookStoreContext = bookStoreContext;
}
public void AddUser(Users users)
{
_bookStoreContext.Users.Add(users);
_bookStoreContext.SaveChanges();
}
}
}
User Model
public partial class Users
{
public long UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int Type { get; set; }
}
public interface IUser
{
void AddUser(Users users);
}
User Controller
public class UsersController : Controller
{
private readonly IUser _userRepo;
public UsersController(IUser userRepo)
{
_userRepo = userRepo;
}
[HttpGet]
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Index(Users users)
{
_userRepo.AddUser(users);
return RedirectToAction("UserAddedSuccessfully");
}
public IActionResult UserAddedSuccessfully()
{
return View();
}
}
I tried this one and it is perfectly working
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<BookStoreContext>();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}

html.dropdownlistfor() troubles...getting null reference exceptions

I've tried to follow a few examples from here and a couple other resources to just create a very simple member in my viewmodel and display it as a dropdown list on my view with a dropdownlistfor() helper. I can't seem to wrap my head around it and it's not working with what I'm trying.
here's my viewmodel:
public class Car
{
public int CarId { get; set; }
public string Name { get; set; }
}
public class MyViewModel
{
public IEnumerable<Car> Cars = new List<Car> {
new Car {
CarId = 1,
Name = "Volvo"
},
new Car {
CarId = 2,
Name = "Subaru"
}
};
public int MyCarId { get; set; }
}
and here is my view:
#Html.DropDownListFor(m => m.MyCarId, new SelectList(Model.Cars, "CarId", "Name"))
and here is my controller:
public ActionResult MyView()
{
return View();
}
You need to make sure you send the Model to your View:
public ActionResult Index()
{
var myViewModel = new MyViewModel()
return View(myViewModel);
}
And in your View you need to make sure you're defining your Model:
#model namespace.MyViewModel
You example works fine, I think you forgot to send MyViewModel in POST Action.
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}

ASP MVC 3 - Localization with LocalizationDisplayNameAttribute

Can somebody tell me what I'm doing wrong in this code:
public class LocalizationDisplayNameAttribute : DisplayNameAttribute
{
public LocalizationDisplayNameAttribute(string resourceKey)
{
ResourceKey = resourceKey;
}
public override string DisplayName
{
get
{
string displayName = App_GlobalResources.Global.ResourceManager.GetString(ResourceKey);
return string.IsNullOrEmpty(displayName)
? string.Format("[[{0}]]", ResourceKey)
: displayName;
}
}
private string ResourceKey { get; set; }
}
The culture is set to cs. I have two resources: Global.resx and Global.cs.resx, but when I run this application I always get string from Global.resx (it should be Global.cs.resx)
The following works fine for me:
public class LocalizationDisplayNameAttribute : DisplayNameAttribute
{
public LocalizationDisplayNameAttribute(string resourceKey)
{
ResourceKey = resourceKey;
}
public override string DisplayName
{
get
{
string displayName = Global.ResourceManager.GetString(ResourceKey);
return string.IsNullOrEmpty(displayName)
? string.Format("[[{0}]]", ResourceKey)
: displayName;
}
}
private string ResourceKey { get; set; }
}
View model:
public class MyViewModel
{
[LocalizationDisplayName("foo")]
public string Foo { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
}
View:
#model MyViewModel
#Html.LabelFor(x => x.Foo)
#Html.EditorFor(x => x.Foo)
Resources:
~/App_GlobalResources/Global.resx:
foo: foo
~/App_GlobalResources/Global.cs.resx:
foo: localized foo
~/web.config:
<system.web>
<globalization culture="cs" uiCulture="cs"/>
...
</system.web>
prints the correct localized value.

Resources