Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc MVC ASP.NET 2-项目数组向导_Asp.net Mvc - Fatal编程技术网

Asp.net mvc MVC ASP.NET 2-项目数组向导

Asp.net mvc MVC ASP.NET 2-项目数组向导,asp.net-mvc,Asp.net Mvc,我想要一点建议。我是MVC新手,一直在尝试编写一个使用web服务获取数据的示例应用程序。正在从Microsoft Navision数据库返回数据。 我希望整合的一个屏幕是一个向导,它允许用户在项目列表中来回移动,并在通过公开的web服务提交回数据库之前整理所有修改。 我的想法是尽量减少web服务调用 我一直在关注Steven Sandersons-Pro ASP.NET MVC 2 Framework一书,他有一节介绍了向导、序列化和反序列化各种控件中的对象,但在我的例子中,我希望调用同一个控制

我想要一点建议。我是MVC新手,一直在尝试编写一个使用web服务获取数据的示例应用程序。正在从Microsoft Navision数据库返回数据。 我希望整合的一个屏幕是一个向导,它允许用户在项目列表中来回移动,并在通过公开的web服务提交回数据库之前整理所有修改。 我的想法是尽量减少web服务调用

我一直在关注Steven Sandersons-Pro ASP.NET MVC 2 Framework一书,他有一节介绍了向导、序列化和反序列化各种控件中的对象,但在我的例子中,我希望调用同一个控制器,但可能使用不同的索引号来显示正确的项目记录。视图将具有对列表的强类型引用

请你告诉我这是不是一个正确的方法,或者这是否真的是可能的

非常感谢

pf79


更新

谢谢你的回答,但我想我已经找到了答案。我试图将它保留在服务器端,因为我可能在Windows6移动设备上使用它,而且我以前也没有真正使用过javascript

通过结合使用TempData和序列化,我能够实现这一点。不确定这是否是“最佳实践”。任何关于如何改进的建议都将不胜感激

我有一个项目类

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}
然后,我有一个webservice调用,它将从控制器类中的另一个方法返回一个项列表

public ActionResult GetDetails()
        {
            //Test filling List. Will be retrieved from Web Service eventually.
            testItemList = new List<Item>();
            testItemList.Add(new Item() { Id = 1, Name = "Bike", Price = new decimal(1000) });
            testItemList.Add(new Item() { Id = 2, Name = "Wheel", Price = new decimal(99.99) });
            testItemList.Add(new Item() { Id = 3, Name = "Saddle", Price = new decimal(49.99) });


            TempData["itemList"] = testItemList;
            return RedirectToAction("Details");
        }
控制器

[HttpGet]
public ActionResult Details()
{
    testItemList = (IList<Item>)TempData["itemList"];
    currentIndex = (int)TempData["currIndex"];

    return View(testItemList[currentIndex]);
}

[HttpPost]
public ActionResult Details(string next, string back)
{
    var testItem = testItemList[currentIndex];

    if (TryUpdateModel(testItem))
    {
        if (next != null)
        {
            currentIndex = (currentIndex + 1) == testItemList.Count ? currentIndex : currentIndex + 1;
        }

        if (back != null)
        {
            currentIndex = (currentIndex - 1) < 0 ? currentIndex : currentIndex - 1;
        }

        TempData["currIndex"] = currentIndex;
        TempData["itemList"] = testItemList;

        return RedirectToAction("Details"); 
    }

    TempData["currIndex"] = currentIndex;
    TempData["itemList"] = testItemList;

    return View(testItem);
}
[HttpGet]
公众行动结果详情()
{
testItemList=(IList)TempData[“itemList”];
currentIndex=(int)TempData[“currentIndex”];
返回视图(testItemList[currentIndex]);
}
[HttpPost]
公共操作结果详细信息(下一个字符串,下一个字符串)
{
var testItem=testItemList[currentIndex];
if(TryUpdateModel(testItem))
{
如果(下一步!=null)
{
currentIndex=(currentIndex+1)=testItemList.Count?currentIndex:currentIndex+1;
}
如果(返回!=null)
{
currentIndex=(currentIndex-1)<0?currentIndex:currentIndex-1;
}
TempData[“currIndex”]=当前索引;
TempData[“itemList”]=testItemList;
返回重定向操作(“详细信息”);
}
TempData[“currIndex”]=当前索引;
TempData[“itemList”]=testItemList;
返回视图(testItem);
}
然后在视图上,我序列化列表和当前索引,以便跟踪它

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var listSerialized = Request.Form["itemList"];
    if (listSerialized != null)
    {
        testItemList = (IList<Item>)new MvcSerializer().Deserialize(listSerialized);
    }

    var indexSerialized = Request.Form["currIndex"];
    if (indexSerialized != null)
    {
        currentIndex = (int)new MvcSerializer().Deserialize(indexSerialized);
    }
    else
    {
        currentIndex = 0;
    }

}
受保护的覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
var listSerialized=Request.Form[“itemList”];
if(listSerialized!=null)
{
testItemList=(IList)新的MvcSerializer()。反序列化(listSerialized);
}
var indexSerialized=Request.Form[“currendex”];
如果(indexSerialized!=null)
{
currentIndex=(int)新的MvcSerializer()。反序列化(indexSerialized);
}
其他的
{
currentIndex=0;
}
}
看法


