在HTML帮助器方法中设置名称属性会导致由于元组而导致命名错误

时间:2013-02-28 09:44:07

标签: c# asp.net-mvc ado.net

您好我正在尝试在asp.net MVC中发布一个表单,但似乎当我点击提交按钮时,我的控制器没有被调用。

我认为这是因为每个输入的名称都没有设置为corectly,因为我使用的是Tuple。我尝试使用HTML属性属性设置名称,但似乎它不起作用。

他是我的模特:

    public int Id { get; set; }
            public string Name { get; set; }
            public string Author { get; set; }
            public string Description { get; set;}
            public DateTime PublicationDate { get; set; }
            public int CategoryId { get; set; }

这是我的控制器:

    public ActionResult AddBook()
        {
            IEnumerable<CategoryModel> categories = categoryContext.GetCategories();
            Tuple<BookModel1, IEnumerable<CategoryModel>> model =
                new Tuple<BookModel1, IEnumerable<CategoryModel>>(book, categories);
            return View(model);
        }

        [HttpPost]
        public ActionResult AddBook(BookModel1 book)
        {
            bookContext.AddBook(book);
            return RedirectToAction("Index", "ProductManager");
        }

这是我的观点:

    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        <fieldset>
               @Html.LabelFor(x => x.Item1.Name , "Book Name")
               @Html.TextBoxFor(x => x.Item1.Name, new { name = "Name" })
               @Html.LabelFor(x => x.Item1.Author)
               @Html.TextBoxFor(x => x.Item1.Author , new { name = "Author" })
               @Html.LabelFor(x => x.Item1.PublicationDate ,"Publication Date")
               @Html.TextBoxFor(x => x.Item1.PublicationDate , new { name = "PublicationDate" })
               @Html.LabelFor(x => x.Item2 , "Select category")
               @Html.DropDownListFor(x => x.Item2, new SelectList(Model.Item2, "Id", "Name")) 
               @Html.LabelFor(x => x.Item1.Description)
               @Html.TextAreaFor(x => x.Item1.Description ,  new { name = "Description" })
            <p>
                <input type="submit" value="Create" class="link"/>
                @Html.ActionLink("Back to List", "Index", "ProductManager", null,new { @class ="link"})
            </p>
        </fieldset>
    }

即使我尝试使用HTMLAttributes设置name属性,结果名称仍然如下所示:Item1.PublicationDate。   我正在使用ADO.NET进行数据访问。

如何解决此问题,以便调用AddBook(BookModel1 book)控制器?

2 个答案:

答案 0 :(得分:1)

是的,问题是因为Tuple类。 Item属性是只读的,它没有setter意味着默认模型绑定器无法在回发时设置其值。您应该使用视图模型:

public class MyViewModel
{
    public BookModel1 Book { get; set; }
    public IEnumerable<CategoryModel> Categories { get; set; }
}

然后将您的视图强烈输入视图模型:

@model MyViewModel
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        @Html.LabelFor(x => x.Book.Name, "Book Name")
        @Html.TextBoxFor(x => x.Book.Name, new { name = "Name" })
        @Html.LabelFor(x => x.Book.Author)
        @Html.TextBoxFor(x => x.Book.Author, new { name = "Author" })
        @Html.LabelFor(x => x.Book.PublicationDate, "Publication Date")
        @Html.TextBoxFor(x => x.Book.PublicationDate , new { name = "PublicationDate" })
        @Html.LabelFor(x => x.Book.CategoryId, "Select category")
        @Html.DropDownListFor(
            x => x.Book.CategoryId, 
            new SelectList(Model.Categories, "Id", "Name")
        ) 
        @Html.LabelFor(x => x.Book.Description)
        @Html.TextAreaFor(x => x.Book.Description, new { name = "Description" })
        <p>
            <input type="submit" value="Create" class="link"/>
            @Html.ActionLink("Back to List", "Index", "ProductManager", null, new { @class ="link"})
        </p>
    </fieldset>
}

最后你的控制器:

public ActionResult AddBook()
{
    var model = new MyViewModel();
    model.Categories = categoryContext.GetCategories();
    model.Book = ...
    return View(model);
}

[HttpPost]
public ActionResult AddBook(MyViewModel model)
{
    bookContext.AddBook(model.Book);
    return RedirectToAction("Index", "ProductManager");
}

答案 1 :(得分:0)

最好的方法是不使用Tuple,而是创建一个复杂的viewmodel类,其中包含视图所需的所有数据。另一种方法是使用前缀

绑定输入BookModel1
public ActionResult AddBook([Bind(Prefix = "Item1")]BookModel1 book) 
/*since you use Tuple and your bookmodel data is Item1*/

另外,检查您的表单是否正在发布以及您要发布的数据(使用fiddler / charles或firebug)