2013-10-02 43 views
0

在我的索引视图中,我需要允许用户输入搜索条件。此标准以FormCollection对象的形式发送回索引控制器。然后我提取搜索条件,从数据库中提取请求的信息,并将用户发回到索引视图。但是,一旦用户返回索引视图和请求的信息,来自FormCollection对象的数据现在变为空白。从控制器回发后保留ASP MVC FormCollection值

我希望能够在我使用的三个文本框中保留用户的搜索条件,但我不确定如何使用FormCollection。有谁知道如何做到这一点或我应该使用另一个?

查看

@using(Html.BeginForm()) 
{ 
    <div id="searchBox" class="boxMe"> 
     <div id="zipBox" style="float: left; padding-left: 20px; padding-right: 10px; padding-top: 20px; padding-bottom: 20px; vertical-align: top;"> 
      @Html.Raw("Zip Code") 
      @Html.TextArea("ZipSearch", new { style = "width: 300px;", placeholder = "Enter up to 35 comma separated zip codes" }) 
     </div> 
     <div id="dateBox" style="float: left; padding-right: 10px; padding-top: 20px;"> 
      @Html.Raw("Effective on this date") 
      @Html.TextBox("DateSearch", null, new { style="width: 80px;"}) 
     </div> 
     <div id="stateBox" style="float: left; padding-right: 20px; padding-top: 20px;"> 
      @Html.Raw("State") 
      @Html.TextBox("StateSearch", null, new { style = "width: 25px;" }) 
      <button type="submit">Search</button> 
     </div> 

    </div> 
    <div style="clear: both;"></div> 
} 

控制器

public ViewResult Index(FormCollection searchDetails = null) 
    { 
     string zip = searchDetails["ZipSearch"]; 
     string date = searchDetails["DateSearch"]; 
     string state = searchDetails["StateSearch"]; 

     if (String.IsNullOrWhiteSpace(zip) && String.IsNullOrWhiteSpace(date) && String.IsNullOrWhiteSpace(state)) 
     { 
      return View(); 
     } 

     string[] zipArray; 
     DateTime effectiveDate; 

     //Convert date string to DateTime type 
     if (String.IsNullOrWhiteSpace(date)) 
     { 
      effectiveDate = DateTime.MinValue; 
     } 
     else 
     { 
      effectiveDate = Convert.ToDateTime(date); 
     } 

     //Conduct search based on Zip Codes 
     if (!String.IsNullOrWhiteSpace(zip)) 
     { 
      //Create array and remove white spaces 
      zipArray = zip.Split(',').Distinct().ToArray(); 
      for (int i = 0; i < zipArray.Length; i++) 
      { 
       zipArray[i] = zipArray[i].Trim(); 
      } 

      //Add zip codes to list object then send back to view 
      List<ZipCodeTerritory> zips = new List<ZipCodeTerritory>(); 

      if (String.IsNullOrWhiteSpace(state)) 
      { 
       foreach (var items in zipArray) 
       { 
        var item = from z in db.ZipCodeTerritory 
           where z.ZipCode.Equals(items) && 
            z.EffectiveDate >= effectiveDate 
           select z; 
        zips.AddRange(item); 
       } 
      } 
      else 
      { 
       foreach (var items in zipArray) 
       { 
        var item = from z in db.ZipCodeTerritory 
           where z.ZipCode.Equals(items) && 
            z.EffectiveDate >= effectiveDate 
           select z; 
        zips.AddRange(item); 
       } 
      } 

      return View(zips); 
     } 

     //Zip code was not specified so search by state 
     if (!String.IsNullOrWhiteSpace(state)) 
     { 
      var items = from z in db.ZipCodeTerritory 
         where z.StateCode.Equals(state) && 
           z.EffectiveDate >= effectiveDate 
         select z; 

      return View(items); 
     } 

     //Neither zip code or state specified, simply search by date 
     var dateOnly = from z in db.ZipCodeTerritory 
        where z.EffectiveDate >= effectiveDate 
        select z; 

     return View(dateOnly); 
    } 

编辑

按照下面我说明已经建立了我的视图模型像这样:

public class ZipCodeIndex 
{ 
    public List<ZipCodeTerritory> zipCodeTerritory { get; set; } 
    public string searchZip { get; set; } 
    public string searchDate { get; set; } 
    public string searchState { get; set; } 
} 

但是在我的视图中,我无法访问这些属性中的任何一个。该视图的标题是这样写的:

@model IEnumerable<Monet.ViewModel.ZipCodeIndex> 

但是所有的TextBoxForTextAreaFor助手说,没有指定属性的存在。

