2013-09-25 32 views
0

我的问题是非常相似,这一个MVC Rest and returning views但答案是不是为我工作。我使用(http://restfulrouting.com/)在我的MVC应用程序中实现了Restful Routing。MVC宁静的路由,并返回查看

当我要添加新记录的网址是:

localhost/operations/1/exhibits/new 

这就要求其返回New.cshtml作为包含表单视图的新动作。当用户提交表格并在展品控制器上成功调用创建操作时。

如果模型状态有错误,我想通过使用输入的日期仍然存在回返回到新建视图,并显示错误消息(尚未实施)。

目前

return View("New", model) 

发回的数据,并呈现了“新”的观点,但网址更改为:

/localhost/operations/1/exhibits 

我检查了路由值和返回的行动仍是“创建”。我有由动作和控制器值驱动的导航链接,而不正确的url意味着这些导航链接无法正确呈现。

控制器

public class ExhibitController : Controller 
{ 
    public ActionResult Index() 
    { 
     CreateExhibitViewModel model = new CreateExhibitViewModel(); 
     return View(model); 
    } 

    public ActionResult New() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Create(MyModel model) 
    { 
     if(!ModelState.IsValid) 
     { 
      return View("New", model") 
     } 

     // Process my model 
     return RedirectToAction("Index"); 
    } 
} 

查看

@model RocketBook.Web.ViewModels.Exhibit.CreateExhibitViewModel 

@{ 
    Html.HttpMethodOverride(HttpVerbs.Put); 
    ViewBag.Title = "Operation " + ViewBag.OperationName; 
} 

<div class="panel panel-default"> 
    <div class="panel-heading"> 
     <h4>New Exhibit</h4> 
    </div> 
    <div class="panel-body"> 
     <div class="col-lg-6 form-horizontal"> 
      @using (var form = Html.Bootstrap().Begin(new Form("create", "exhibit").Id("newexhibit").Type(FormType.Horizontal).FormMethod(FormMethod.Post).WidthLg(4))) 
      { 
       @Html.AntiForgeryToken()     
       <fieldset> 
        <legend>Details</legend> 
        @Html.HiddenFor(m => m.OperationID) 
        @Html.HiddenFor(m => m.JobID) 
        @form.FormGroup().TextBoxFor(m => m.Barcode) 
        @form.FormGroup().TextBoxFor(m => m.ExhibitRef) 
        @form.FormGroup().TextBoxFor(m => m.ExhibitDescription) 
        @form.FormGroup().DropDownListFor(m => m.ClassificationGroupID, Model.ClassificationGroups).OptionLabel("") 
        @form.FormGroup().DropDownListFor(m => m.ClassificationID, Model.Classifications).OptionLabel("") 
        @form.FormGroup().DropDownListFor(m => m.ExhibitPriority, Model.EntityPriorities).OptionLabel("") 
       </fieldset> 
       <hr /> 
       @(form.FormGroup().CustomControls(
       Html.Bootstrap().SubmitButton().Style(ButtonStyle.Primary).Text("Add Exhibit"))) 

      } 
     </div> 
    </div> 
</div> 

回答

0

在它看起来像OperationsId乍一看没有被分解为URL /表单操作。

当您第一次进入新页面时会发生什么,ASP.NET MVC将传入operationId。 ASP.NET MVC是由试图找到和使用任何路线值,并将其插入到你对你的路线是有帮助的。听起来令人困惑,但让我通过网址解释。

// url 

/localhost/operations/1/exhibits/new 

// on the view 

Url.Action("create", "exhibits", new { /* operationId is implicit */ }) 

接下来我们对创建操作进行POST。

// url 

/localhost/operations/1/exhibits 

// on the view 

Url.Action("create", "exhibits", new { /* operationId is missing! */ }) 

产生的问题是,当你得到,因为从上面的动作缺少operationId送回这个页面。这是ASP.NET MVC中路由值字典的一个症状(我不知道为什么会这样做,但它确实如此)。

解决方案:

我把我的所有路线明确,不要在ASP.NET MVC瘦给你隐含值,因为它仅仅是太难记时使用它们。而不是仅仅得到总是被明确的习惯。

// on new the view 

Url.Action("create", "exhibits", new { operationId = Model.OperationId }) 

// on the edit view 

Url.Action("update", "exhibits", new { operationId = Model.OperationId, id = Model.Id }) 

这会每次都有效,你不必担心你需要的值是否坐在路由值字典中。

+0

好吧我把Url.Action连接成一个链接,然后用Javascript回发。我仍然得到和我原来的问题完全一样的行为。再想一想? – oceanexplorer

+1

啊我明白你的意思,这是Restful Routing的预期行为。你不能指望它进入/新的状态,因为国家在**职位**行动中停了下来。 Rails可以做同样的事情。 –

1

我继续RestfulRouting Github的页面上讨论在

https://github.com/stevehodgkiss/restful-routing/issues/76

对于任何人谁也发现这种行为,是迷茫的,不要,其实它是正确的行为。这是从ASP.NET MVC

否RestfulRouting项目的预期的史蒂夫Hodgkiss创作者的explanaition,这就是你去创建一个模型时的路径,如果出现问题,它被停止很自然那里。当他们通过验证后,他们可以继续前进......

存在两种用于区分URL的解决方案。通话时使用的HTTP方法

http://localhost/operations/1/exhibits 

是一个GET请求,应该调用Index操作。如果我们在创建操作中返回了此URL,但HTTP方法应该显示为POST。这可以通过使用

System.Web.HttpContext.Current.Request.HttpMethod 

另一个解决方案哈立德的建议被访问是:

如果您使用的是视图模型,你可以只从动作内翻转的视图模型的值。由于您将模型返回到创建操作中,因此只需触摸一个属性即可。可以帮你省去

System.Web.HttpContext.Current.Request.HttpMethod 徘徊在你的代码中。

哦,如果你把它放在viewmodel上,你可以用ActionFilter创建一个约定。如果模型== FlippyModel,只是自动翻转该属性。如果失败,那么该属性将为真,如果通过,则转到下一个视图。