0

現在の進行状況をブロックする ASP.NET MVC 3 アプリケーションで奇妙なニーズがあります。これがケースです:

製品用の小さな検索エンジンがあり、この検索エンジンを複数のページに表示しています。productこの SE は、コントローラーのsearchアクションに対して HTTP POST 要求を行います。ここまでは大丈夫。

私がhomeコントローラーのindexアクション(/home/index)にいると仮定しましょう。検索して確認しますModelState.IsValid。その結果、有効ではありません。そのため、入力されたモデル (ユーザーが値を失わないようにするため) とモデル状態エラーと共にこれを返す必要があります。しかし、それを行うと、予想どおり別の URL (/product/search) になりました。

リダイレクトを行うと、ModelStateエラー メッセージが失われ、表示できません。

これまでにさまざまなソリューションがあり、それらはすべて汚れているように見えます。何か案が?

編集

これを示す小さなプロジェクトを次に示します。

これは次のProductControllerとおりです。

public class ProductController : Controller {

    [HttpPost]
    public ActionResult Search(SearchModel searchModel) {

        if (ModelState.IsValid) { 
            //Do some stuff...

            return RedirectToAction("Index", "SearchResult");
        }
        return View(searchModel);
    }
}

これは次のSearchModelとおりです。

public class SearchModel {

    [Required]
    public string ProductCategory { get; set; }

    [Required]
    public string ProductName { get; set; }
}

これは *_SearchPartial* です:

@model MvcApplication20.SearchModel

@using (Html.BeginForm("search", "product"))
{
    @Html.EditorForModel()

    <input type="submit" value="Search" />
}

最後に、これは*_SearchPartial* をレンダリングするHomeコントローラーアクション ビューです。Index

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>

@Html.Partial("_SearchPartialView")

Productここで、フォームを送信してモデルの状態が失敗した場合、コントローラーのSearchアクションをどのように進めればよいでしょうか?

4

2 に答える 2

2

Here, when I submit the form and if the model state fails, how should I proceed at the Product controller Search action?

Normally in this case you should render the _SearchPartialView but not as a partial but as a full view with layout so that the user can fix his errors. No need to stay at Home/Index in this case:

[HttpPost]
public ActionResult Search(SearchModel searchModel) {

    if (ModelState.IsValid) { 
        //Do some stuff...

        return RedirectToAction("Index", "SearchResult");
    }
    // since we are returning a view instead of a partial view,
    // the _SearchPartialView template should be displayed with the layout
    return View("_SearchPartialView", searchModel);
}

And if you wanted to stay on the same page upon error you could use an AJAX call to perform the search. So you would AJAXify this search form and then in the success callback test the result of the Search action and based on it decide whether to refresh the partial in order to show the error or redirect to the results action using window.location.href:

something along the lines of:

$(document).on('submit', '#searchForm', function() {
    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(), 
        success: function(result) {
            if (result.redirectTo) {
                // no validation errors we can redirect now:
                window.location.href = result.redirectTo;
            } else {
                // there were validation errors, refresh the partial to show them
                $('#searchContainer').html(result);

                // if you want to enable client side validation
                // with jquery unobtrusive validate for this search form
                // don't forget to call the .parse method here 
                // since we are updating the DOM dynamically and we
                // need to reattach client side validators to the new elements:
                // $.validator.unobtrusive.parse(result);
            }
        }
    });
    return false;
});

This obviously assumes that you have now wrapped the partial call in a div with id="searchContainer" and that you provided an id="searchForm" when generating the search form:

<div id="searchContainer">
    @Html.Partial("_SearchPartialView")
</div>

and now the search action:

[HttpPost]
public ActionResult Search(SearchModel searchModel) {

    if (ModelState.IsValid) { 
        //Do some stuff...

        return Json(new { redirectTo = Url.Action("Index", "SearchResult") });
    }
    return PartialView("_SearchPartialView", searchModel);
}
于 2012-02-13T09:44:45.897 に答える
1

RedirectToActionを実行するとModelStateが失われることがわかっている限り、解決策はTempDataにモデル状態を保存することです。これは、私が使用している例の1つです。

http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg

これは、インスタンスMVC Transfer Data Between Viewsなどのさまざまな投稿でも説明されています

于 2012-02-13T10:53:00.937 に答える