Элемент ViewData с ключом message имеет тип System.String, но должен иметь тип IEnumerable ‹SelectListItem›.

Я пытаюсь реализовать приложение MVC, которое имеет представление, контроллер и модель представления, чтобы заполнить раскрывающийся список из базы данных, а затем использовать данные для выбранного элемента в [HttpPost]. Ниже приведены данные в каждом из соответствующих файлов:

MessageController.cs

public String send_url;
    private msg_cmsEntities smse = new msg_cmsEntities();
public ActionResult Message_Send_Get()
{

    var model = new MessageModel
    {
        MessagesList = smse.Messages
           .Select(c => new SelectListItem
           {
               Value = c.message1,
               Text = c.message1
           })
    };
    return View(model);            
}

[HttpPost]
    public ActionResult Message_Send_Get(String code, String password, String from, String Message_List, MessageModel message_to_send)
    {
        //If the Model is valid (no errors) then go into this statement
        if (ModelState.IsValid)
        {
            WebRequest wrGETURL;

        //This is a string that points to the location of the Web Service 
        string web_service_location = "http://www.google.com?";

        //This initates a new writeable instance of HttpValueCollection
        NameValueCollection query_string = System.Web.HttpUtility.ParseQueryString(string.Empty);
        //This builds up the query string that will be used for the redirect
        query_string["code"] = code;
        query_string["password"] = password;
        query_string["from"] = from;
        query_string["msg"] = Message_List;

        //This concatinates the web_service_location (String) and query_string (String)
        send_url = web_service_location + query_string.ToString();


        Debug.WriteLine(send_url);

        wrGETURL = WebRequest.Create(send_url);
    }
    var model = new MessageModel
    {
        MessagesList = smse.Messages
           .Select(c => new SelectListItem
           {
               Value = c.message1,
               Text = c.message1
           })
    };
    return View(message_to_send);
}

Message_Send_Get.aspx (Просмотр):

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Message_Send.Models.MessageModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Message_Send_Get
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Message_Send_Get</h2>

    <% using (Html.BeginForm()) {%>
        <%: Html.ValidationSummary(true) %>

        <fieldset>
            <legend>Fields</legend>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.code) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.code) %>
                <%: Html.ValidationMessageFor(model => model.code) %>
            </div>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.password) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.password) %>
                <%: Html.ValidationMessageFor(model => model.password) %>
            </div>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.from) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.from) %>
                <%: Html.ValidationMessageFor(model => model.from) %>
            </div>

            <div class="editor-label">
                <%: Html.LabelFor(model => model.message) %>
            </div>
            <div class="editor-field">
                <%= Html.DropDownListFor(model => model.message, Model.MessagesList)%>
                <%: Html.ValidationMessageFor(model => model.message) %>
            </div>               

            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%: Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>

MessageModels.cs

public class MessageModel
    {
        [Required(ErrorMessage = "You must enter a code for this service!!")]
        [DataType(DataType.Text)]
        [DisplayName("Code")]
        public string code { get; set; }

        [Required(ErrorMessage = "A password is required for the service!!")]
        [DataType(DataType.Text)]
        [DisplayName("Password")]
        public string password { get; set; }

        [Required(ErrorMessage = "You must enter the 'From' information!!")]
        [DataType(DataType.Text)]
        [DisplayName("Message From")]
        public string sms_from { get; set; }

        [Required]
        [DisplayName("Send Message")]
        public string message { get; set; }

        public IEnumerable<SelectListItem> MessagesList { get; set; }
    }

При использовании этого я получаю сообщение об ошибке в заголовке, может ли кто-нибудь помочь мне с этим?

Спасибо


person user723858    schedule 15.05.2012    source источник
comment
Мне все это кажется хорошим ... вы пробовали пройти через это, чтобы точно определить, где именно возникает ошибка? Это в ваших действиях GET или POST? Это в поле зрения?   -  person Ethan Brown    schedule 16.05.2012


Ответы (1)


В действии контроллера POST вы, кажется, создаете экземпляр некоторой переменной модели, с которой ничего не делаете. Вы по-прежнему return View(message_to_send); и, конечно же, этой message_to_send переменной не назначено свойство MessagesList. Также почему вы повторяете все аргументы действия, если они уже присутствуют в вашей модели представления?

Вот как я бы посоветовал вам улучшить свой код (я поместил некоторые предупреждения в виде комментариев в код):

[HttpPost]
public ActionResult Message_Send_Get(MessageModel message_to_send)
{
    if (ModelState.IsValid)
    {
        WebRequest wrGETURL;

        //This is a string that points to the location of the Web Service 
        string web_service_location = "http://www.google.com?";

        //This initates a new writeable instance of HttpValueCollection
        NameValueCollection query_string = System.Web.HttpUtility.ParseQueryString(string.Empty);
        //This builds up the query string that will be used for the redirect
        query_string["code"] = message_to_send.code;
        query_string["password"] = message_to_send.password;
        query_string["from"] = message_to_send.sms_from;

        // Warning: you seem to have used some Message_List argument in your action
        // but there's no corresponding input field in the view or in the model
        // maybe you want to add some
        // query_string["msg"] = message_to_send.sms_from.msg;

        //This concatinates the web_service_location (String) and query_string (String)
        send_url = web_service_location + query_string.ToString();

        Debug.WriteLine(send_url);

        // Warning: Here you only created the request but never sent it
        // I guess you will have to complete the code .....
        wrGETURL = WebRequest.Create(send_url);
    }

    // since we want to redisplay the same view we need to reassign the
    // MessagesList property used by the dropdown because in HTML a dropdown
    // sends only the selected value when the form is submitted and not the entire
    // list of options
    message_to_send.MessagesList = smse.Messages
       .Select(c => new SelectListItem
       {
           Value = c.message1,
           Text = c.message1
       });
    return View(message_to_send);
}

Небольшое замечание: на ваш взгляд, вы, кажется, используете какое-то свойство from вашей модели: <%: Html.TextBoxFor(model => model.from) %>, но такое свойство не существует в показанной вами модели. Может ты имел ввиду sms_from.

person Darin Dimitrov    schedule 16.05.2012
comment
Привет, спасибо за помощь с кодом :-) Я понимаю, что там был какой-то нежелательный код, и это было из-за того, что я пытался так много способов обойти эту проблему, лол! Ваш код помог мне на этом пути, за исключением того, что я все еще получаю эту ошибку. Элемент ViewData с ключевым словом message имеет тип System.String, но должен иметь тип IEnumerable ‹SelectListItem›. Похоже, это происходит в строке ‹% = Html.DropDownListFor (model =› model.message, Model.MessagesList)% ›моего представления, и я думаю, что это связано с моей моделью представления. Любые идеи? - person user723858; 16.05.2012
comment
Вы видели, что я возвращаю return View(message_to_send);? Вы также заметили, что я установил свойство message_to_send.MessagesList непосредственно перед возвращением? Вы сделали то же самое? В вашем коде вы, кажется, создали экземпляр какой-то model переменной, которая никогда не использовалась. Я протестировал код, и он работал нормально. Попробуйте удалить весь мусор (на данный момент все, что находится внутри условия ModelState.IsValid), чтобы убедиться, что код работает. - person Darin Dimitrov; 16.05.2012