4

我在使用NHibernate進行數據訪問的ASP.NET MVC 2 RC應用程序中的模型綁定存在問題。我們試圖用Ruby on Rails的方式構建應用程序,並有一個非常簡單的架構,其中域實體從數據庫一直用到視圖。ASP.NET MVC 2 RC模型與NHibernate和下拉列表綁定

的應用有幾個結構域的實體,其可以由以下兩個類進行說明:

public class Product { 
    ... 

    public Category Category { get; set; }  
} 

public class Category { 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

在呈現編輯表單視圖具有以下語句來顯示一個下拉列表:

<%= Html.DropDownListFor(model => model.Category.Id, 
     new SelectList(ViewData["categories"] as IList<Category>, "Id", "Name"), 
     "-- Select Category --") %> 

請忽略使用「非類型」視圖數據來保存類別集合。

接收表單帖子的操作方法類似於以下內容。請注意,TransactionFilter屬性添加了NHibernate事務處理,並在沒有發生異常且驗證成功的情況下提交事務。

[HttpPost] 
[TransactionFilter] 
public ActionResult Edit(int id, FormCollection collection) { 
    var product = _repository.Load(id); 

    // Update the product except the Id 
    UpdateModel(product, null, null, new[] {"Id"}, collection); 

    if (ModelState.IsValid) { 
     return RedirectToAction("Details", new {id}); 
    } 
    return View(product); 
} 

我的問題是,product.Category.Id設置與表單中選定的值,例如, Category.Id =「2」。在以下類型的NHibernate的異常使用默認的模型綁定結果:

identifier of an instance of Name.Space.Entities.Category was altered from 4 to 2 

這使得有很大的意義,因爲該產品已分配的類別,只有現有的類別的主鍵被改變。應該分配另一個類別實例。

我想可以創建一個自定義的ModelBinder來處理這個問題,但有沒有更簡單的方法來使這項工作?可以(也應該)修改域實體來處理這個問題嗎?

+0

您是否找到了解決此問題的解決方案?我有完全相同的問題。 – nabeelfarid 2011-06-07 22:59:51

+0

不,我從來沒有找到一個好的解決方案(但是,我們沒有花很多時間尋找它)。我們在活頁夾外明確處理了這個問題。 – HakonB 2011-06-08 08:04:34

+0

你能否給我一些提示,你是如何在活頁夾外面處理這個事情的。你沒有使用TryUpdateModel/UpdateModel嗎? – nabeelfarid 2011-06-08 09:23:37

回答

0

我們選擇了當時的解決辦法是與此類似:

TryUpdateModel(product, null, null, new[] {"Category"}, collection); 
int categoryId; 
if (int.TryParse(collection["Category.Id"], NumberStyles.Integer, CultureInfo.InvariantCulture, out categoryId) && categoryId > 0) { 
    product.Category = _categoryRepository.Load(categoryId); 
} 
else { 
    product.Category = null; 
} 

我們只是告訴模型綁定排除關聯屬性和手動處理的。不漂亮,但在工作的時候....

0

我以前用Linq to SQL類的類似技術沒有問題。我不認爲你需要爲此定製ModelBinder。 UpdateModel應該更新您傳遞給它的Product類 - 而不是附加到它的Category子類。檢查由DropDownListFor幫助器生成的html。元素的名稱是什麼?它應該是產品表中外鍵字段的名稱(例如「CategoryID」或「Product.CategoryID」而不是「Category.Id」)。如果它是「Category.Id」 - 嘗試將DropDownListFor的第一個參數更改爲「model => model.Category」或「model => model.CategoryID」(或任何外鍵字段)。這應該會導致UpdateModel僅更新Product類中的外鍵字段而不更新Category類ID。

+1

外鍵不可用,因爲關係完全由NHibernate處理。我最終只是手動處理類別案例,而不是創建自定義模型綁定器 – HakonB 2010-03-11 18:55:49

2

我解決了我的編輯頁面上組合框類似的問題,通過更改以下行

@Html.DropDownListFor(x => x.Employee.Id, new SelectList(ViewBag.Employees, "Id", "DisplayName")) 

通過

@Html.DropDownListFor(x => x.Employee, new SelectList(ViewBag.Employees, "Id", "DisplayName")) 

所以我刪除像布賴恩這樣的'.Id'建議。在更改之前,模型只包含員工的Id,並且在更改之後,Binder還將員工的所有詳細信息加載到模型中。