1

I had an issue similar to that posted in this related question: mvc 4 textbox not updating on postback

Because I wanted to be a bit more targeted than "nuke it all" I am using ModelState.Remove("propertyname") instead to just affect specific values in my model.

However even this is too broad for what I want, because this removes any validation information, etc. that might have been accrued for this property.

How can I update the specific posted back value without losing all this other useful state information?

The below code displays the current behaviour, (with unwanted behaviour in bold):

  • submitting "test" returns a model with "replacement", but a form with "test"
  • submitting "testlong" returns a model with "replacement", but a form with "testlong", and displays a validation message
  • submitting "remove" returns a model with "replacement", and form with "replacement"
  • submitting "removelong" returns a model with "replacement", and form with "replacement" and no validation message

Model:

public class TestViewModel
{
    [StringLength(7, ErrorMessage = "{0} must be less than {1} characters")]
    public string A { get; set; }
}

Action:

public ActionResult Test(TestViewModel model)
{
    if(model.A == "remove" || model.A == "removelong")
    {
        ModelState.Remove("A");
    }
    model.A = "replacement";
    return View(model);
}

View:

@model TestNamespace.TestViewModel
@{ Layout = null; }

<!DOCTYPE html>
<html>
<head></head>
<body>
    <form>
        @Html.ValidationMessageFor(m=>m.A)
        @Html.TextBoxFor(m => m.A)
    </form>
</body>
</html>

Some examples where this would be useful:

  • Telling the user what they got wrong, fixing it for them, and telling them we fixed it.
  • An application that logs validation errors for analysis, and always does so as the last step before the view so as to capture validation errors added during the Action.
  • Manager/Customer mandated logic which is nonsensical, but still required despite advice to that effect.
fweaks
  • 23
  • 7
  • The behavior you want makes no sense. If the user submits an invalid value, then of course it should return that same invalid value and the validation error associated with that value. –  Nov 30 '17 at 22:45
  • @StephenMuecke The behaviour makes little sense in a conventional form, I agree. My use case is substantially different from the MCV I have presented here. – fweaks Nov 30 '17 at 22:56
  • Then show your real case! (your question makes no sense as it stands) –  Nov 30 '17 at 22:57
  • @StephenMuecke The whole point of an MCVE is that it clearly demonstrates the behaviour in question, not that it represents production code. It works, is clear, and so is the question, regardless of how contrived the example is. – fweaks Nov 30 '17 at 23:02
  • Then what do you expect the answer to be - you even agreed that the behavior you want makes no sense. –  Nov 30 '17 at 23:04
  • @StephenMuecke I expect the answer to be how to get the requested behaviour, (or (unlikely) a statement that it is impossible), regardless of how much sense it makes normally. Whether something makes sense does not affect whether it is possible, especially when it only does not make sense in the common case. – fweaks Nov 30 '17 at 23:16
  • Yes its possible, but the purpose of this site is to build a repository of answers to questions that will be useful to others having similar problems (and adding an answer to show how to do something that should not be done, or would not make sense with regard to the question wont help others) –  Nov 30 '17 at 23:20
  • @StephenMuecke Would you consider telling the user what they got wrong, fixing it for them, and telling them we fixed it, to be an example of a sensible use case for this? Or having an application which logs validation errors for analysis purposes, which logs as the last step before the view so as to capture validation messages added during the action? Neither of these is my use case, but both are valid real-world use cases. I will edit these into the question. – fweaks Nov 30 '17 at 23:41
  • Hint. You can read the `Errors` property of `ModelState` and get the errors associated with a specific property before clearing `ModelState`, then you can add use `ModelState.AddModelError()` to add a validation error. –  Nov 30 '17 at 23:47
  • The 2nd example you gave (logging the error) might be a be a _real-world case_, but it would still not make sense to change the value the user sees in the textbox and then display a error message that they entered is an invalid value - the error message would be both confusing and meaningless (see the last part of [this answer](https://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) for a bit more explanation of the default behavior). And how can you possibly know what is the correct fix for what a user entered. –  Nov 30 '17 at 23:53
  • @StephenMuecke That looks like an answer in comments. If you're not already doing so, I'll turn that into an answer for you, once I get it working. It seems a bit cumbersome, but I suppose when you're going against the grain you expect a bit of that. – fweaks Nov 30 '17 at 23:58
  • I am not going to add an answer which starts with _DO NOT DO THIS, but ..._ :) –  Dec 01 '17 at 00:02
  • @StephenMuecke as a side note then, If my use case happened to be the third example I posted in my question, and for something even more ill advised, does that mean I simply cannot seek help from stackoverflow? – fweaks Dec 01 '17 at 00:11
  • I do not know what you mean by your 3rd example, but of course you can seek help, but that does not mean you will get an answer, or the answer you want :) –  Dec 01 '17 at 00:15
  • @StephenMuecke to restate then, people should not seek help from stackoverflow in such a scenario because stackoverflow is disinclined to be helpful to people in that (unfortunately common) scenario? Even despite https://meta.stackoverflow.com/questions/290684/answering-questions-with-no-proper-technical-solution?rq=1 – fweaks Dec 01 '17 at 00:43
  • I was stating my position. I will not give an answer to a question that (1) makes no real sense (i.e. you should not do what I state in my answer), and (2) is not going to be helpful to others. Of course, had you given a real use case that made sense (although I cannot imagine what that would be) then I would have added an answer. –  Dec 01 '17 at 00:49
  • @StephenMuecke the answers in the link in my last comment state explicitly that your position is wrong. – fweaks Dec 01 '17 at 01:14
  • That's an opinion. I am not required to answer your question! And I am certainly not going to add one to a question which is not clear, and is not helpful. –  Dec 01 '17 at 01:20
  • 1
    Here's my use case that drove me to this question: When a user submits an address, I need to change the entered city name to the primary city name (e.g. E St Louis to East Saint Louis), notify the user, and make them resubmit the form. I'm adding the error message and changing the city property during validation and I would like the user to see the data change and the error message. – Jamie Ide Dec 26 '17 at 16:16

1 Answers1

0

There is no clearly provided way to do this, due to the fact that in 99% of cases this is an X-Y problem (e.g. the reason for wanting this is flawed).

However if you really want to do this, you can do it with the following instead of Model.Remove("propertyName"):

ModelState propertyState = ModelState["propertyName"];
if (propertyState != null)
{
    propertyState.Value = null;
}

or in another form

ModelState propertyState;
if (ModelState.TryGetValue("propertyName"))
{
    propertyState.Value = null;
}
fweaks
  • 23
  • 7