细节
细节

t、 名称)%%>

t、 价格)%>


这在很大程度上取决于表单的复杂性,以及如果用户需要一半填写表单,然后下次再来,是否需要存储临时数据并可能进行保存

我个人喜欢使用各种可用的客户端向导。虽然不是用于向导,但可以用于向导。这有几个优点:

  • 通话次数限制为最后一次通话,用户可以根据自己的意愿进行任意修改。因此,在web服务调用方面是最佳的
  • 更好地支持服务器端技术,如ASP NET MVC
  • 它可以通过简单的实现来保存半填充的表单

但它需要非常好的客户端验证,以尽量减少由于无效日期而产生的往返,但现在有几十种工具可供您选择,以实现健壮的客户端验证。

如果您确实需要服务器端向导,请尝试以下方法:

假设您有一个将在向导完成时填充的模型

// This is a pseudo-model to show the properties Member has in this example.
// I use entity framework when generating my model objects. How you generate
// your model objects is not important in this example.
public class Member
{
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string ReferredBy { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
}
我建立了一个名为
Member
的简单模型,我们的向导最终将填充该模型。现在,我将构建一个视图模型,用于向导页面

public class RegisterViewModel
{
    public Member NewMember { get; set; }
    public int Step { get; set; } //int cannot be null and will be 0 by default.
}
现在我要建立一些行动方法

// First request will pull up the first view of the wizard with 
// a new RegisterViewModel.
[HttpGet]
public ViewResult RegisterNewMember()
{
    return View("RegisterWizardStep1", new RegisterViewModel());
}

// This will be the post action method. Rather than create a different
// action method for every step of the wizard, our view model will support
// which step we are on and this method will be aware of what to do.
[HttpPost]
public ViewResult RegisterNewMember(RegisterViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        if (viewModel.Step < 2)
            return View(String.Format("RegisterWizardStep{0}", viewModel.Step + 1), viewModel);
        else
        {
            db.Members.AddObject(viewModel.NewMember);
            db.SaveChanges();
            // db is a fictional context. The syntax is that of entity framework.
            // You could substitute this for a LINQ to SQL context or any other
            // data storage component.
            ViewBag.WelcomeMessage = "Thank you for registering. We welcome you!";
            return View("Welcome");
        }
    }
    else
        return View(String.Format("RegisterWizardStep{0}", viewModel.Step));
        // Assuming you have model validation set up, returning the same view with
        // an invalid modelstate will trigger your validation helpers.
}
//第一个请求将使用
//一个新的RegisterViewModel。
[HttpGet]
公共视图结果注册表成员()
{
返回视图(“RegisterWizardStep1”,newRegisterViewModel());
}
//这将是操作后的方法。而不是创造一个不同的
//对于向导的每个步骤,我们的视图模型都将支持
//我们正在进行哪一步,这种方法将知道该做什么。
[HttpPost]
公共视图结果RegisterNewMember(RegisterViewModel视图模型)
{
if(ModelState.IsValid)
{
如果(viewModel.Step<2)
返回视图(String.Format(“RegisterWizardStep{0}”、viewModel.Step+1)、viewModel);
其他的
{
db.Members.AddObject(viewModel.NewMember);
db.SaveChanges();
//db是一个虚构的上下文,语法是实体框架的语法。
//您可以将其替换为LINQ到SQL上下文或任何其他上下文
//数据存储组件。
ViewBag.WelcomeMessage=“感谢您的注册。我们欢迎您!”;
返回视图(“欢迎”);
}
}
其他的
返回视图(String.Format(“RegisterWizardStep{0}”,viewModel.Step));
//假设已设置模型验证,则返回相同的视图
//无效的modelstate将触发验证帮助程序。
}
在这个例子中,我需要三个步骤
public class RegisterViewModel
{
    public Member NewMember { get; set; }
    public int Step { get; set; } //int cannot be null and will be 0 by default.
}
// First request will pull up the first view of the wizard with 
// a new RegisterViewModel.
[HttpGet]
public ViewResult RegisterNewMember()
{
    return View("RegisterWizardStep1", new RegisterViewModel());
}

