英文:
InvalidOperationException: Multiple handlers matched. The following handlers matched route data and had all constraints satisfied: in razorpage c# app
问题
抱歉,以下是您提供的代码的翻译:
我正在开发一个 Web 应用程序,使用 Razor Pages 和 C# 为我工作的公司执行盈余操作。我正在使用 LDAP 进行用户身份验证,以验证用户的用户名和密码,并将用户的名字和姓氏传递到欢迎消息,显示在盈余页面上。但是,当用户使用有效的帐户登录时,尝试加载盈余表单页面时出现以下错误:
未处理的异常发生在处理请求时。
InvalidOperationException:匹配到多个处理程序。以下处理程序匹配了路由数据,并且所有约束都得到满足:
Void OnGet(),Void OnGet(System.String,System.String)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageHandlerMethodSelector.Select(PageContext context)
堆栈查询 Cookie 标头路由
InvalidOperationException:匹配到多个处理程序。以下处理程序匹配了路由数据,并且所有约束都得到满足:Void OnGet(),Void OnGet(System.String,System.String)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageHandlerMethodSelector.Select(PageContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next,ref Scope scope,ref object state,ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker,Task lastTask,State next,Scope scope,object state,bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next,ref Scope scope,ref object state,ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker,Task task,IDisposable scope)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker,Task task,IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint,Task requestTask,ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
以下是我的 loginpage.cs 代码:
using System.DirectoryServices.AccountManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Surplus.Pages
{
public class LoginModel : PageModel
{
[BindProperty]
public string Username { get; set; }
[BindProperty]
public string Password { get; set; }
public string ErrorMessage { get; set; }
public IActionResult OnPost()
{
if (!ValidateUser(Username, Password))
{
ErrorMessage = "Invalid username or password.";
return Page();
}
var user = GetUserDetailsFromLDAP(Username);
if (user == null)
{
ErrorMessage = "Failed to retrieve user details from Server.";
return Page();
}
// Pass user details to the surplus entry form
return RedirectToPage("/SurplusEntryForm", new { firstName = user.FirstName, lastName = user.LastName });
}
private bool ValidateUser(string username, string password)
{
try
{
using (var context = new PrincipalContext(ContextType.Domain))
{
// 验证用户的凭据是否与 LDAP 服务器匹配
return context.ValidateCredentials(username, password);
}
}
catch (Exception ex)
{
// 处理 LDAP 认证期间发生的任何异常
// 根据您的应用程序要求记录异常或执行错误处理
Console.WriteLine($"LDAP authentication failed: {ex.Message}");
}
return false; // 如果认证失败或发生错误,则返回 false
}
private User GetUserDetailsFromLDAP(string username)
{
try
{
using (var context = new PrincipalContext(ContextType.Domain))
{
var userPrincipal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
if (userPrincipal != null)
{
var firstName = userPrincipal.GivenName;
var lastName = userPrincipal.Surname;
// 创建并返回一个 User 对象
return new User { FirstName = firstName, LastName = lastName };
}
}
}
catch (Exception ex)
{
// 处理从 LDAP 检索用户详细信息时发生的任何异常
// 根据您的应用程序要求记录异常或执行错误处理
Console.WriteLine($"Failed to retrieve user details from Server: {ex.Message}");
}
return null; // 如果找不到用户或发生错误,则返回 null
}
}
}
这里是 loginpage 使用的 user.cs 模型:
using System;
using System.Data.SqlClient;
using System.DirectoryServices;
namespace Surplus.Pages
{
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string DatabaseConnectionString { get; set; }
public bool ValidateLDAP(string userId, string password)
{
try
{
var ldapManager = new LdapManager();
return ldapManager.Validate(userId, password);
}
catch (Exception ex)
{
// 处理 LDAP 验证期间发生的任何异常
Console.WriteLine($"LDAP validation failed: {ex.Message}");
}
return false;
}
public void ConnectToDatabase()
{
try
{
using (var connection = new SqlConnection(DatabaseConnectionString))
{
connection.Open();
// 在此执行数据库操作
connection.Close();
}
}
catch (Exception ex)
{
// 处理任何数据库连接异常
Console.WriteLine($"Database connection failed: {ex.Message}");
}
}
internal object GetUserDetailsFromLDAP(string username)
{
throw new NotImplementedException();
}
}
public class LdapManager
{
public bool Validate(string userId, string password)
{
try
{
string path = LdapPath();
string username = UserFullId(userId);
DirectoryEntry de = new DirectoryEntry(path, username, password, AuthenticationTypes.Secure);
DirectorySearcher ds = new DirectorySearcher(de);
ds.FindOne();
return true;
}
catch (DirectoryServicesCOMException)
{
return false;
}
}
private string UserFullId(string userId)
{
string value = string.Format(@"{0}@{1}", userId, "YourDomainName");
return value;
}
private string LdapPath()
{
string value = string.Format(@"LDAP://{0}:{1}", "YourDomainName", 389);
return value;
}
}
}
这里是 surpluspage 的 C# 代码:
using Microsoft.AspNetCore
<details>
<summary>英文:</summary>
I am working on a web app using razor pages and c# to do surplus for the company I work for. I am using LDAP to authenticate the user's username and password and pass the user's first name and last name to a welcome message on the surplus page, but when the user logs in with a valid account I get this error when it tries to load the surplus form page:
An unhandled exception occurred while processing the request.
InvalidOperationException: Multiple handlers matched. The following handlers matched route data and had all constraints satisfied:
Void OnGet(), Void OnGet(System.String, System.String)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageHandlerMethodSelector.Select(PageContext context)
Stack Query Cookies Headers Routing
InvalidOperationException: Multiple handlers matched. The following handlers matched route data and had all constraints satisfied: Void OnGet(), Void OnGet(System.String, System.String)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageHandlerMethodSelector.Select(PageContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
here is my loginpage cs code:
using System.DirectoryServices.AccountManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Surplus.Pages
{
public class LoginModel : PageModel
{
[BindProperty]
public string Username { get; set; }
[BindProperty]
public string Password { get; set; }
public string ErrorMessage { get; set; }
public IActionResult OnPost()
{
if (!ValidateUser(Username, Password))
{
ErrorMessage = "Invalid username or password.";
return Page();
}
var user = GetUserDetailsFromLDAP(Username);
if (user == null)
{
ErrorMessage = "Failed to retrieve user details from Server.";
return Page();
}
// Pass user details to the surplus entry form
return RedirectToPage("/SurplusEntryForm", new { firstName = user.FirstName, lastName = user.LastName });
}
private bool ValidateUser(string username, string password)
{
try
{
using (var context = new PrincipalContext(ContextType.Domain))
{
// Validate the user's credentials against the LDAP server
return context.ValidateCredentials(username, password);
}
}
catch (Exception ex)
{
// Handle any exception that occurred during the LDAP authentication
// Log the exception or perform error handling as per your application's requirements
Console.WriteLine($"LDAP authentication failed: {ex.Message}");
}
return false; // Return false if authentication fails or an error occurs
}
private User GetUserDetailsFromLDAP(string username)
{
try
{
using (var context = new PrincipalContext(ContextType.Domain))
{
var userPrincipal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
if (userPrincipal != null)
{
var firstName = userPrincipal.GivenName;
var lastName = userPrincipal.Surname;
// Create and return a User object
return new User { FirstName = firstName, LastName = lastName };
}
}
}
catch (Exception ex)
{
// Handle any exception that occurred while retrieving user details from LDAP
// Log the exception or perform error handling as per your application's requirements
Console.WriteLine($"Failed to retrieve user details from Server: {ex.Message}");
}
return null; // Return null if the user is not found or an error occurs
}
}
}
here is the user.cs model the login page uses:
using System;
using System.Data.SqlClient;
using System.DirectoryServices;
namespace Surplus.Pages
{
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string DatabaseConnectionString { get; set; }
public bool ValidateLDAP(string userId, string password)
{
try
{
var ldapManager = new LdapManager();
return ldapManager.Validate(userId, password);
}
catch (Exception ex)
{
// Handle any exception that occurred during LDAP validation
Console.WriteLine($"LDAP validation failed: {ex.Message}");
}
return false;
}
public void ConnectToDatabase()
{
try
{
using (var connection = new SqlConnection(DatabaseConnectionString))
{
connection.Open();
// Perform database operations here
connection.Close();
}
}
catch (Exception ex)
{
// Handle any database connectivity exceptions
Console.WriteLine($"Database connection failed: {ex.Message}");
}
}
internal object GetUserDetailsFromLDAP(string username)
{
throw new NotImplementedException();
}
}
public class LdapManager
{
public bool Validate(string userId, string password)
{
try
{
string path = LdapPath();
string username = UserFullId(userId);
DirectoryEntry de = new DirectoryEntry(path, username, password, AuthenticationTypes.Secure);
DirectorySearcher ds = new DirectorySearcher(de);
ds.FindOne();
return true;
}
catch (DirectoryServicesCOMException)
{
return false;
}
}
private string UserFullId(string userId)
{
string value = string.Format(@"{0}@{1}", userId, "YourDomainName");
return value;
}
private string LdapPath()
{
string value = string.Format(@"LDAP://{0}:{1}", "YourDomainName", 389);
return value;
}
}
}
and here is the surpluspage C# code:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using System.Data.SqlClient;
namespace Surplus.Pages
{
public class SurplusEntryFormModel : PageModel
{
private readonly string _connectionString = "Data Source=dbname;Initial Catalog=tablename;User ID=dbusername;Password=dbpassword;";
public string FirstName { get; set; }
public string LastName { get; set; }
public string WelcomeMessage { get; set; }
[BindProperty]
public string AssetTag { get; set; }
[BindProperty]
public string BulidingName { get; set; }
[BindProperty]
public string ItemName { get; set; }
[BindProperty]
public string Description { get; set; }
[BindProperty]
public string Reason { get; set; }
public List<string> BuildingOptions { get; set; }
public void OnGet()
{
// Initialize the BuildingOptions list
BuildingOptions = new List<string>();
try
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
string query = "SELECT ID, BuildingName FROM SurplusItemsNew";
using (var command = new SqlCommand(query, connection))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
string buildingName = reader["BuildingName"].ToString();
BuildingOptions.Add(buildingName);
}
}
}
connection.Close();
}
}
catch (SqlException ex)
{
// Handle the exception
// For simplicity, this example just rethrows the exception
throw ex;
}
}
public List<string> ReasonOptions { get; } = new List<string>
{
"Broken",
"Burned Out",
"Extinction",
"No Longer Used",
"Obsolete",
"Other"
};
public void OnGet(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
WelcomeMessage = $"Welcome, {FirstName} {LastName}!";
}
public IActionResult OnPostSearchItem()
{
if (string.IsNullOrEmpty(AssetTag))
{
ModelState.AddModelError(string.Empty, "Please enter a valid Asset Tag.");
return Page();
}
if (!ModelState.IsValid)
{
return Page();
}
try
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
string query = "SELECT BulidingName, ItemName, Description, Reason FROM Items WHERE AssetTag = @assetTag";
using (var command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@assetTag", AssetTag);
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
BulidingName = reader["BulidingName"].ToString();
ItemName = reader["ItemName"].ToString();
Description = reader["Description"].ToString();
Reason = reader["Reason"].ToString();
}
else
{
ModelState.AddModelError(string.Empty, "Item not found with the given Asset Tag.");
}
}
}
connection.Close();
}
}
catch (SqlException ex)
{
ModelState.AddModelError(string.Empty, $"Database connection failed: {ex.Message}");
}
return Page();
}
}
}
I tried stepping through breakpoints googling the error and looking at my code
I am still new to razor pages and c# so any help would be amazing
thanks again for any help in advance!!!!!
</details>
# 答案1
**得分**: 1
你在同一个 `PageModel` 类中不能有多个名为 `OnGet` 的处理程序。参数在基于相同 HTTP 方法的处理程序之间没有任何消除歧义的作用,尽管编译器会允许它。`Async` 后缀也不能起到作用,因此 `OnGet()`, `OnGet(string s)` 和 `OnGetAsync()` 都被视为重复。
你可以将其中一个处理程序更改为一个 [命名处理程序方法][1],例如:
```csharp
public void OnGetWelcome(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
WelcomeMessage = $"欢迎, {FirstName} {LastName}!";
}
英文:
You cannot have multiple handlers named OnGet
in the same PageModel
class. Parameters play no part in disambiguating between handlers based on the same HTTP method, despite the fact that the compiler will allow it. Neither does the Async
suffix, so OnGet()
, OnGet(string s)
and OnGetAsync()
are all seen as duplicates.
You could change one of the handlers to a named handler method instead e.g.
public void OnGetWelcome(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
WelcomeMessage = $"Welcome, {FirstName} {LastName}!";
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论