Samuel Silva
Samuel Silva

Reputation: 43

Cannot bind source type Umbraco.Web.Models.RenderModel to model type Repower.Cms.Umbraco.Models.Test

First of all I am new to Umbraco so if you see some basic mistakes don't judge me.

So I am creating currently a Login form which he goes to the database (check Username and Password) and reads the value which he returns and let's him Cannot bind source type Umbraco.Web.Models.RenderModel to model type Repower.Cms.Umbraco.Models.Test.

This Is my HTML:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<Repower.Cms.Umbraco.Models.Test>

@{
    Layout = "Master.cshtml";
}

<style type="text/css">
    .btnStyle {
        border: thin solid #000000;
        line-height: normal;
        width: 80px;
    }
</style>
@using (Html.BeginForm("Test", "MembersProtectedPage", FormMethod.Post))
{
    <div class="fontStyle">
        <center>
            <table style="margin-top: 100px;margin-left:150px">
                <tr style="height:30px">
                    <td align="right">
                        @Html.LabelFor(m => m.User)
                    </td>
                    <td style="width:200px" align="right">
                        @Html.TextBoxFor(m => m.User)
                    </td>
                    <td style="width:250px;color:Red" align="left">
                        @Html.ValidationMessageFor(m => m.User)
                    </td>
                </tr>
                <tr style="height:30px">
                    <td align="right">
                        @Html.LabelFor(m => m.Password)
                    </td>
                    <td align="right">
                        @Html.PasswordFor(m => m.Password)
                    </td>
                    <td style="width:250px;color:Red" align="left">
                        @Html.ValidationMessageFor(m => m.Password)
                    </td>
                </tr>
                <tr style="height:30px">
                    <td colspan="2" align="center">
                        <input type="submit" value="Sign In" class="btnStyle" />
                    </td>
                </tr>
            </table>
        </center>
    </div>
}

This is my Model:

    public class Test : RenderModel
{
    public Test() : this(new UmbracoHelper(UmbracoContext.Current).TypedContent(UmbracoContext.Current.PageId)) { }
    public Test(IPublishedContent content, CultureInfo culture) : base(content, culture) { }
    public Test(IPublishedContent content) : base(content) { }

    string connString = ConfigurationManager.ConnectionStrings["connectionStringName"].ConnectionString;
    SqlConnection conn;
    SqlCommand sqlcomm;

    public string User { get; set; }
    public string Password { get; set; }

    public bool IsUserExist(string emailid, string password)
    {
        bool flag = false;
        conn = new SqlConnection(connString);
        conn.Open();

        sqlcomm = new SqlCommand();
        sqlcomm.Connection = conn;
        sqlcomm.CommandType = System.Data.CommandType.StoredProcedure;
        sqlcomm.CommandText = "dbo.uspLogin";
        sqlcomm.Parameters.AddWithValue("@pLoginName", User);
        sqlcomm.Parameters.AddWithValue("@pPassword", Password);

        SqlParameter retval = sqlcomm.Parameters.Add("@RESULT", SqlDbType.VarChar);
        retval.Direction = ParameterDirection.ReturnValue;
        sqlcomm.ExecuteNonQuery(); // MISSING
        string retunvalue = (string)sqlcomm.Parameters["@RESULT"].Value;

        switch (retunvalue)
        {
            case "0":
                flag = true;
                break;
            case "1":
                flag = false;
                break;
            case "2":
                flag = false;
                break;
            default:
                flag = false;
                break;
        }
        return flag;
    }
}

And this is my Controller:

public class TestController : Controller
{
    public ViewResult Login()
    {
        return View();
    }

[HttpPost, ValidateInput(false)]
public ActionResult Login(Test model)
{
    if (ModelState.IsValid)
    {
        if (model.IsUserExist(model.User, model.Password))
        {
            ViewBag.UserName = model.User;
            FormsAuthentication.RedirectFromLoginPage(model.User, false);
        }
        else
        {
            ModelState.AddModelError("", "Username or Password Incorrect.");
        }
    }
    return View(model);
   }
}

So I am inheriting a RenderModel because previously my error was "The model item passed into the dictionary is of type Repower.Cms.Umbraco.Models.Test', but this dictionary requires a model item of type 'Umbraco.Web.Models.RenderModel'." So I changed it (searched a lot in the Internet) and now I get this error.

Is also the rest of the code correct? The way that I access the Database and everything? I am expecting a Return value from the Database (don't know if that is correct)

Could Someone please help me? I need to get this done today.

Thanks in Advance

Upvotes: 0

Views: 1500

Answers (1)

harvzor
harvzor

Reputation: 2908

There's a few issues with your implementation.

Use the Umbraco MemberService

You're reinventing the wheel by building a new table which holds member information (such as username and password).

Umbraco has built in membership which can handle members of your site. You can view the GUI in Umbraco at /umbraco/#/member. Using this GUI, you can manually create and edit members.

You can also programmatically create end edit members in this section using this MemberService.

For example, register a member:

var MemberService = ApplicationContext.Current.Services.MemberService

var member = MemberService.CreateMemberWithIdentity(newEmail, newEmail, newName, "Member");

MemberService.Save(member);
MemberService.SavePassword(member, newPassword);

FormsAuthentication.SetAuthCookie(newEmail, true);

Login:

var memberService = ApplicationContext.Current.Services.MemberService;

if (memberService.Exists(email))
{
    if (Membership.ValidateUser(email, password))
    {
        FormsAuthentication.SetAuthCookie(email, true);
    }
}

You can read about what other methods are available here.

You're mixing up your MVC

Your Test model isn't purely a model, is also has some controller in it as it is handling database stuff too!

Ideally, your model should just contain the data which has been sent forward, and your TestController should handle using that data.

As for fixing your binding issue

You're currently setting your page view model to Repower.Cms.Umbraco.Models.Test, where as I think it should be left as is.

Stop this model from inheriting from RenderModel.

Instead, render a partial with your code.

For your page view:

@inherits Umbraco.Web.Mvc.UmbracoViewPage
@{
    Layout = "Master.cshtml";
}
@Html.Partial("Login", new Repower.Cms.Umbraco.Models.Test())

Partial called Login.cshtml:

@model Repower.Cms.Umbraco.Models.Test
@using (Html.BeginUmbracoForm<TestController>("Login"))
{
    <div class="fontStyle">
        <center>
            <table style="margin-top: 100px;margin-left:150px">
                <tr style="height:30px">
                    <td align="right">
                        @Html.LabelFor(m => m.User)
                    </td>
                    <td style="width:200px" align="right">
                        @Html.TextBoxFor(m => m.User)
                    </td>
                    <td style="width:250px;color:Red" align="left">
                        @Html.ValidationMessageFor(m => m.User)
                    </td>
                </tr>
                <tr style="height:30px">
                    <td align="right">
                        @Html.LabelFor(m => m.Password)
                    </td>
                    <td align="right">
                        @Html.PasswordFor(m => m.Password)
                    </td>
                    <td style="width:250px;color:Red" align="left">
                        @Html.ValidationMessageFor(m => m.Password)
                    </td>
                </tr>
                <tr style="height:30px">
                    <td colspan="2" align="center">
                        <input type="submit" value="Sign In" class="btnStyle" />
                    </td>
                </tr>
            </table>
        </center>
    </div>
}

Finally, update your controller to inherit from SurfaceController.

I hope this helps

This isn't the complete solution but should help you get off on the right track.

Upvotes: 1

Related Questions