ASP.Net MVC partial views keeping their model state?

前端 未结 5 1448
小蘑菇
小蘑菇 2021-02-08 19:43

This is probably again a newbie question.

When I create an ASP.NET MVC2 application, an Account Controller with an Action LogIn is created like this:

[H         


        
5条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-08 20:04

    This is certainly not a newbie question and I have combed up and down the web for an answer to this problem and so far the best solution I've found was kind of hidden in this tutorial here. This is what Darin Dimitrov was suggesting with the Ajax refresh. I'll summarize the important parts of that link and why this isn't easily fixed : /

    Ajax refresh based on weird lover

    The solution with the ajax refresh pretty much hinges on the following function (weird lover uses ControllerContext but it didn't exist for me so I have ControllerExtension):

    ControllerExtension.RenderPartialViewToString(this,"mypartial", (object)model)
    

    This function is what takes your model + modelstate and rerenders your partial view into an html string. You can then take that string and send it back in a json object to some javascript to refresh the view. I used jquery and it looks like this,

    $(document).ready(function () {
        var partialViewUpdate = function (e) {
                e.preventDefault(); //no postback
                var partialDiv = $(this).parent(".partial");
                $.post($(this).attr("action"),
                       $(this).serialize(),
                       function (json) {
                       if (json.StatusCode != 0) {
                           // invalid model, return partial 
                           partialDiv.replaceWith(json.Content);
                       }
                       else if (json.Content != null && json.Content != "") {
                           window.location.replace(data.Content);
                       };
               });
    
        $(".partial").find("form")
                     .unbind('submit')
                     .live("submit", partialViewUpdate);
    };
    

    Jquery explanation:

    1. Look up the div that contains my partial (class="partial") and find the form within that div
    2. Unbind any other "submit" events with that form (I got some strange double submit bug until I did that unbind).
    3. use "live" so that once the content is replaced it rebinds again
    4. Once we enter the function partialViewUpdate...
    5. Prevent the form from finishing the submit so that it can all be handled by ajax.
    6. fetch the div that contains my partial (will use this later)
    7. Setup the jquery post url by taking it from the form, $(this).attr("action")
    8. Take the form (i.e. our model) and serialize it for the controller function, $(this).serialize()
    9. Create the function that will handle the ajax return value.
    10. I use my own personal json object, where a StatusCode 1 is bad. So if it's bad then I take what's in Content, this is the string that RenderPartialViewToString gave me, and I just replace the contents of the div that contains my partial.

    Why it doesn't "just work" normally

    So the reason the partials' don't just work with modelstate validation is that you can't return View(model) with the POST because MVC will resolve that to the route address of the partial view (login.ascx) instead of where the partial is embedded (index.aspx).

    You also can't use RedirectAction() because that will send it to (index.aspx) controller function, which is the equivalent of clearing everything and refreshing the index.aspx page. However if you use that ActionFilter suggested by Chino and Thabaza then when your page is refreshed and the login.ascx controller function is fired off again it will pick up that tempdata. This however doesn't work if refreshing the page causes a hassle with client-side code such as popup modals (i.e. if you refresh your popup is gone).

    Say it aint so

    I would prefer if it "just worked" so if anyone knows the correct/better way of doing this pleaaaase share it! I still feel that the Ajax refresh and ActionFilter solutions are not a clean way of doing it because it almost makes it look like partial views with forms are impossible to use without some sort of "trick".

提交回复
热议问题