开发者

Why is MVC persisting on HttpGet?

I thought I understood MVC until now. To me a GET should be from a clean slate. But I discoved today MVC assumes a GET to be a POST if a page request a get from itself. The text box should always show the text "Red" but instead it persist its last value from the previous view. Acting like an HTTPPost. You have t开发者_C百科o uncomment ModelState.Clear to act like a HttpGet. This appears to me to be a bug.

<form action="" method="get">
    <div>
        <%=Html.TextBox("search") %>
        <input type="submit" value="Search" />
    </div>
    </form>

 [HttpGet]
        public ActionResult Index(string search)
        {
            //ModelState.Clear();
            ViewData["search"] = "Red";      

            var items = GetYourTestData;
            if (!string.IsNullOrEmpty(search))
            {
                var items2 = items.Where(x => x.Color == search).ToList();

                return View(items2);

            }

            return View(items);
        }

The search results returns correct and different data so it is not browser cache. For the purpose of a search results page it does not make sense to have to redirect to another page to avoid this. That is why I chose GET thinking it should be clean each time.


Like I stated in the description. Other contents on the page does change so it is not cache. Uncomment ModelState.Clear() and all is good so that is not cache. You can put a dynamic datetime label always showing the latest time from the server and it does change. That also proves it is not page cache. It is a very simple test to do. Yes, just a sure as there is gravity, MVC2 framework 4.0 considers it an HTTPPost if the HttpGet requested page is the same as the requester. If you are not aware of this during programming the results could be disastrous. For instance, If someone like TurboTax uses MVC I hope that their developer are aware of that. ... ViewData["AdjustedTaxAmount"]=3435.00; ... is not going to work unless they call this ModelState.Clear().

I don't know of why there should be ModelState on a get so one sure fire work around is to Inherit Controller from a base class

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    if (string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
    {
        ModelState.Clear();
    } 

    base.OnActionExecuted(filterContext);
}


The browser will cache GET requests that are from the same URL. If you add a querystring variable that is random then the GET request will be different each time and the browser will not cache the result.


That's to be expected.

When you submit a form via GET, you're serializing its elements and passing those to the target via the QueryString. So, it makes sense that your search value would be part of MVC's model in the next request. When you use the Html.TextBox helper, it's going to automatically inject the model's value as the HTML input's value. That's why you're seeing the value cover over.

One solution to avoid that is to not use the HTML Helper to render the input:

<form action="" method="get">
  <div>
    <input type="text" name="search" />
    <input type="submit" value="Search" />
  </div>
</form>

Then, you should get the clean slate you're expecting after each form submission.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