Domanda

Sto utilizzando un modulo AJAX per aggiornare una voce al database. Quando viene fatto, restituisce una vista parziale che ri-elenca tutti gli elementi e li visualizza in una tabella. Il problema si verifica quando devo aggiungere un errore di ModelState nella mia azione del controller. Non voglio tornare l'elenco delle voci quando c'è un errore di ModelState perché voglio mostrare all'utente l'errore utilizzando il ValidationMessage. Il mio pensiero è che avrei potuto fare qualcosa di simile in mio controller:

       [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UpdateNewsItem(int newsID, string newsTitle, string newsDescription, string newsBeginningDate, string newsEndingDate)
    {
        List<Models.News> lstNewsItem = new List<News>();

        //we need to grab the member so we can capture the user id 
        //for the corresponding news property
        MembershipUser member = Membership.GetUser(User.Identity.Name);

        //the news instance to use in case the viewdata is invalid
        Models.News newsError = new Models.News();

        //create the datetime objects
        DateTime dtBeginningDate = DateTime.MinValue;
        DateTime dtEndingDate = DateTime.MaxValue;

        //the message we want to send whenever the user enters an invalid date
        string strInvalidDateError = "Invalid date.  Please use a format like '12/25/2008'";

        //clean user input
        newsTitle = Models.clsGlobals.CleanString(newsTitle);
        newsDescription = Models.clsGlobals.CleanParagraph(newsDescription);

        //newsTitle 
        if (string.IsNullOrEmpty(newsTitle))
        {
            newsError.Title = string.Empty;
            ModelState.AddModelError("newsTitle", "You must enter a news title.");
        }

        //description
        if (string.IsNullOrEmpty(newsDescription))
        {
            newsError.Description = string.Empty;
            ModelState.AddModelError("newsDescription", "You must enter a news description.");
        }

        //beginningDate
        if (string.IsNullOrEmpty(newsBeginningDate))
        {
            ModelState.AddModelError("newsBeginningDate", "You must enter a beginning date.");
        }

        //endingDate
        if (string.IsNullOrEmpty(newsEndingDate))
        {
            ModelState.AddModelError("newsEndingDate", "You must enter an ending date.");
        }

        //set the beginning date 
        try
        {
            dtBeginningDate = DateTime.Parse(newsBeginningDate);
            newsError.BeginningDate = dtBeginningDate;
        }

        catch (FormatException)
        {
            ModelState.AddModelError("newsBeginningDate", strInvalidDateError);
        }

        //set the ending date
        try
        {
            dtEndingDate = DateTime.Parse(newsEndingDate);
            newsError.EndingDate = dtEndingDate;
        }

        catch (FormatException)
        {
            ModelState.AddModelError("newsEndingDate", strInvalidDateError);
        }

        //data is validated, so we can begin the update
        if (ModelState.IsValid == true)
        {

            try
            {
                //use to perform actions on db
                Models.NewsDataContext dcNews = new Models.NewsDataContext();

                //fetch the items that match what the user requested to edit
                lstNewsItem = this.GetNewsItem(newsID);

                //set news properties
                foreach (Models.News news in lstNewsItem)
                {

                    news.UserId = (Guid)member.ProviderUserKey;
                    news.Title = newsTitle;
                    news.Description = newsDescription;
                    news.EntryDate = DateTime.Now;
                    news.BeginningDate = dtBeginningDate;
                    news.EndingDate = dtEndingDate;

                }//next

                //update the transaction
                dcNews.SubmitChanges();

                //update the news list
                return PartialView("NewsList", this.GetNewsItems());

            }

            //just to make sure everything goes as planned,
            // catch any unhandled exceptions
            catch (Exception ex)
            {
                ModelState.AddModelError("_FORM", ex);
            }//end catch

        }//end if valid modelstate


        //invalid modelstate, so repopulate the viewdata and
        //send it back

        //the list to hold the entries
        List<Models.News> lstErrorNewsItems = new List<Models.News>();

        //set the remaining error properties
        newsError.UserId = (Guid)member.ProviderUserKey;
        newsError.NewsID = newsID;
        newsError.EntryDate = DateTime.Now;

        //add the item--there will only be one
        //but the view is expecting a list so we will
        //treat it like one
        lstErrorNewsItems.Add(newsError);

        return PartialView("EditNews", lstErrorNewsItems);

    }//end actionresult

Il problema è che quando si verifica un errore ModelState, il viewdata ModelState non viene restituito. Ho il sospetto che è forse perché non sto specificando un id bersaglio aggiornamento. Ma non riesco a impostare un altro updatetargetid perché ho già uno. Tutte le idee?

È stato utile?

Soluzione 2

Va bene, ho capito. Grazie per la risposta. Per riferimento futuro, quello che ho dovuto fare è stato istituito un divisore di master che tutti i miei contenuti va in. Poi, ho sempre impostato l'updateTargetID a quel divisorio in modo che non importa quale contenuto viene visualizzato, solo che lo visualizza. Questo in realtà si rivela essere più facile perché non c'è bisogno di sprecare funzioni Impostazioni JavaScript altri tag div on e off, perché si sta utilizzando solo uno che è in continuo aggiornamento.

Altri suggerimenti

 if (!Model.IsValid)  {
    return PartialView("YourEditForm");
    }
    else 
    {
    return View("YourIndexView");
    }

dovrebbe funzionare bene per la mostra di nuovo il modulo di modifica con errori di convalida e tutti. Viewdata viene popolata da dati successivi.

grande aggiornamento

Ho fatto alcuni test per capirlo. E si avvicinò con un progetto di test di funzionamento. ecco alcuni annunci:

Il mio controller di test

 public class TestController : Controller
    {
                 //
        // GET: /Test/
        List<TestData> data;
        public TestController()
        {
            data = new List<TestData>();
            for (var i = 0; i < 10; i++)
            {
                data.Add(new TestData(){Name=string.Format("TestData{0}",i.ToString().PadLeft(4,'0'))});
            }
        }

        public ActionResult Index()
        {


            return View( data);
        }

        public ActionResult Edit(string name)
        {
            if (Request.IsAjaxRequest())
            {
                return PartialView("AjaxEdit", new TestData() { Name = name });
            }

            return View(new TestData() { Name = name });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(TestData testData)
        {
            ModelState.AddModelError("name", "incorrect name");
            if (!ModelState.IsValid)
            {
                if (Request.IsAjaxRequest())
                {
                    return PartialView("AjaxEdit");
                }


            }

            return View();
        }
    }

La mia Modifica Visualizza:

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

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

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

    <h2>Edit</h2>
    <div id="editForm">
<% Html.RenderPartial("AjaxEdit",Model );%>
</div>
</asp:Content>

Il mio Ajax parziale Modifica Visualizza

"%>

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

<% using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "editForm" }))
   {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Name">Name:</label>
            <%= Html.TextBox("Name")%>
            <%= Html.ValidationMessage("Name", "*")%>
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

<% } %>

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

E il mio TestData classe del modello

  public class TestData
    {
        public string Name { get; set; }
    }

con questo codice funziona proprio come si voleva. avviso che non supero qualsiasi modello di vista parziale nella mia azione "Post" Modifica. Guarda che viene reso ottiene tutti i valori di cui ha bisogno da una richiesta POST.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top