asp.net-mvc - MVC ASP.NET 2向导通过项目 array

  显示原文与译文双语对照的内容
0 0

我在做一个小小的建议。 我是MVC新手,一直在尝试将一个使用web服务的示例应用程序来获取数据。 数据正从 Microsoft Navision数据库返回。 我希望放在一起的一个屏幕是一个向导,它允许用户在项目列表中前后移动,并在通过公开的web服务提交到数据库之前整理所有的修改。 我的想法是最小化网络服务调用。

我是史蒂文 Sandersons - Pro ASP.NET MVC 2框架书,他有一节关于向导和跨各种Contollers对象进行序列化和反序列化,但是在我的情况下我希望调用相同的控制器,但用不同的指数显示正确的项目记录。 视图将具有对列表的强类型引用。

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

非常感谢

pf79


更新

谢谢你的回答但我觉得我找到了答案。 我试图让它保持服务器端,因为我可能在 Windows 6移动设备上使用它,而且我以前没有真正使用过 javascript ;

使用TempData和序列化的组合,我就能够实现这一点。 不确定这是否是"最佳实践"。 关于如何改进的建议将得到极大的赞赏。

我有一个项目类


public class Item
{
 public int Id { get; set; }
 public string Name { get; set; }
 public decimal Price { get; set; }
}

然后我有一个web服务调用,它返回来自控制器类中另一个方法的项的列表。


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");
 }

这将列表和currentIndex通过OnResultExecuted放入 TempData


protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
 if (filterContext.Result is RedirectToRouteResult)
 {
 TempData["testItemList"] = testItemList;
 TempData["currIndex"] = currentIndex;
 }
}

控制器


[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);
}

然后在视图中,我同时序列化列表和当前索引,以便能够跟踪它。


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;
 }

}

视图


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ArrayTest.Models.Item>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 Details
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
 <h2>
 Details</h2>
 <% int Index = (int)TempData["currIndex"]; %> 
 <% var ItemList = (List<ArrayTest.Models.Item>)TempData["itemList"]; %>
 <% using (Html.BeginForm())
 {%> 
 <%: Html.Serialize("itemList",ItemList) %>
 <%: Html.Serialize("currIndex",Index) %> 
 <%: Html.ValidationSummary() %>
 <p>
 <%: Html.EditorFor(t => t.Name) %></p>
 <p>
 <%: Html.EditorFor(t => t.Price) %></p>
 <input type="submit" value="Back" name="back"/>
 <input type="submit" value="Next" name="next"/>
 <%} %>
</asp:Content>

时间: 原作者:

0 0

它非常依赖于表单的复杂性,无论你是否需要存储临时数据,如果用户需要半次填充表单并返回另一个表单,则需要保存该临时数据。

我个人希望客户端向导使用各种 jquery向导插件可用。 jquery插件lightbox虽然不是用来向导中,可以使用。 这有一些优点:

  • 限制通话次数和用户可以做多少修改的次数。 所以在web服务调用方面是最佳的。
  • 对服务器端技术( 如 ASP 。NET MVC ) 自身更好
  • 它可以用一个简单的实现来节省一半的填充空间。

但是它需要很好的客户端验证,以减少由于无效日期而导致的往返过程,但是现在有几十个工具可以选择健壮的客户端验证。

原作者:
0 0

如果你真的想要服务器端向导,请尝试:

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


//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.
}

在本例中,我希望在向导中。 因此我们将有三个视图。

第 1步。


//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>
}

现在步骤 2.


//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>
}

最后步骤 3 。


//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>
}

希望这有帮助。请注意,我没有在IDE中测试这里代码,因为我不在开发计算机上。 我相信需要调整但你得知道。

原作者:
...