2013-09-25 31 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,只是自動翻轉該屬性。如果失敗,那麼該屬性將爲真,如果通過,則轉到下一個視圖。