1

Steve Sanderson の著書のサンプルに基づいて、セッションを使用してカスタム モデル バインダーを実装する方法のサンプルを提供しました。もちろん、global.asax.cs に登録する必要があります。

public class CartModelBinder : IModelBinder
{
    private string sessionKey = "Cart";

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        Cart cart = (Cart)controllerContext.HttpContext.Session[this.sessionKey];
        if (cart == null)
        {
            cart = new Cart();
            controllerContext.HttpContext.Session[this.sessionKey] = cart;
        }

        return cart;
    }
}

モードクラス

public class Cart
{
    private List<int> itemList;

    public List<int> ItemList
    {
        get
        {
            return this.itemList;
        }
    }

    public Cart()
    {
        this.itemList = new List<int>();
    }

    public void AddItem(int itemId)
    {
        this.itemList.Add(itemId);
    }
}

次に、コントローラー/アクションでそれを使用します:

public class HomeController : Controller
{
    public ActionResult Index(Cart cart)
    {
        return View();
    }

    [HttpPost]
    public ActionResult AddToCart(Cart cart, int id)
    {
        cart.AddItem(id);

        return View(cart);
    }
}

Index.cshtml見る

@model MvcApplication2.Models.Cart

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        @using (@Html.BeginForm("AddToCart", "Home")) {
        <h1>Cart form</h1>
            @Html.TextBox("id")

            <input type="submit" />
        }
    </div>
</body>
</html>

AddToCart.cshtml見る

@model MvcApplication2.Models.Cart

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AddToCart</title>
</head>
<body>
    <div>
        @foreach (int itemId in Model.ItemList)
        { 
            @Html.Label(itemId.ToString())<br />
        }
        @Html.ActionLink("Go back", "Index")
    </div>
</body>
</html>

しかし、ここでの私の質問は、値を更新してセッションに戻すコードが表示されないことです。それはどのように起こりますか?

4

1 に答える 1

0

コントローラーの Session に保存する必要があります。

public RedirectToRouteAction AddToCart(Cart cart)
{
    cart.AddItem(newItem);

    HttpContext.Session["Cart"] = cart;
}

更新: セッション変数は、IEnumerable および ICollection を実装する SessionStateItemCollection オブジェクトに格納されます。オブジェクトをセッションに保存すると、オブジェクトの新しいインスタンスではなく、オブジェクトへの参照のみが保存されます。そのため、オブジェクトに変更を加えると、実際にはセッション内にある同じオブジェクトに変更を加えることになります (そのオブジェクトへの参照はセッションに保存されます)。これは、オブジェクトを作成してリストに追加するのと同じです。オブジェクトをリストに追加した後にオブジェクトを更新すると、実際にはリスト内の同じインスタンスが更新されます。

したがって、この場合、カートをセッションに保存し直す必要はありません。モデル バインダーは、セッションにカートがない場合にのみ新しいカートを作成するため、セッションがアクティブである限り、カートがあり、 Cart オブジェクトは 1 つだけです。

于 2013-07-12T15:56:03.293 に答える