在MVC3中使用Get方法提交表单?

时间:2012-06-18 12:13:11

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

我有以下表格:

@model Teesa.Models.SearchModel
@using (Html.BeginForm("Index", "Search", FormMethod.Get, new { id = "SearchForm" }))
{
    <div class="top-menu-search-buttons-div">
        @if (!MvcHtmlString.IsNullOrEmpty(Html.ValidationMessageFor(m => m.SearchText)))
        {
            <style type="text/css">
                .top-menu-search-text
                {
                    border: solid 1px red;
                }
            </style>
        }
        @Html.TextBoxFor(q => q.SearchText, new { @class = "top-menu-search-text", id = "SearchText", name = "SearchText" })
        @Html.HiddenFor(q=>q.Page)
        <input type="submit" value="search" class="top-menu-search-submit-button" />
    </div>
    <div id="top-menu-search-info" class="top-menu-search-info-div">
        Please Select one :
        <hr style="background-color: #ccc; height: 1px;" />
        <div class="top-menu-search-info-checkbox-div">
            @Html.CheckBoxFor(q => q.SearchInBooks, new { id = "SearchInBooks", name = "SearchInBooks" })
            <label for="SearchInBooks">Books</label>
        </div>
        <div class="top-menu-search-info-checkbox-div">
            @Html.CheckBoxFor(q => q.SearchInAuthors, new { id = "SearchInAuthors" })
            <label for="SearchInAuthors">Authors</label>
        </div>
        <div class="top-menu-search-info-checkbox-div">
            @Html.CheckBoxFor(q => q.SearchInTags, new { id = "SearchInTags" })
            <label for="SearchInTags">Tags</label>
        </div>
}

以及以下控制器和型号:

namespace Teesa.Models
{
    public class SearchModel
    {
        [Required(ErrorMessage = "*")]
        public string SearchText { get; set; }
        public bool SearchInTags { get; set; }
        public bool SearchInAuthors { get; set; }
        public bool SearchInBooks { get; set; }
        public int Page { get; set; }
        public List<SearchBookModel> Result { get; set; }
        public List<SimilarBookModel> LatestBooks { get; set; }
    }

    public class SearchBookModel
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
        public string Summary { get; set; }
        public List<Tags> Tags { get; set; }
        public string StatusName { get; set; }
        public string SubjectName { get; set; }
        public string ThumbnailImagePath { get; set; }
        public string BookRate { get; set; }
        public string RegistrationDate { get; set; }
        public int NumberOfVisit { get; set; }
    }
}

[HttpGet]
public ActionResult Index(SearchModel model)
{
    FillSearchModel(model);
    if (ModelState.IsValid)
    {
            string page = model.Page;
        DatabaseInteract databaseInteract = new DatabaseInteract();
        model.Result = new List<SearchBookModel>();
        List<Book> allBooks = databaseInteract.GetAllBooks();
        List<Book> result = new List<Book>();
        #region 
        if (model.SearchInTags)
        {
            var temp = (from item in allBooks
                        from tagItem in item.Tags
                        where tagItem.Name.Contains(model.SearchText)
                        select item).ToList();
            result.AddRange(temp);
        }
        if (model.SearchInBooks)
        {
            var temp = (from item in allBooks
                        where item.عنوان.Contains(model.SearchText)
                        select item).ToList();
            result.AddRange(temp);
        }
        if (model.SearchInAuthors)
        {
            var temp = (from item in allBooks
                        where item.Author.Contains(model.SearchText)
                        select item).ToList();
            result.AddRange(temp);
        }
        #endregion
        #region Paging
        string itemsPerPage = databaseInteract.GetItemsPerPage();
        int ItemInPage = int.Parse(itemsPerPage);
        var pagingParams = Helpers.SetPagerParameters(page, ItemInPage, result);
        ViewBag.AllPagesCount = pagingParams.AllPagesCount;
        ViewBag.CurrentPageNumber = pagingParams.CurrentPageNumber;
        ViewBag.CountOfAllItems = pagingParams.CountOfAllItems.ToMoneyFormat().ToPersianNumber();
        result = pagingParams.ListData as List<Book> ?? result;
        #endregion
        foreach (var item in result)
        {
            var bookRate = (item.BookRate == null || item.BookRate.Count == 0)
                               ? 0.0
                               : item.BookRate.Average(q => q.Rate);
            model.Result.Add(new SearchBookModel
            {
                Author = item.Author,
                Id = item.Id,
                .
                .
                .
            });
        }
    }
    else
    {
        model.Result = new List<SearchBookModel>();
    }
    return View(model);
}

当我提交表单时,我会看到以下查询字符串(注意重复的名称):

http://localhost:2817/Search?SearchText=book&Page=2&SearchInBooks=true&SearchInBooks=false&SearchInAuthors=true&SearchInAuthors=false&SearchInTags=true&SearchInTags=false

但它必须是这样的:

http://localhost:2817/Search?SearchText=book&Page=2&SearchInBooks=true&SearchInAuthors=true&SearchInTags=true

我该如何解决? 感谢

3 个答案:

答案 0 :(得分:3)

Html.Checkbox(和相关的For...方法)为false生成隐藏输入,为true生成复选框。这是为了确保模型绑定在绑定时一致地工作。

如果您必须摆脱隐藏输入产生的“错误”项目,您需要自己构建复选框输入(使用HTML而不是帮助程序)。

<input type="checkbox" id="SearchInBooks" name="SearchInBooks">

答案 1 :(得分:1)

为什么不为Get方法创建一个匹配名称的Post方法。这将确保代码更容易调试。因为你没有很大的功能来尝试找到这样的问题。

我无法找到从中获取重复的url查询字符串的位置。

这也允许您将结果绑定回模型。

答案 2 :(得分:1)

如果您希望模型绑定成功发生,那么您必须采用这种方式,因为这是Html.CheckBox/Html.CheckBoxFor方法的本质,它们也将呈现隐藏字段。

我建议宁愿选择POST让你的生活变得轻松。如果您仍想使用GET,则必须直接使用复选框元素,但您必须处理模型绑定问题。当选中复选框时,并非所有浏览器都返回“true”。 firefox传递“on”,因此默认模型绑定器会抛出错误。

其他备用选项是您可以使用自定义模型绑定器,或者您可以通过侦听提交事件使用jquery提交表单。