1

我遇到了一个我似乎无法追踪的问题。通过我的 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,所以我知道它们已成功注册,但没有更改登录文件中的任何内容,它仅在更改注册后才开始出错/确认文件。

很抱歉用这么多代码打你,但问题可能出在这三个页面中的任何地方。如果有人需要更多信息或其他文件,请告诉我,我会立即回复。提前感谢您的帮助。

4

1 回答 1

1

问题出在登录屏幕上。变量 user 被定义为一个字符串。db.QuerySingle 返回一行,这是一个动态对象。即使您只选择一个字段也是如此。您可以执行以下操作

var rowResults = db.QuerySingle( "...");
user = rowResults.firstName;

或者您可以更改该行以返回单个值。

user = db.QueryValue( "Select firstName...");
于 2012-10-15T14:39:17.087 回答