我遇到了一个我似乎无法追踪的问题。通过我的 WebMatrix 站点注册后,我无法登录。在设置注册以通过电子邮件发送确认令牌之前,我能够正常登录。这是我得到的 YSOD 错误(该错误专门发生在登录文件的第 21 行):
Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'WebMatrix.Data.DynamicRecord' to 'string'
Source Error:
Line 19: {
Line 20: var db = Database.Open("Users");
Line 21: user = db.QuerySingle("SELECT firstName FROM UserProfile WHERE LOWER(Email) = LOWER(@0)", username);
Line 22:
Line 23: AppState["gActionMessage"] = "Hello, " + user + "!";
Source File: c:\Users\cradebaugh\Documents\My Web Sites\Persons Of Interest\Account\Login.cshtml Line: 21
以下是相关文件:
注册页面:
@{
var email = "";
var firstName = "";
var lastName = "";
var password = "";
var confirmPassword ="";
var errorMessage = "";
AppState["gActionMessage"] = "";
if(IsPost)
{
email = Request.Form["email"];
firstName = Request.Form["firstName"];
lastName = Request.Form["lastName"];
password = Request.Form["password"];
confirmPassword = Request.Form["confirmPassword"];
if(email.IsEmpty() || password.IsEmpty())
{
errorMessage = "You must specify both an email address and a password";
}
if(password != confirmPassword)
{
errorMessage = "The password and the confirmation password do not match.";
}
if(!EmailValidator.IsEmailAdress(email))
{
errorMessage = "The email you entered is not a valid email address.";
}
if(firstName=="" || lastName=="")
{
errorMessage = "You must provide both a first and last name";
}
if(errorMessage=="")
{
var db = Database.Open("Users");
var user = db.QuerySingle("SELECT Email FROM UserProfile WHERE LOWER(Email) = LOWER(@0)", email);
if(user==null)
{
WebSecurity.Logout();
db.Execute("INSERT INTO UserProfile (Email, IPAddress, firstName, lastName) VALUES (@0, @1, @2, @3)", email, Request.UserHostAddress, firstName, lastName);
var token = WebSecurity.CreateAccount(email, password, true);
var hostUrl = Request.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
var confirmationUrl = hostUrl + VirtualPathUtility.ToAbsolute("~/Account/Confirm?confirmationCode=" + HttpUtility.UrlEncode(token) + "&firstName=" + firstName);
WebMail.Send(
to: email,
subject: "Please confirm your account",
body: "Your confirmation code is: " + token + ". Visit <a href=\"" + confirmationUrl + "\">" + confirmationUrl + "</a> to activate your account."
);
AppState["gActionMessage"] = "An email to confirm your account has been emailed to you.";
AppState["gActionMessageDisplayed"] = "not";
Response.Redirect("~/IntroPage.cshtml");
}
else
{
errorMessage = "That email address is already in use.";
}
}
}
}
@RenderPage("~/Shared/HeaderLayout.cshtml")
<div style="color: #808080;">
<span class="heading">Register</span>
<span style="font-size: 3em;">________________________________________________</span></br></br></br>
</div>
@{
if (errorMessage != "")
{
<div class="errorMessageWrapper">@errorMessage</div><br/>
}
}
<div class="accInterfaceWrapper">
<form class="accInterfaceForm" method="post" action="">
<table class="accInterfaceTable">
<tr>
<td class="accInterfaceLabelCell">
<label for="email">Email Address:</label>
</td>
<td class="accInterfaceInputCell">
<input type="text" id="email" name="email" value="@email" /><br/><br/>
</td>
</tr>
<tr>
<td class="accInterfaceLabelCell">
<label for="firstName">First Name:</label>
</td>
<td class="accInterfaceInputCell">
<input type="text" id="firstName" name="firstName" value="@firstName" /><br/><br/>
</td>
</tr>
<tr>
<td class="accInterfaceLabelCell">
<label for="lastName">Last Name:</label>
</td>
<td class="accInterfaceInputCell">
<input type="text" id="lastName" name="lastName" value="@lastName" /><br/><br/>
</td>
</tr>
<tr>
<td class="accInterfaceLabelCell">
<label for="password">Create Password:</label>
</td>
<td>
<input type="password" id="password" name="password" /><br/><br/>
</td>
</tr>
<tr>
<td class="accInterfaceLabelCell">
<label for="confirmPassword">Confirm Password:</label>
</td>
<td>
<input type="password" id="confirmPassword" name="confirmPassword" /><br/><br/>
</td>
</tr>
</table><br/><br/>
<button type="button" class="btn" onclick="location.href='/IntroPage.cshtml'">Main Page</button><input class="btn" type="submit" value="Register" />
</form>
</div>
@RenderPage("~/Shared/FooterLayout.cshtml")
这是确认页面:
@{
var errorMessage = "";
var confirmationToken = Request["confirmationCode"];
var firstName = Request["firstName"];
WebSecurity.Logout();
if (!confirmationToken.IsEmpty())
{
if(WebSecurity.ConfirmAccount(confirmationToken))
{
AppState["gActionMessage"] = "Welcome to the POI Database, " + firstName + "!";
AppState["gActionMessageDisplayed"] = "not";
Response.Redirect("~/");
}
else
{
errorMessage = "An error occurred while trying to confirm your account. " +
"Please try again.";
}
}
}
@RenderPage("~/Shared/HeaderLayout.cshtml")
<div style="color: #808080;">
<span class="heading">Confirm Account</span>
<span style="font-size: 3em;">________________________________________________</span></br></br></br>
</div>
@if (errorMessage != "")
{
<div class="errorMessageWrapper">@errorMessage</div><br/>
}
@RenderPage("~/Shared/FooterLayout.cshtml")
最后,登录页面:
@{
var username = "";
var user = "";
var password = "";
var errorMessage = "";
AppState["gActionMessage"] = "";
if(IsPost)
{
username = Request.Form["username"];
password = Request.Form["password"];
if(username.IsEmpty() || password.IsEmpty())
{
errorMessage = "You must specify both a username and password.";
}
else
{
if(WebSecurity.Login(username, password, false))
{
var db = Database.Open("Users");
user = db.QuerySingle("SELECT firstName FROM UserProfile WHERE LOWER(Email) = LOWER(@0)", username);
AppState["gActionMessage"] = "Hello, " + user + "!";
AppState["gActionMessageDisplayed"] = "not";
Response.Redirect("~/");
}
else
{
errorMessage = "Login failed";
}
}
}
}
@RenderPage("~/Shared/HeaderLayout.cshtml")
<div style="color: #808080;">
<span class="heading">Please Log In</span>
<span style="font-size: 3em;">________________________________________________</span></br></br></br>
</div>
@{
if (errorMessage != "")
{
<div class="errorMessageWrapper">@errorMessage</div><br/>
}
}
<div class="accInterfaceWrapper">
<form class="accInterfaceForm" method="post" action="">
<table class="accInterfaceTable">
<tr>
<td class="accInterfaceLabelCell">
<label for="username">Email Address:</label>
</td>
<td class="accInterfaceInputCell">
<input type="text" id="username" name="username" value="@username" /><br/><br/>
</td>
</tr>
<tr>
<td class="accInterfaceLabelCell">
<label for="password">Password:</label>
</td>
<td>
<input type="password" id="password" name="password" /><br/><br/>
</td>
</tr>
</table><br/><br/>
<button type="button" class="btn" onclick="location.href='/IntroPage.cshtml'">Main Page</button><input class="btn" type="submit" value="Log In" />
</form>
<a href="~/Account/Register.cshtml">Don't have a Account?</a><br/><br/>
<a href="~/Account/ForgotPassword.cshtml">Forgot your password?</a>
</div>
@RenderPage("~/Shared/FooterLayout.cshtml")
同样,当我尝试登录时实际上会引发错误,并且在数据库中将确认设置为 true,所以我知道它们已成功注册,但没有更改登录文件中的任何内容,它仅在更改注册后才开始出错/确认文件。
很抱歉用这么多代码打你,但问题可能出在这三个页面中的任何地方。如果有人需要更多信息或其他文件,请告诉我,我会立即回复。提前感谢您的帮助。