为什么我的MVC5 Post Action模型没有被填充?

3

我在我的解决方案中有一个模型,在我的POST表单操作中没有填充。为什么这个模型不同呢?

这是无法绑定到我的Post操作的模型:

public class CompanyListingParameters
{
    public String Category { get; set; }
    public String CityState { get; set; }
}

这是从Chrome调试器中获取的实时表单:
<form class="panel form-horizontal" method="post" action="/company/search" novalidate="novalidate">
            <div class="panel-heading">
                <h2 class="panel-title">
                    <i class="panel-title-icon fa fa-search fa-3x"></i>
                    Find a Company
                </h2>
            </div>
            <div class="panel-body padding-sm">
                <div class="row">
                    <div class="col-md-8 col-md-offset-2">
                        <label class="control-label sr-only" for="Category">Category</label>
                        <span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span>
                        <input type="text" id="Category" name="Category" value="Architecture" class="autocomplete required form-control form-group-margin ui-autocomplete-input" data-autocomplete-url="/api/servicecategory/search/" data-autocomplete-url-method="get" autocomplete="off">
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 col-md-offset-2">
                        <label class="control-label sr-only" for="CityState">City, State</label>
                        <span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span>
                        <input type="text" id="CityState" name="CityState" value="" class="autocomplete required form-control form-group-margin ui-autocomplete-input ui-autocomplete-loading" data-autocomplete-url="/api/companyservicelisting/area/cities/search" data-autocomplete-url-method="get" data-autocomplete-itemtemplate="CityAutocomplete" data-autocomplete-itemvalue="FormattedAddress" autocomplete="off">
                    </div>
                </div>
            </div>
            <div class="panel-footer text-center">
                <input type="submit" value="Search" id="Search" name="Search" class="btn btn-primary btn-lg">
            </div>
        </form>

控制器代码如下:

    [RoutePrefix("company/search")]
    public partial class CompanySearchController : Controller
    {
        [Route("")]
        public virtual ActionResult Search(String category, String cityState)
        {
            var model = ...; //This action works - search results view
            return View(MVC.CompanySearch.Views.Search, model);
        }

        [HttpPost]
        [Route("")]
        public virtual ActionResult SearchPost(CompanyListingParameters search)
        {   //parameter 'search' is null here
            return string.IsNullOrWhiteSpace(search.CityState) || string.IsNullOrWhiteSpace(search.Category)
                ? RedirectToAction(MVC.Home.Index())
                : RedirectToAction(MVC.CompanySearch.Search(search.Category.ToLower(), search.CityState.ToLower()));
        }
}

如果我将无效的操作更改为以下内容,则它可以正常工作(类别和城市/州已绑定):
[HttpPost]
[Route("")]
public virtual ActionResult SearchPost(String Category, String CityState)
{   //parameters 'Category' and 'CityState' are populated on Post
    return string.IsNullOrWhiteSpace(CityState) || string.IsNullOrWhiteSpace(Category)
        ? RedirectToAction(MVC.Home.Index())
        : RedirectToAction(MVC.CompanySearch.Search(Category.ToLower(), CityState.ToLower()));
}
1个回答

1
在您的表单中,从提交按钮中删除name="Search"
<input type="submit" value="Search" id="Search" class="btn btn-primary btn-lg">

提交按钮的值会被发送回来,因此您在发布时会发送Search:“Search”,因此ModelBinder试图将typeof CompanyListingParameters绑定到字符串(当然会失败)。除非您有一些JavaScript,否则id属性似乎是不必要的。

哇,这个可行!谢谢。虽然我必须承认这个要求很糟糕。为什么模型绑定器不能更聪明一些,只填写与表单字段匹配的属性并忽略模型未定义的属性呢?模型绑定器在Web API帖子中的类似情况下也可以工作。 - Michael Lang
为什么ModelBinder尝试将CompanyListingParameters绑定到字符串?我有三个表单字段返回,它们都是字符串。当只有两个返回时,它会找到正确的属性。问题是ModelBinder必须为所有表单字段找到匹配项,否则整个过程就会失败吗? - Michael Lang
发生的情况是 DefaultModelBinder 初始化了一个新的 CompanyListingParameters 实例,然后从 FormCollection 中分配 CategoryCityState 的值,接着它读取另一个名为 search 的值,该值匹配您的参数名称,因此它试图将 CompanyListingParameters 设置为字符串“搜索”(按钮的值),但无法绑定,因此变成 null。请注意,您还可以通过将参数名称更改为任何名称(除了您返回的其中一个值的名称)来解决此问题。 - user3559349
我曾尝试将其他表单字段命名为search.CityState和search.Category,但没有成功。或者也许它确实成功了,只是按钮“搜索”处于最后并获胜了。 - Michael Lang
是的,问题在于按钮的名称与参数的名称相匹配。如果您将按钮名称保留为“搜索”,但将参数名称更改为“ABC”或“XYZ”,则可以正常工作(但除非您想发布其值,否则为什么要给按钮命名)。 - user3559349

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接