Ngu*_*ong 14 c# ajax asp.net-mvc jquery
我正在处理ASP.NET MVC
发送Ajax
到我的控制器的值,但遇到了问题。
假设我有SampleViewModel
这样的:
public class SampleViewModel
{
private string _firstName = string.Empty;
public SampleViewModel()
{
_firstName = string.Empty;
}
public string FirstName
{
get { return _firstName; }
set { _firstName = value ?? string.Empty; }
}
public string LastName { get; set; }
public string FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
控制器
[HttpPost]
public JsonResult ActionSubmit(SampleViewModel model)
{
var result = "";
if(model.FirstName == null)
result += "\nFirstName is null";
if(model.LastName == null)
result += "\nLastName is null";
return Json(result);
}
Run Code Online (Sandbox Code Playgroud)
阿贾克斯
$('.submit').click(function() {
$.ajax({
url: '@Url.RouteUrl(new{ action="ActionSubmit", controller="Home"})',
data: JSON.stringify({ FirstName: '', LastName: '', FullName: 'Phong_Nguyen' }),
// Even though I use { FirstName: '', LastName: '', FullName: 'Phong_Nguyen' } without JSON.stringify
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(resp) {
alert(resp);
}});
});
Run Code Online (Sandbox Code Playgroud)
如您所见,我发送了空值,但在控制器的一端,我得到了空值(响应值始终为“LastName 为空”):
题
为什么当我在 Ajax 中发送时empty
,我null
在我的控制器中获得了价值?
有没有更好的方法和更优雅的方式来解决我的问题,如下所示?
public string FirstName
{
get { return _firstName; }
set { _firstName = value ?? string.Empty; }
}
Run Code Online (Sandbox Code Playgroud)
为什么在 Ajax 中发送空时,我
null
在控制器中获得了值?
string
是一个引用类型,它的默认值为null
。在ModelBinder
如果没有值在请求中提供设置属性的默认值。
有没有更好的方法和更优雅的方式来解决我的问题,如下所示?
您可以使用 注释该属性[DisplayFormat(ConvertEmptyStringToNull = false)]
,以便保留空字符串值。
您可以编写一个ModelBinder
设置ConvertEmptyStringToNull
为的自定义false
,并在全球范围内应用它。
public class NullStringModelBinder : DefaultModelBinder {
public override object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext) {
bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
return base.BindModel(controllerContext, bindingContext);
}
}
//register it in Application_Start()
ModelBinders.Binders.Add(typeof(string), new NullStringModelBinder());
Run Code Online (Sandbox Code Playgroud)
这一特定的更改已记录在此处,它是 的重大更改之一MVC 1.0
。将空字符串绑定到 s 的逻辑由. 使用的属性null
控制。ModelMetadata.ConvertEmptyStringToNull
DefaultModelBinder
现在,如果您不想注释所有属性,您可以创建自定义模型绑定器:
public class EmptyStringModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
Binders = new ModelBinderDictionary() { DefaultBinder = this };
return base.BindModel(controllerContext, bindingContext);
}
}
Run Code Online (Sandbox Code Playgroud)
并将其设置在您的Global.asax
:
ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder();
Run Code Online (Sandbox Code Playgroud)
或者在你的具体行动中:
[HttpPost]
public JsonResult ActionSubmit([ModelBinder(typeof(EmptyStringModelBinder))SampleViewModel model)
Run Code Online (Sandbox Code Playgroud)
为什么要这样做?
这样做是因为 a 的默认值string
是anull
并且所有引用类型的默认值是。因此,框架的这种变化可能是合理的。但另一方面,我们应该尽量避免空值,因此我们需要编写一个自定义模型绑定器来避免这种情况。string
reference type
null
有一个问题为什么字符串类型的默认值是null而不是空字符串?。您可以查看此内容以更多地了解进行此更改的原因。
根据@Anton:c# 8.0
您可以打开空检查以避免NullReferenceException
并设置为引用类型默认值而不是null
我决定从@Rahul Sharma和@rhytonix 的答案中进行总结,并为您提供示例和更详细的解释。
- 为什么当我在 Ajax 中发送空值时,我的控制器中得到空值?
这只是因为MVC 2.0
默认将字符串初始化为 null。更准确地说,如果一个empty
字符串没有值,那么 .NET 将设置它的默认值。默认字符串(属于引用类型)是null
。
更多详细信息,请参阅模型字符串属性绑定重大更改
- 有没有更好、更优雅的方法来解决我的问题,如下所示?
有一些方法可以将 String 属性绑定为string.Empty
而不是null
1. 从 C# 6 开始,您可以使用DefaultValueAttribute为自动属性设置初始值,如下所示
public string LastName => string.Empty;
Run Code Online (Sandbox Code Playgroud)
基本上,这种方式与帖子中提到的OP解决方案相同,只是更优雅。
IModelBinder
2.通过继承内部对象DefaultModelBinder
并将其值更改为 false 来自定义默认实现。ConvertEmptyStringToNull
ModelMetaData
public sealed class EmptyStringModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
return base.BindModel(controllerContext, bindingContext);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Application_Start()
方法中Global.asax.cs
你需要像下面那样完成
protected void Application_Start()
{
ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder();
RegisterRoutes( RouteTable.Routes );
}
Run Code Online (Sandbox Code Playgroud)
3.使用DisplayFormatAttribute.ConvertEmptyStringToNull 属性,如下所示
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string LastName { get; set; }
Run Code Online (Sandbox Code Playgroud)
仅仅因为在ModelMetadata中
true
如果空字符串值自动转换为null
; 否则,false
。默认为true
归档时间: |
|
查看次数: |
12114 次 |
最近记录: |