C# – Razor form asp.net mvc

asp.net-mvc-4crazor

<% using (Html.BeginForm("DisplayCustomer","Customer",FormMethod.Post))
{ %>
Enter customer id :- <%= Html.TextBox("Id",Model)%> <br />
Enter customer code :- <%= Html.TextBox("CustomerCode",Model) %><br />
Enter customer Amount :- <%= Html.TextBox("Amount",Model) %><br />
<input type="submit" value="Submit customer data" />
<%} %>

Using Razor

    @using (Html.BeginForm("DisplayResult", "DisplayCustomer", FormMethod.Post)) { 
    @Html.ValidationSummary(true);

    @:Enter customer id :- @Html.TextBox("Id",Model)
    @:Enter customer code :-@Html.TextBox("Code",Model)
    @:Enter customer Amount :-@Html.TextBox("Amount",Model)
    <input type="submit" value="Enter the value" />

} 

Compiler Error Message: CS1973: 'System.Web.Mvc.HtmlHelper' has no applicable method named 'TextBox' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

@using (Html.BeginForm("DisplayResult", "DisplayCustomer", FormMethod.Post)) { 
    @Html.ValidationSummary(true);

    @:Enter customer id :- <input type="text" name="Id" />
    @:Enter customer code :-<input type="text" name="Code" />
    @:Enter customer Amount :-<input type="text" name="Amount" />
    <input type="submit" value="Enter the value" />

}

This works correctly

What am I doing wrong .I am trying to use the razor equivalent of the code given in first section.The second part is the razor code attempt and third works when only form is used .I also want to know if nest is the reason the error is happening

EDIT:-

  @:Enter customer id :- @Html.TextBox("Id")
  @:Enter customer code :-@Html.TextBox("Code")
  @:Enter customer Amount :-@Html.TextBox("Amount")

If I do not use model then everything works perfectly

Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class DisplayCustomerController : Controller
    {
        //
        // GET: /DisplayCustomer/
        [HttpPost]
        public ViewResult DisplayResult()
        {
            Customer objCustomer = new Customer();
            objCustomer.Id = Convert.ToInt16(Request.Form["Id"].ToString());  //101; 
            objCustomer.Amount =Convert.ToDouble(Request.Form["Amount"].ToString());// 80.00;
            objCustomer.Code = Request.Form["Code"].ToString();//"IE100"; 

            return View("DisplayResult", objCustomer);
        }
        public ActionResult ShowForm() 
        {

            return View("ShowForm");
        }

    }
}

Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplication1.Models
{
    public class Customer
    {
        //private string Code;
      //  private int Id;
        //private double Amount;
        public String Code
        {
            get;
            set;
        }
        public int Id
        {
            get;
            set;
        }
        public double Amount
        {
            get;
            set;
        }

    }
}

View(ShowForm)

@{
    ViewBag.Title = "ShowForm";
}

<h2>ShowForm</h2>

@using (Html.BeginForm("DisplayResult", "DisplayCustomer", FormMethod.Post)) { 
    @Html.ValidationSummary(true);

    @:Enter customer id :- @Html.TextBox("Id")
    @:Enter customer code :-@Html.TextBox("Code")
    @:Enter customer Amount :-@Html.TextBox("Amount")
    <input type="submit" value="Submit" />

}

Best Answer

Your error occurs because you have not declared the model in the view. Modify the view to

@model MvcApplication1.Models.Customer // add this
@{
    ViewBag.Title = "ShowForm";
}
....

Note the error will also occur if you use @model dynamic

I would however suggest a number of changes to your code. Firstly, always using a view model, especially when editing (refer What is ViewModel in MVC?). It is also preferable to use the ***For() methods to generate you controls, and you curret use of @Html.TextBox("Id", Model) would mean the each textbox would display "MvcApplication1.Models.Customer", not the value of the property. In addition, use LabelFor() to generate labels associated with your controls, and include ValidationMesageFor() for validation

public class CustomerVM
{
    [Display(Name = "Customer Id")]
    [Required(ErrorMesage = "Please enter the customer id")]
    public int? Id { get; set; }
    [Display(Name = "Customer Code")]
    [Required(ErrorMesage = "Please enter the customer code")]
    public string Code { get; set; }
    [Display(Name = "Customer Amount")]
    [Required(ErrorMesage = "Please enter the customer amount")]
    public double? Amount { get; set; }
}

and the view will be

@model yourViewModelAssembly.CustomerVM
....

@using (Html.BeginForm("DisplayResult", "DisplayCustomer", FormMethod.Post))
{
    @Html.AntiForgeryToken();
    @Html.ValidationSummary(true);
    @Html.LabelFor(m => m.Id)
    @Html.TextBoxFor(m => m.Id)
    @Html.ValidationMessageFor(m => m.Id)
    @Html.LabelFor(m => m.Code)
    @Html.TextBoxFor(m => m.Code)
    @Html.ValidationMessageFor(m => m.Code)
    ....
}

Side note: If the Id property is the PK, then that should not be included in the view as an editable control.

Its also unclear why you are submitting to a different method, and in any case your POST method does not do anything with the data (e.g. saving it). It just returns the same data back again, but to a different view. Typically your methods would be

public ActionResult Create()
{
    var model = new CustomerVM();
    return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerVM model)
{
    if (!ModelState.IsValid)
    {
        return View(model)
    }
    var customer = new Customer
    {
        Code = model.Code,
        Amount = model.Amount
    }
    .... // save the Customer and redirect
}