views:

34

answers:

2

Hello I am using ASP.NET partial views like in this example

<% using (Html.BeginForm()) { %>
    <table cellspacing="2" cellpadding="0" border="0" width="100%">
    <tr>
        <td><%= Html.LabelFor(model => model.PersonName)%></td>
        <td>
            <%= Html.TextBoxFor(model => model.PersonName)%>
            <%= Html.ValidationMessageFor(model => model.PersonName, "*")%>
        </td>
    </tr>
    ...
    <tr><td colspan="2"><%= Html.ValidationSummary(false) %></td></tr>
    </table>
<% } %>

I show these partial views in Jquery dialogs calling them using jquery code

$.ajax({
    type: "get",
    dataType: "html",
    url: urlAction,
    data: {},
    success: function(response) {
        $("#panelDetail").html('').html(response).dialog('open');
    }
});

and everything works and make me happy. I am also able to submit the form using jquery ajax and this make me even more happy. :)

What is really annoying is that I did not understand where validation occurs because, when it happens, it does a full refresh of the page and close the dialog.

I am sure that somebody can help on this. Anyway....who will be? :)

Thanks in advance!

EDIT:

This is the controller action signature with some code in it

[HttpPost]
public ActionResult MyAction(FormCollection form) {
    string foroID = form["ForoId"];
    string foro = form["Foro"];
    string authorityId = form["AuthorityId"];
    string sezione = form["Sezione"];
    ...
}

Do I have to re-create the model class to validate it?

+2  A: 

First of all: if you're using client validation, than the first check is already on the client side using javascript, but your validation would show errors while typing in data.

Second of all: your data being sent back to controller action is being validated at that particular point as long as your action takes a parameter of the same type as your PartialView has as model type. If this type (class) has data annotations attached to properties, those are being validated. Of course you should as well check for model errors in your action and act accordingly.

A redirect? If you'd provide some more code of your controller action we could more easily check what's going on and provide some additional help.

How did I handle this situation

I created a special action filter that checks for model state errors and returns 400 to the client with error description. All my Ajax calls handle success as well as error replies and act accordingly.

Check the code here (question and solution).

The actual solution

This solution is based on additional information gotten from comments below

So after a discussion the problem isn't actually the full page postback, but the validation that didn't happen at all. The reason being that controller action takes a parameter of type FormCollection. MVC framework has no knowledge whatsoever to know how to validate that data, so no validation happens.

The change you have to do is to change the type of this parameter, to match your strong type view. If your view is of type ViewPage then your HttpPost action should most probably have a parameter of the same type.

In general action type can have parameters of any type. Yes it can have even more parameters. The only restriction being that default model binder will be able to relate posted data to these parameters. This is where you come in. All you have to do is to name your parameters properly and model binder will do the rest.

If you come across a certain situation where this can't be done easily, you can always write a custom model binder for a particular type, and it will be completely on you how to parse posted data.

Robert Koritnik
First of all thanks for your answer. It is interesting and very clean your solution but I think that does not apply to my code. The reason is that, when I make the first ajax call, it returns the html of the view. When I submit the form I just send the form serialized so my controller action receives in input a FormCollection param and not a Model instance.
Lorenzo
Maybe I am saying stupid things but consider that I am just learning MVC from two weeks. :) I am editing the answer to include sample Action code.
Lorenzo
@Lorenzo: That's because you've changed your HTML. When you first displayed your page you've almost probably run the `$(function(){})` that changed the behaviour of your form submition to Ajax. So when you then redisplayed the returned partial view, your previous HTML (including attached DOM events) have been removed with a new HTML (that just happens to be something quite similar). You should rerun the code that changed your FORM submission behaviour to Ajax. *(or maybe I completely misunderstood your question as well as your comments)*
Robert Koritnik
@Robert: No Robert. I have not changed anything. The first ajax call in the question, the one with GET parameter, is the call invoked from an hyperlink that returns the Partial. The action simply create a new instance of teh model class and then return "PartialView("ForoControl", fm);". ForoControl is the partial that I have included briefly at the top of the question.
Lorenzo
@Lorenzo: If you submit your form as Ajax or as a full postback and you want your data to be validated, your action should take parameter of a particular type with data annotations in order for the data to be validated. `FormCollection` can't be validated automatically. You should change that or validate data manually within your action (which I would strongly oppose you to do).
Robert Koritnik
So you are saying that if I simply change the signature of the Action to receive a ForoModel object there's some piece of code that automagically change the data for me? Really?
Lorenzo
Yes!!! So it is... Wow!!! Great framework ASP.NET MVC!!!
Lorenzo
Great! Now I better understand your answer. Thanks very much Robert
Lorenzo
@Lorenzo: So it worked, didn't it? I guess Asp.net MVC has a new fan. :)In time you'll start loving it even more. The same as we did when we started developing applications with it.
Robert Koritnik
A: 

with Robert's suggestion in here

before you close your dialog box, you try to check what is the server response when you submit the form via ajax before you close the dialog, try to check if the response is valid or invalid model state before you call dialog('close') of the dialog. Same thing in all other situation of dialogs.

rob waminal