Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为后端C#MVC中的发布对象添加值_C#_Asp.net Mvc_Asp.net Mvc 4 - Fatal编程技术网

为后端C#MVC中的发布对象添加值

为后端C#MVC中的发布对象添加值,c#,asp.net-mvc,asp.net-mvc-4,C#,Asp.net Mvc,Asp.net Mvc 4,我有这样一个问题,是否可以在MVC中为发布的对象添加值 public ActionResult Create([Bind(Include = "ID = 1", LastName, FirstMidName, EnrollmentDate")] Student student) { try { if (ModelState.IsValid) { db.Students.Add(student); db.Sav

我有这样一个问题,是否可以在MVC中为发布的对象添加值

public ActionResult Create([Bind(Include = "ID = 1", LastName, FirstMidName, EnrollmentDate")] Student student)
{
    try {
        if (ModelState.IsValid)
        {
            db.Students.Add(student);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
}
比如ID=1,这当然不起作用。在开始表单验证过程之前,我想添加关于模型的附加信息。 我有类似于
TryValidateModel(我的更新模型)
的选项,但在这种情况下,我将验证我的对象两次,或者其他选项是在前端添加隐藏类型。我之所以要这样做,是因为我的模型有CRUD操作,并且每种CRUD类型的验证都是不同的。例如,在更新期间,它不会检查数据库中是否存在该值等


我提出了使用HTTP方法名(如HTTPPUT-HTTPDELETE)的解决方案,对于验证,它将是类似REST的解决方案。感谢大家的帮助。

修改ASP.net MVC操作输入的最佳位置是ModelBinder,创建自定义通用ModelBinder并从默认MVC继承
DefaultModelBinder
,并在
BindModel
方法覆盖中添加所需信息

下面是一个可以扩展以实现您所需的示例:

公共类CustomModelBinderBinder:DefaultModelBinder
{
专用只读词典_extraProperties;
公共CustomModelBinderBinder(字典外部属性)
{
_extraProperties=extraProperties;
}
公共重写对象BindModel(ControllerContext ControllerContext,ModelBindingContext bindingContext)
{
var model=bindingContext.model;
var modelType=model.GetType();
var modelProperties=modelType.GetProperties(BindingFlags.Public);
foreach(在_extraProperties中的var属性)
{
var matchingProperty=modelType.GetProperties().FirstOrDefault(p=>p.Name==property.Key);
if(matchingProperty!=null)
{
尝试
{           
matchingProperty.SetValue(model,property.Value);
}
捕获(例外情况除外)
{
//如果无法设置此值,会发生什么情况?
//可能是由于类型不匹配或只读属性
投掷;
}
}
}
}
}

在该示例中,要扩展的属性列表位于构造函数动态参数中,然后对
模型
对象使用它来覆盖或扩展其属性。

在搜索Internet上的答案、阅读文章和书籍后,我想出了一些解决问题的方法。
1.将隐藏类型添加到我的HTML并通过Post方法发送。ViewModel验证程序使用隐藏类型的值,并根据需要进行验证。但是我不喜欢隐藏类型的想法。
2.第二种解决方案是使用自定义模型绑定器,它可以是高级解决方案
3.为路由添加附加值,此解决方案是最佳解决方案,操作名称可帮助我的模型了解要验证的内容。
4.还有另一种添加Modelstate修改、删除属性的解决方案,

但是我将使用第三个选项,另外我考虑使用REST逻辑,并根据HTTP方法进行验证

您不能在方法的第一行设置值吗?或者在模型的构造函数中?该值类似于CRUD标识符,例如IsDelete属性,只有在调用Delete操作时才为真,我使用ViewModel,我不想使用多个模型来完成这项工作。您可以使用路由值添加附加值,但不清楚您试图做什么,或者附加值的目的是什么。我不想使用路由值,因为路由值可以从前端更改。在验证中使用操作名称是正常的,还是我可以向我的操作添加一些参数,我可以从模型验证中访问这些参数?昨天我在玩modelstate,它为我的问题添加了另一个解决方案,但我还是想要一些特别的东西:)好的,我会尝试这个选项。没有Cutom Model活页夹,不会有帮助。我需要viewmodel知道它正在验证哪个操作。像Delete、Read、Put这样的字段必须发送到我的验证代码。我认为现在使用数据注释来传递具有值的字段。
public class CustomModelBinderBinder : DefaultModelBinder
{
    private readonly Dictionary<string, object> _extraProperties;

   public CustomModelBinderBinder(Dictionary<string, object> extraProperties)
   {
        _extraProperties = extraProperties;
   }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = bindingContext.Model;
        var modelType = model.GetType();
        var modelProperties = modelType.GetProperties(BindingFlags.Public);

        foreach (var property in _extraProperties)
        {
           var matchingProperty = modelType.GetProperties().FirstOrDefault(p => p.Name == property.Key);

            if (matchingProperty != null)
            {
                try
                {           
                    matchingProperty.SetValue(model, property.Value);
                }
                catch (Exception ex)
                {
                    // what happens when we fail to set this value?
                    // possibly due to type mismatch, or readonly property
                    throw;
                }
            }
        }
    }
}