2009-07-10 3 views
3

У меня есть два элемента управления Address.ascx на странице ASP.NET MVC.Как использовать два экземпляра одного и того же .ascx на одной странице в ASP.NET MVC?

<h1>Shipping Address</h1> 
    <% Html.RenderPartial("Controls/AddressControl"); %> 

    <h1>Billing Address</h1> 
    <% Html.RenderPartial("Controls/AddressControl"); %> 

Конечно, с кодом точно так же я получаю одинаковые идентификаторы для каждого поля в адресе. Я могу легко добавить строку к идентификатору полей, чтобы у меня были 'Street1_billing' и 'Street1_shipping', но я не совсем понимаю, как сопоставить это с моделью.

Какое оптимальное решение для сопоставления модели с массивом элементов (в данном случае всего 2). Я не знаю ни одного решения ASP.NET «из коробки» для этого.

Примечание: Это немного похоже на this question, и я мог бы использовать this solution from Scott Hanselman, но это не совсем то, что я хочу. В моем случае я знаю, что у меня есть два элемента, поэтому его по существу 2 массива элементов, но мне интересно, есть ли немного более элегантное решение.

PS. Я уверен, что это задавали много раз раньше, но я просто не могу найти правильные условия поиска. Пожалуйста, напишите этот вопрос, если вы знаете об обманах!

ответ

3

Вы можете иметь ViewModel

OrderCheckoutViewModel 
{ 
    public Address ShippingAddress{get;set;} 
    public Address BillingAddress{get;set;} 
} 

Значение formelements сопоставляются право члена ViewModel, если они имеют форму

<input type="text" name="ShippingAddress.StreetAddress1"><input> 

Нет простого и элегантного способа перехода от улицыAddress1 до ShippingAddress.StreetAddress1. Мой адрес модель имеет вид:

public class Address 
{ 
    String StreetAddress1 { get; set } 
    String StreetAddress2 { get; set } 
    String City { get; set } 
    String State { get; set } 
    String Zip { get; set } 
    String InstanceName{ get; set } 
} 

Я установить InstanceName на имя свойства (ShippingAddress).

Затем элементы формы определены в этой форме

<input type="text" name="<%=Model.InstanceName%>.StreetAddress1"><input> 

Место ASCX выглядит необычно.Любая причина, по которой вы не разместите ее в разделе «Доступ к ней» и получите к ней доступ

<% Html.RenderPartial("AddressControl",Model.ShippingAddress); %> 

?

+0

спасибо. это выглядит самым чистым решением. Я не понял, что модельный манипулятор был таким умным :-), и насколько это касается местоположения .ascx, я пишу корзину покупок в существующем приложении, и я хочу, чтобы элементы управления корзиной покупок были как можно более раздельными. –

+0

Этот парень умный. Одна вещь, которую я до сих пор не видел, - это если вы можете сопоставить значение с маршрутом с тем же типом синтаксиса. –

4

Прежде всего, добавьте Адрес класс модели.

public class Address 
{ 
    String StreetAddress1 { get; set } 
    String StreetAddress2 { get; set } 
    String City { get; set } 
    String State { get; set } 
    String Zip { get; set } 
} 


В Address.ascx, вам нужна строка в верхней части, который наследует модель адреса, как это:

<%@ Page Language="C#" 
    Inherits="System.Web.Mvc.ViewPage<MyProject.Models.Address>" %> 


В контроллере для главного вида , нажмите два ваших адреса в ViewData.

Address myAddressObject1 = new Address 
{ 
    AddressLine1 = "123 Anywhere Street", 
    // ..etc. Same with MyAddressObject2. Or, just populate from database. 
} 

ViewData["Address1"] = myAddressObject1; 
ViewData["Address2"] = myAddressObject2; 
// 
// do other stuff as needed 
// 
Return View(); 


В вашем главного окна, звоните свои два адресных подвиды, как это:

<%= Html.RenderPartial("Address", ViewData["Address1"]) %> 
<%= Html.RenderPartial("Address", ViewData["Address2"]) %>