我有一个[HttpPost]
像这样的动作方法签名:
[HttpPost]
public ActionResult Edit(ExistingPostViewModel model)
{
// Save the edited Post.
}
Run Code Online (Sandbox Code Playgroud)
现在,在过去(当我没有使用ViewModels,例如R&D)时,我有一个像这样的Edit方法的实现:
[HttpPost]
public ActionResult Edit(Post model)
{
var existingPost = repo.Find(model.Id);
TryUpdateModel(existingPost);
repo.Save(existingPost);
return RedirectToAction("Success", existingPost.Id);
}
Run Code Online (Sandbox Code Playgroud)
哪个很好用.
但我很困惑如何使上述内容适应ViewModel方法.
如果我这样做:
TryUpdateModel(existingPost)
Run Code Online (Sandbox Code Playgroud)
使用我的ViewModel方法,没有太多发生.没有错误,但没有任何更新,因为MVC将不知道如何更新Post
a ExistingPostViewModel
(在它之前Post
- > Post
).
现在,我正在使用AutoMapper.所以我想我可以从ViewModel映射到Post
,然后保存帖子.
但后来我基本上压倒一切.我不想这样做,并且打败了ViewModel.
有人可以让我迷惑吗?
这似乎是一种非常常见的情况,我对人们如何解决这个问题感到非常难过.我只能看到3种可能的解决方案:
不要在HTTP POST中使用ViewModel.正如我说我这样做,在过去的R&d和它的作品,但现在我看到我的视图的演变(验证,简单),我不能妥协,只是这个问题的缘故.
不要使用TryUpdateModel.可能,但那么我将如何合并这些变化呢?
从左到右使用.啊.但目前这似乎是我倾向的方式.
有人请给我解决方案#4!:)
顺便说一下,我正在使用ASP.NET MVC 3,Razor和Entity Framework.
asp.net-mvc model-binding updatemodel viewmodel asp.net-mvc-3
我发现了很多关于为验证目的实现自定义模型绑定器的信息,但我还没有看到我正在尝试做什么.
我希望能够根据视图模型中属性的属性来操作模型绑定器要设置的值.例如:
public class FooViewModel : ViewModel
{
[AddBar]
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
AddBar就是
public class AddBarAttribute : System.Attribute
{
}
Run Code Online (Sandbox Code Playgroud)
我无法在自定义模型绑定器的BindModel方法中找到一种在查看模型属性上查找属性的简洁方法.这有效,但感觉应该有一个更简单的解决方案:
public class FooBarModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = base.BindModel(controllerContext, bindingContext);
var hasBarAttribute = false;
if(bindingContext.ModelMetadata.ContainerType != null)
{
var property = bindingContext.ModelMetadata.ContainerType.GetProperties()
.Where(x => x.Name == bindingContext.ModelMetadata.PropertyName).FirstOrDefault();
hasBarAttribute = property != null && property.GetCustomAttributes(true).Where(x => x.GetType() == typeof(AddBarAttribute)).Count() > 0;
}
if(value.GetType() == typeof(String) && …
Run Code Online (Sandbox Code Playgroud) 我正在创建一个锁定清单,每个锁具有一个序列号(标题),一个关联的学校(SchoolCode)和5个相关的组合(具有Number,Combination和IsActive).我们正在使用Ncommon和linq并将它们设置为嵌套实体(Lock Has Many Combinations).
在表单上,我使用JQuery模板动态构建表单.其中SchoolCode和Title是基本表单元素,Combinations [index] .Number和Combinations [index] .Combination是子元素.
<form method="post" action="/Lockers.aspx/Locks/Add">
<input type="hidden" name="SchoolCode" value="102">
Lock S/N: <input type="text" name="Title" value=""><br>
<div id="combinations">
<input type="hidden" name="Combinations[0].Number" value="1">
<input type="text" name="Combinations[0].Combination" value="">
<input type="radio" value="1" name="ActiveCombination"><br>
<input type="hidden" name="Combinations[1].Number" value="2">
<input type="text" name="Combinations[1].Combination" value="">
<input type="radio" value="2" name="ActiveCombination"><br>
<input type="hidden" name="Combinations[2].Number" value="3">
<input type="text" name="Combinations[2].Combination" value="">
<input type="radio" value="3" name="ActiveCombination"><br>
<input type="hidden" name="Combinations[3].Number" value="4">
<input type="text" name="Combinations[3].Combination" value="">
<input type="radio" value="4" name="ActiveCombination"><br>
<input type="hidden" name="Combinations[4].Number" value="5">
<input type="text" name="Combinations[4].Combination" value=""> …
Run Code Online (Sandbox Code Playgroud) 我做了一个小项目来理解Stephen Muecke的答案:将多次调用的同一部分视图提交给控制器?
几乎一切都有效.javascript在Partial View中添加了新的字段,我可以通过控制器方法为局部视图插入的"temp"值来告诉他们它们与模型绑定.
但是,当我提交新字段时,AddRecord()方法抛出一个异常,表明模型没有被传入("对象引用未设置为对象的实例").
此外,当我查看页面源时,BeginCollectionItem帮助器正在主视图中的表周围插入一个隐藏标记,该标记显示预先存在的记录,但不包括javascript添加的新字段.
我究竟做错了什么?我很擅长这一点,谢谢你的耐心等待!
我的主要观点:
@model IEnumerable<DynamicForm.Models.CashRecipient>
@using (Html.BeginForm("AddDetail", "CashRecipients", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div id="CSQGroup">
</div>
}
<div>
<input type="button" value="Add Field" id="addField" onclick="addFieldss()" />
</div>
<script>
function addFieldss()
{
//alert("ajax call");
$.ajax({
url: '@Url.Content("~/CashRecipients/RecipientForm")',
type: 'GET',
success:function(result) {
//alert("Success");
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hi there and greetings!");
newDiv.appendChild(newContent);
newDiv.innerHTML = result;
var currentDiv = document.getElementById("div1");
document.getElementById("CSQGroup").appendChild(newDiv);
},
error: function(result) {
alert("Failure");
}
});
}
</script>
Run Code Online (Sandbox Code Playgroud)
我的部分观点:
@model DynamicForm.Models.CashRecipient
@using HtmlHelpers.BeginCollectionItem
@using (Html.BeginCollectionItem("recipients")) …
Run Code Online (Sandbox Code Playgroud) javascript asp.net-mvc model-binding asp.net-mvc-partialview begincollectionitem
在MVC3中,如果模型具有嵌套对象,是否可以自动将javascript对象绑定到模型?我的模型看起来像这样:
public class Tweet
{
public Tweet()
{
Coordinates = new Geo();
}
public string Id { get; set; }
public string User { get; set; }
public DateTime Created { get; set; }
public string Text { get; set; }
public Geo Coordinates { get; set; }
}
public class Geo {
public Geo(){}
public Geo(double? lat, double? lng)
{
this.Latitude = lat;
this.Longitude = lng;
}
public double? Latitude { get; set; }
public double? Longitude { get; …
Run Code Online (Sandbox Code Playgroud) 我在global.asax中为MyList注册了一个自定义模型绑定器.但是,模型绑定器不会触发嵌套属性,对于简单类型,它可以正常工作.在下面的示例中,它会触发Index()但不会触发Index2()
Global.asax中
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(MyList), new MyListBinder());
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Run Code Online (Sandbox Code Playgroud)
码:
public class MyListBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new MyList();
}
}
public class MyList
{
public List<int> items { get; set; }
}
public class MyListWrapper
{
public MyList listItems { get; set; }
}
public class TestController : Controller
{
public ActionResult Index(MyList list) // ModelBinder fires :-)
{
return View();
}
public ActionResult Index2(MyListWrapper wrapper) // …
Run Code Online (Sandbox Code Playgroud) 我遇到了json绑定到视图模型的问题.这是我的代码:
我的ViewModel的一部分(AddressViewModel有更多属性):
public class AddressViewModel
{
[Display(Name = "Address_Town", ResourceType = typeof(Resources.PartyDetails))]
public string Town { get; set; }
[Display(Name = "Address_Country", ResourceType = typeof(Resources.PartyDetails))]
public Country Country { get; set; }
}
public class Country : EntityBase<string>
{
public string Name { get; set; }
protected override void Validate()
{
if (string.IsNullOrEmpty(Name))
{
base.AddBrokenRule(new BusinessRule("CountryName", "Required"));
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用Javascript:
$(document).on("click", "#addAddress", function () {
var jsonData = {
"Town": $('#txt-Town').val(),
"District": $('#txt-District').val(),
"Street": $('#txt-Street').val(),
"PostCode": $('#txt-PostCode').val(),
"FlatNumber": $('#txt-FlatNumber').val(), …
Run Code Online (Sandbox Code Playgroud) 我正在使用Web API模型绑定来解析URL中的查询参数.例如,这是一个模型类:
public class QueryParameters
{
[Required]
public string Cap { get; set; }
[Required]
public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我打电话时,这很好用/api/values/5?cap=somecap&id=1
.
有什么方法可以更改模型类中属性的名称,但保持查询参数名称相同 - 例如:
public class QueryParameters
{
[Required]
public string Capability { get; set; }
[Required]
public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我认为添加[Display(Name="cap")]
到该Capability
属性将起作用,但事实并非如此.我应该使用某种类型的数据注释吗?
控制器将有一个如下所示的方法:
public IHttpActionResult GetValue([FromUri]QueryParameters param)
{
// Do Something with param.Cap and param.id
}
Run Code Online (Sandbox Code Playgroud) 我从第三方静态页面(由Adobe Muse生成)捕获发布请求并使用MVC操作处理它.
<form method="post" enctype="multipart/form-data">
<input type="text" name="Name">
...
</form>
Run Code Online (Sandbox Code Playgroud)
路由空表单操作:
app.UseMvc(routes => routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}"));
Run Code Online (Sandbox Code Playgroud)
但是根据行动我有模型,每个属性都是空的
行动:
[HttpPost]
public void Index(EmailModel email)
{
Debug.WriteLine("Sending email");
}
Run Code Online (Sandbox Code Playgroud)
模型:
public class EmailModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public string Phone { get; set; }
public string Additional { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Request.Form
从表单中获取所有值,但模型为空
[0] {[Name, Example]}
[1] {[Email, Example@example.com]}
[2] {[Company, …
Run Code Online (Sandbox Code Playgroud) 我只是没有运气将 url 编码的表单值从邮递员发送到使用文件-> 新项目创建的 vanilla asp.net core 2.1 web api。我什么也没做,但新的模型验证功能似乎仍然启动并向邮递员返回 400 Bad Request。谁能告诉我我做错了什么?
控制器动作:
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
Run Code Online (Sandbox Code Playgroud)
原始请求(如 fiddler 所示):
POST http://localhost:60843/api/values HTTP/1.1
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: a791eee7-63ff-4106-926f-2s67a8dcf37f
User-Agent: PostmanRuntime/7.3.0
Accept: */*
Host: localhost:60843
accept-encoding: gzip, deflate
content-length: 7
Connection: keep-alive
value=test
Run Code Online (Sandbox Code Playgroud)
原始回复:
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Kestrel
X-SourceFiles: =?UTF-8?BQzpcUmVwb3NcVGVzdGJlZFxNb2RlbEJpbmRpbmdcTW9kZWxCaW5kaW5nXGFwaVx2YWx1ZXM=?=
X-Powered-By: ASP.NET
Date: Thu, 25 Oct 2018 15:23:49 GMT
21
{"":["The input was not valid."]} …
Run Code Online (Sandbox Code Playgroud) model-binding ×10
asp.net-mvc ×4
c# ×4
asp.net ×3
asp.net-core ×2
json ×2
forms ×1
javascript ×1
updatemodel ×1
viewmodel ×1