【问题标题】:ASP.NET MVC - how to reload same view after posting data?ASP.NET MVC - 发布数据后如何重新加载相同的视图?
【发布时间】:2015-06-22 20:34:56
【问题描述】:

我有一个视图,其中包含一个 Google 地图,该地图具有一个国家/地区的默认缩放级别和位置设置。在地图上显示的默认位置来自 DB,我所做的是我有一个 [HttpGet]Index 操作来获取此信息,将其发送到视图,然后在视图中我使用 JS 绘制地图(通常谷歌地图的东西来绘制一个简单的地图)。

然后在地图 div 上方,我显示了一个文本框和一个搜索按钮。因此,用户输入地址并按下搜索按钮,我将文本框的值发布到 [HttpPost]Index 操作。现在我想将此值传递给 [HttpGet]Index 操作,以便它从数据库中获取该地址的数据,将其发送到索引视图,以便使用设置为地图中心的特定地址重绘地图,并且也在文本框中显示地址。

关于如何做到这一点的任何建议?

我尝试过(但没有成功)的方法是调用 Get 版本的 Index 操作并使用 TempData 字典将地址传递给它。但我看到的只是一个空/空白页。

这是我的 HttpGet Index 操作的外观:

[HttpGet]
public async Task<ActionResult> Index()
{
    // I fetch the info from DB here put it inside ViewBag and call the view    
            return View();
}

这会正确加载信息,并且当在浏览器中第一次点击 URL 控制器/索引时,地图会按照应有的方式绘制。

文本框和搜索按钮的标记是:

<form class="form" id="searchForm" action="@Url.Action("Index", "Default")" method="post">
<div class="form-group">
    <div class="row">
        <div class="col-xs-9 col-sm-9 col-md-10">
           <label for="address" class="sr-only">Search for address</label>
           <input type="text" class="form-control" id="address" placeholder="Search for address" name="address">
         </div>
    <div class="col-xs-3 col-sm-3 col-md-2">
    <input type="submit" class="btn btn-block btn-success" value="Search" />
    </div>
   </div>
</div>
</form>

最后是 HttpPost Index 操作:

[HttpPost]
public void Index(String address)
{
   TempData["address"] = address;
   Index();
}

因此,当我提交表单时,我希望它被发布到 HttpPost Index 操作,然后将值传递给它的 HttpGet 版本,该版本最终将从 DB 获取数据并使用更新的地图获取视图。但我看到的只是一个空白页。

有什么帮助吗?

【问题讨论】:

    标签: forms asp.net-mvc-5 postback


    【解决方案1】:

    这样

    [HttpPost]
    public void Index(String address)
    {
       TempData["address"] = address;
       RedirectToAction("Index");
    }
    

    您看到它是空白的,因为您正在重定向 RedirectToAction("Index"); 并将数据存储在 TempData 中,而您没有在 index Get 方法中使用它

    [HttpGet]
    public async Task<ActionResult> Index()
    {
        // I fetch the info from DB here put it inside ViewBag and call the view   
        // you must check for the temp data
        if (!string.IsNullOrWhiteSpace(TempData["address"].ToString()))
        {
             ViewBag["result"] = TempData["address"];
             //and use you viewbag data in the view
        }
        return View();
    }
    

    【讨论】:

    • 谢谢谢里夫。但我仍然看到一个空白页。
    • 我会告诉你为什么你会看到一个空白页
    • 谢谢。我在等!
    • 我正在使用它。 ViewBag.RawAddress = TempData["Address"] in Index Get 方法。
    • 但这一切都是一个糟糕的方法......你可以阅读更多关于 Post Redirect Get 机制......你可以检查THIS && THIS
    【解决方案2】:

    我告诉你的那个机制......

    如果我有一个地址实体

    public class Address
    {
        public int Id { get; set; }
        public string Street { get; set; }
        public string House { get; set; }
        public int Floor { get; set; }
    }
    

    这是控制器操作AddressController

    [HttpGet]
    public ActionResult Index()
    {
        var model = new SearchAddressesViewModel();
    
        // you can here also fetch all the addresses in your db ... 
        //but this is not a good approach also, but if you need to do that it's easy
    
        // fetch data base and get all addresses
        //model.AddressesFound = db.Addresses.Select(a => new AddressModel
        //{
        //    Street = a.Street,
        //    House = a.House,
        //    Floor = a.Floor
        //}).ToList();
    
        return View(model);
    }
    
    [HttpPost]
    public ActionResult Index(SearchAddressesViewModel model)
    {
        if (!ModelState.IsValid)
            return View(model);
    
        // fetch data base and get addresses based on the search criteria in 
        //model.SearchCriteria
        // for example:
        //var addresses = db.Addresses.Where(a => a.Street == model.SearchCriteria);
    
        //add found addresses to model
    
        //model.AddressesFound = addresses.Select(a => new AddressModel
        //{
        //    Street = a.Street,
        //    House = a.House,
        //    Floor = a.Floor
        //}).ToList();
    
        return View(model);
    }
    

    这是我的观点Index.cshtml

    @model SearchAddressesViewModel
    
    @using (Html.BeginForm("Index", "Address", FormMethod.Post))
    {
        @Html.LabelFor(m => m.SearchCriteria);
        @Html.TextBoxFor(x=>x.SearchCriteria);
        @Html.ValidationMessageFor(m => m.SearchCriteria, "");
    
        <br />
        <input type="submit" class="btn btn-block btn-success" value="Search" />
    }
    
    @if (Model.AddressesFound != null)
    {
        <table>
            <thead>
                <tr>
                    <th>Street</th>
                    <th>House</th>
                    <th>Floor</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.AddressesFound)
                {
                    <tr>
                        <td>@item.Street</td>
                        <td>@item.House</td>
                        <td>@item.Floor</td>
                    </tr>
                }
            </tbody>
        </table>
    }
    

    这里是我使用的视图模型 SearchAddressesViewModelAddressModel

    public class SearchAddressesViewModel
    {
        [Required]
        [Display(Name = "Search for address")]
        public string SearchCriteria { get; set; }
    
        public IList<AddressModel> AddressesFound { get; set; }
    }
    
    public class AddressModel
    {
        public string Street { get; set; }
        public string House { get; set; }
        public int Floor { get; set; }
    }
    

    您也可以根据您的情况在视图中为AddressModel 使用部分视图。

    希望你明白我的意思...谢谢

    【讨论】:

    • 感谢谢里夫的帮助。是的,那是我的一个糟糕的设计解决方案。我应该通过将表单的方法设置为 GET 来将表单提交给 Get Index 方法。然后在 Get Index 方法中,我应该检查文本框值是否已提交,如果是,则我使用该地址从 DB 获取信息,否则,仅使用默认地址。因为,@Sherif 您指出这是一种不好的方法,所以我会将您的答案标记为正确。谢谢!
    • @Syed 不要听从这个建议,因为它是非常错误的。您必须在 POST 之后重定向。检查 PRG 模式:en.wikipedia.org/wiki/Post/Redirect/Get.
    • @L-Four ... 请检查以确保此机制适用于搜索过滤器PRG Pattern with Search Filters on Action Method
    • 为什么要使用帖子作为搜索过滤器?没有任何副作用,只是查询数据?
    猜你喜欢
    • 1970-01-01
    • 2021-09-29
    • 2011-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 2019-08-07
    相关资源
    最近更新 更多