MVC 4 - привязка пользовательской модели с абстрактным классом - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь следовать рекомендациям онлайн, чтобы создать пользовательское связующее для моделей.Причина, по которой я это делаю, заключается в том, что у меня есть абстрактный класс, из которого я хочу создать экземпляр для детей.У меня есть "MasterTicket" абстрактный родитель с "MasterTicketItems" как абстрактный ребенок.

Идея состоит в том, что конкретные дочерние элементы в иерархии наследования будут иметь своих конкретных дочерних элементов (т. Е. Задачи назначения (один дочерний) имеют ApptTaskItems, а общие задачи имеют GenLogItems, инцидентные задачи имеют IncidentLogItems и т. Д.).

Проблема заключается в том, что при создании журнала мой связыватель моделей фактически не связывает данные с конкретными дочерними элементами, которые я хотел вернуть из связывателя моделей.Вот код связывателя модели:

public class MasterTicketItemBinder : DefaultModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Guid ticketId)
        {
            var values = (ValueProviderCollection)bindingContext.ValueProvider;
            IEnumerable<MasterTicket> uptList = StaticDataStore.tickets;
            var currTicket = uptList.Single(a => a.id == ticketId);
            //var name = (string)values.GetValue("Name").ConvertTo(typeof(string));
            return currTicket is ApptTaskTicket ? (MasterTicketItem)new ApptConfirmItem() { ticketItemId = Guid.NewGuid() } : new GenLogItem() { ticketItemId = Guid.NewGuid() };
        }
    }

Вот мой файл Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
    {
        private readonly List<ApptTaskTicket> _initialTickets;
        private readonly List<Personnel> _allUsers;

        public MvcApplication()
        {
            _initialTickets = new List<ApptTaskTicket>();
            _allUsers = new List<Personnel>();
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            ModelBinders.Binders.Add(typeof(MasterTicketItem), new MasterTicketItemBinder());
            Application["taskTickets"] = new List<ApptTaskTicket>();
            Application["allUsers"] = new List<Personnel>();
        }
    }

А вот мой MasterTicketItem:

[Table("TicketItem")]
[ModelBinder(typeof(MasterTicketItemBinder))]
public abstract class MasterTicketItem
{
    public Guid ticketItemId{ get; set; }
    public DateTime createTime{ get; set; }
    public bool active{ get; set; }
    public DateTime updateTime{ get; set; }
    //TODO: Create foreign key relation
    public Guid userCreatedId{ get; set; }
    public Guid userUpdateId{ get; set; }
    public Guid userOwnerId{ get; set; }
    public string itemType{ get; set; }
    public string itemDescription{ get; set; }
    public int timesUpdated{ get; set; }
    public DateTime expectedCompletionTime{ get; set; }
    public DateTime actualCompletionTime{ get; set; }

    public MasterTicketItem()
    {

    }
}

Кроме того, воткод сообщения JavaScript для рассматриваемого контроллера:

handleLogSubmit(log) {
    //e.preventDefault();
    const logs = this.state.data.masterTicketItems;
    // Optimistically set an id on the new comment. It will be replaced by an
    // id generated by the server. In a production application you would likely
    // use a more robust system for ID generation.
    if (!logs) {
        log.ticketItemId = 1;
        log.createTime = new Date().toISOString();
        log.userCreatedId = this.userState.data.userId;
        const newLogs = log;
        let masterItemsAccess = Object.assign({}, this.state.data);
        masterItemsAccess.masterTicketItems = log;
        this.setState(prevData => ({...prevData, data: { ...prevData.data, masterTicketItems: [log], apptConfirmItems: [log] } }));
    }
    else {
        log.ticketItemId = logs.length + 1;
        log.createTime = new Date().toISOString();
        log.userCreatedId = this.userState.data.userId;
        const newLogs = logs.concat([log]);
        this.setState(prevData => ({ ...prevData, data: { ...prevData.data, masterTicketItems: newLogs, apptConfirmItems: newLogs } }));
    }

    const data = new FormData();


    data.append('ItemType', log.itemType);
    data.append('ItemDescription', log.itemDescription);
    data.append('UserCreatedId', log.userCreatedId);
    data.append('CreateTime', log.createTime);
    data.append("ticketId", this.state.data.id);


    const xhr = new XMLHttpRequest();
    xhr.open('post', this.props.submitUrl, true);
    xhr.onload = () => this.loadLogsFromServer();
    xhr.send(data);
}

Наконец, вот рассматриваемый контроллер, с которым у меня возникают проблемы («не удается создать абстрактный класс»):

[HttpPost]
public ActionResult AddLog([ModelBinder(typeof(MasterTicketItemBinder))]MasterTicketItem log, Guid ticketId)
{
    IEnumerable<MasterTicket> uptList = StaticDataStore.tickets;
    var currTicket = uptList.Single(a => a.id == ticketId);
    MasterTicketItem newLog;
    if(currTicket is ApptTaskTicket)
    {
        newLog = new ApptConfirmItem();
    }
    else
    {
        newLog = new GenLogItem();
    }
    // Create a new ID for this working log
    newLog.ticketItemId = Guid.NewGuid();
    //ticket.masterTicketItems.Add(log);
    if(currTicket.masterTicketItems is null)
        uptList.Single(a => a.id == ticketId).masterTicketItems = new List<MasterTicketItem>() { newLog };
    else
        uptList.Single(a => a.id == ticketId).masterTicketItems.Add(newLog);
    Personnel user = (Personnel)Session["loggedInUser"];
    uptList.Single(a => a.id == ticketId).userUpdateId = user.userId;
    uptList.Single(a => a.id == ticketId).TimesUpdated = Utility.updateIncrement(uptList.Single(a => a.id == ticketId));
    StaticDataStore.tickets = uptList;
    return Content("Success :)");
}

Можеткто-нибудь, дайте мне знать, что я должен делать здесь?Цель состоит в том, чтобы вернуть класс элемента дочернего билета на основе родительского билета, который передается контроллеру по идентификатору.

Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...