// This will be the post action method. Rather than create a different
// action method for every step of the wizard, our view model will support
// which step we are on and this method will be aware of what to do.
[HttpPost]
public ViewResult RegisterNewMember(RegisterViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        if (viewModel.Step < 2)
            return View(String.Format("RegisterWizardStep{0}", viewModel.Step + 1), viewModel);
        else
        {
            db.Members.AddObject(viewModel.NewMember);
            db.SaveChanges();
            // db is a fictional context. The syntax is that of entity framework.
            // You could substitute this for a LINQ to SQL context or any other
            // data storage component.
            ViewBag.WelcomeMessage = "Thank you for registering. We welcome you!";
            return View("Welcome");
        }
    }
    else
        return View(String.Format("RegisterWizardStep{0}", viewModel.Step));
        // Assuming you have model validation set up, returning the same view with
        // an invalid modelstate will trigger your validation helpers.
}
// RegisterWizardStep0
@model AppName.Models.RegisterNewMember
@using AppName.Models;
@{
    Layout = "~/Views/Shared/Master.cshtml";
}

@* I'm not going to worry much about formatting in these views as they are only samples.
   I am also not going to worry about client-side validation before step submission;
   I will let you worry about that. *@

@using(Html.BeginForm())
{
    <text>
    @Html.HiddenFor(x => x.Step)

    @Html.TextBoxFor(x => x.NewMember.Username)
    @Html.ValidationMessageFor(x => x.NewMember.Username)
    <br />
    @Html.TextBoxFor(x => x.NewMember.FirstName)
    @Html.ValidationMessageFor(x => x.NewMember.FirstName)
    <br />
    @Html.TextBoxFor(x => x.NewMember.LastName)
    @Html.ValidationMessageFor(x => x.NewMember.LastName)
    <br />
    <input type="submit" value="Next" />
    </text>
}
// RegisterWizardStep1
@model AppName.Models.RegisterNewMember
@using AppName.Models;
@{
    Layout = "~/Views/Shared/Master.cshtml";
}

@using(Html.BeginForm())
{
    <text>
    @Html.HiddenFor(x => x.Step)

    @Html.HiddenFor(x => x.Member.Username)
    @Html.HiddenFor(x => x.NewMember.FirstName)
    @Html.HiddenFor(x => x.NewMember.LastName)

    @Html.TextBoxFor(x => x.NewMember.Email)
    @Html.ValidationMessageFor(x => x.NewMember.Email)
    <br />
    @Html.TextBoxFor(x => x.NewMember.ReferredBy)
    @Html.ValidationMessageFor(x => x.NewMember.ReferredBy)
    <br />
    <input type="submit" value="Next" />
    </text>
}
// RegisterWizardStep2
@model AppName.Models.RegisterViewModel
@using AppName.Models;
@{
    Layout = "~/Views/Shared/Master.cshtml";
}

@using(Html.BeginForm())
{
    <text>
    @Html.HiddenFor(x => x.Step)

    @Html.HiddenFor(x => x.NewMember.Username)
    @Html.HiddenFor(x => x.NewMember.FirstName)
    @Html.HiddenFor(x => x.NewMember.LastName)
    @Html.HiddenFor(x => x.NewMember.Email)
    @Html.HiddenFor(x => x.NewMember.ReferredBy)

    @Html.TextBoxFor(x => x.NewMember.Address)
    @Html.ValidationMessageFor(x => x.NewMember.Address)
    <br />
    @Html.TextBoxFor(x => x.NewMember.City)
    @Html.ValidationMessageFor(x => x.NewMember.City)
    <br />
    @Html.TextBoxFor(x => x.NewMember.State)
    @Html.ValidationMessageFor(x => x.NewMember.State)
    <br />
    @Html.TextBoxFor(x => x.NewMember.Country)
    @Html.ValidationMessageFor(x => x.NewMember.Country)
    <br />
    <input type="submit" value="Done" />
    </text>
}