@using(Html.BeginForm("Index", "ZipCodeTerritory", FormMethod.Post)) 
{ 
    <div id="searchBox" class="boxMe"> 
     <div id="zipBox" style="float: left; padding-left: 20px; padding-right: 10px; padding-top: 20px; padding-bottom: 20px; vertical-align: top;"> 
      @Html.Raw("Zip Code") 
      @Html.TextAreaFor(model => model.searchZip, new { style = "width: 300px;", placeholder = "Enter up to 35 comma separated zip codes" }) 
     </div> 
     <div id="dateBox" style="float: left; padding-right: 10px; padding-top: 20px;"> 
      @Html.Raw("Effective on this date") 
      @Html.TextBoxFor(model => model.searchDate, null, new { style="width: 80px;"}) 
     </div> 
     <div id="stateBox" style="float: left; padding-right: 20px; padding-top: 20px;"> 
      @Html.Raw("State") 
      @Html.TextBoxFor(model => model.searchState, null, new { style = "width: 25px;" }) 
      <button type="submit">Search</button> 
     </div> 
    </div> 
    <div style="clear: both;"></div> 
} 

最后编辑

错过了该页面在寻找一个IEnuerable Model对象。将标题更改为此并解决了问题。

@model Monet.ViewModel.ZipCodeIndex 
+7

我会建议寻找到模型和的ViewModels而不是返回的形式。如果你想要看的东西,我可以给你一些例子。 –

+0

有没有不使用模型和DefaultModelBinder的好理由? – Yoeri

+2

你忽略了MVC中的** M ** – Liam

回答

3

好的,所以你想要做的第一件事就是创建一个模型,只是一个新的类文件,看起来像这样。

public class AddressModel 
    {  
     public int zip{ get; set; } 
     public string state{ get; set; } 
     public string date{ get; set; }  
    } 

然后另一个新的类文件称为视图模型像这样。这样你就可以参考不同的事情。有像你的搜索地址,然后返回单独的列表中的结果。

public class AddressViewModel 
    { 
     public AddressModel SearchAddress { get; set; } 
     public List<AddressModel> ResultsAddress{ get; set; } 
    } 

然后在您的视图您引用这样@model MVCTestProject.ViewModels.InsertPage 顶行的视图模型。 然后这些将是你的文本框。

@using (Html.BeginForm("Submit", "Insert", FormMethod.Post)) 
{ 
@Html.TextBoxFor(model => model.SearchAddress.zip) 
@Html.TextBoxFor(model => model.SearchAddress.state) 
@Html.TextBoxFor(model => model.SearchAddress.date) 
    <input id="button" name="button" type="submit" value="submit" /> 
} 

而在你的控制器中,它将与此类似。

public ActionResult Submit(AddressViewModel model) 
     { 
      model.ResultsAddress = (from z in db.ZipCodeTerritory 
         where z.StateCode.Equals(state) && 
           z.EffectiveDate >= model.SearchAddress.date 
         select new AddressModel { 
         date = z.effectiveDate }).toList(); 
      return View("viewName", model); 
     } 

这将返回您的原始搜索条件和结果。可能不是百分之百的功能,但主要想法在那里,如果你决定走这条道路,我可以帮助你解决问题。

来显示结果

@for (int i = 0; i < Model.ResultsAddress.Count; i++) 
{ 
@Html.DisplayFor(model => model.ResultsAddress[i].date) 
} 

或只是显示它们最上面的一个可用于编辑和重新提交数据。

@foreach (var item in Model.ResultsAddress) 
{ 
    <div>@item.date</div> 
} 
+0

所以我使用ViewModel来包含搜索条件,是否正确?在索引页面上,我需要显示搜索条件(视图模型)和结果(模型)。这有可能使用这种方法吗? – NealR

+0

Ya ViewModel同时拥有它们public AddressModel SearchAddress {get;组; } public List ResultsAddress {get;组; }你的搜索是标准和结果是你的结果虐待添加到解决方案如何显示结果 –

+0

啊,明白了。因此,页面被设置为像你说的那样显示视图模型。好吧,我会给这个镜头。谢谢您的帮助! – NealR

0

Ryan Schlueter是正确的,你应该使用ASP.NET MVC原则,例如模型,自动绑定来模拟操作参数中的字段等等。但主要的在这种情况下,你应该使用强类型的视图:

操作:

public ActionResult SomeAction(ModelClass model) 
{ 
    .... 
    return("ViewName", model) 
} 

查看:

@model SomeNamespace.ModelClass 

@using (Html.BeginForm("Submit", "Insert", FormMethod.Post)) 
{ 
    @Html.TextBoxFor(model => model.Property1) 
    @Html.TextBoxFor(model => model.Property2) 
    @Html.TextBoxFor(model => model.Property3) 
    <input id="button" name="button" type="submit" value="submit" /> 
} 
+0

我已编辑帖子以详细介绍此方法。出于某种原因,即使我指定了需要使用的View Model,我也无法使Index页面识别View Model的属性。任何帮助,将不胜感激。谢谢 – NealR