Как изменить значения формы после публикации в ASP.NET MVC?

Я хочу изменить значение формы, прежде чем передать его действию контроллера. но выдает Collection is read-only.

public class PersonController : Controller
{
    public ActionResult Add()
    {
        return View();
    }

    [HttpPost]
    [PersianDateConvertor("birthday")]
    public ActionResult Add(FormCollection collection)
    {
        string firstName = collection["firstName"];
        string lastName = collection["lastName"];
        string birthday = collection["birthday"];

        return View();
    }
}
public class PersianDateConvertorAttribute : ActionFilterAttribute
{
    string[] fields;
    public PersianDateConvertorAttribute(params string[] persianDateFieldNames)
    {
        if (persianDateFieldNames == null)
            fields = new string[] { };
        else
            fields = persianDateFieldNames;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        foreach (var field in fields)
        {
            string value = filterContext.HttpContext.Request.Form[field];
            filterContext.HttpContext.Request.Form.Remove(field); //throws Collection is read-only
            filterContext.HttpContext.Request.Form.Add(field, ConvertToGregorian(value));
            // or filterContext.HttpContext.Request.Form[field] = ConvertToGregorian(value);
        }

        base.OnActionExecuting(filterContext);
    }
}

person Jalal    schedule 19.08.2011    source источник
comment
По некоторым причинам я не хочу преобразовывать данные внутри своего действия.   -  person Jalal    schedule 19.08.2011
comment
взгляните на эти вопросы SO: stackoverflow.com/questions/323265/ и stackoverflow.com/questions/5561207/   -  person Baz1nga    schedule 19.08.2011


Ответы (1)


Если я правильно понимаю, вы хотите изменить поведение DateTime во время процесса привязки. Вместо использования атрибута я бы использовал ModelBinder для изменения формата строки даты.

Я сделал что-то подобное для проблемы при преобразовании десятичных значений из нескольких культур: (код взят из сообщения в блоге, это не мое, но я не помню источник. Извините)

using System;
using System.Globalization;
using System.Web.Mvc;

public class DecimalModelBinder : IModelBinder
{
  public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    ModelState modelState = new ModelState { Value = valueResult };
    object actualValue = null;
    try
    {
      actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
    }
    catch (FormatException e)
    {
      modelState.Errors.Add(e);
    }
    bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
    return actualValue;
  }
}

в global.asax вы регистрируете связующее

protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);

  ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

}

Имо, это лучший подход, и вам не нужно указывать атрибут для каждого действия.

person Iridio    schedule 19.08.2011