Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
608 views
in Technique[技术] by (71.8m points)

asp.net mvc - How to modify posted form data within controller action before sending to view?

I want to render the same view after a successful action (rather than use RedirectToAction), but I need to modify the model data that is rendered to that view. The following is a contrived example that demonstrates two methods that that do not work:

    [AcceptVerbs("POST")]
    public ActionResult EditProduct(int id, [Bind(Include="UnitPrice, ProductName")]Product product) {
        NORTHWNDEntities entities = new NORTHWNDEntities();

        if (ModelState.IsValid) {
            var dbProduct = entities.ProductSet.First(p => p.ProductID == id);
            dbProduct.ProductName = product.ProductName;
            dbProduct.UnitPrice = product.UnitPrice;
            entities.SaveChanges();
        }

        /* Neither of these work */
        product.ProductName = "This has no effect";
        ViewData["ProductName"] = "This has no effect either";

        return View(product);
    }

Does anyone know what the correct method is for accomplishing this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After researching this further, I have an explanation why the following code has no effect in the Action:

product.ProductName = "This has no effect";
ViewData["ProductName"] = "This has no effect either";

My View uses HTML Helpers:

<% Html.EditorFor(x => x.ProductName);

HTML Helpers uses the following order precedence when attempting lookup of the key:

  1. ViewData.ModelState dictionary entry
  2. Model property (if a strongly typed view. This property is a shortcut to View.ViewData.Model)
  3. ViewData dictionary entry

For HTTP Post Actions, ModelState is always populated, so modifying the Model (product.ProductName) or ViewData directly (ViewData["ProductName"]) has no effect.

If you do need to modify ModelState directly, the syntax to do so is:

ModelState.SetModelValue("ProductName", new ValueProviderResult("Your new value", "", CultureInfo.InvariantCulture));

Or, to clear the ModelState value:

ModelState.SetModelValue("ProductName", null);

You can create an extension method to simplify the syntax:

public static class ModelStateDictionaryExtensions {
    public static void SetModelValue(this ModelStateDictionary modelState, string key, object rawValue) {
        modelState.SetModelValue(key, new ValueProviderResult(rawValue, String.Empty, CultureInfo.InvariantCulture));
    }
}

Then you can simply write:

ModelState.SetModelValue("ProductName", "Your new value");

For more details, see Consumption of Data in MVC2 Views.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...