JsonPropertyAttribute 取消 DisplayAttribute
JsonPropertyAttribute Cancels DisplayAttribute
我有一个模型 class 库,它定义了用于 WebAPI 中的 JSON 序列化以及 ASP.NET MVC 中的模型传输的 DTO。因为它们是这两个函数的模型,所以我的模型 classes 用 DisplayAttribute 和 JsonPropertyAttribute (Newtonsoft.Json) 装饰,以提供人类可读的标签以及完全不同的序列化 属性姓名。我发现用这两个属性装饰的 class 属性丢失了它们的标签,而是显示 属性 名称(例如,"CompanyCode" 而不是 "Company Code")。 DisplayAttribute 和 JsonPropertyAttribute 之间是否存在会导致此问题的已知兼容性问题?也许是没有明确记录的优先顺序?
我真的不想在 MVC 项目中复制我的 classes 只是为了将属性装饰减少到一个。我讨厌重复的代码。这是问题的示例:
public class Store {
// This one doesn't work in Razor:
[Display(Name = "Company Code")]
[JsonProperty(PropertyName = "company_code")]
public string CompanyCode { get; set; }
// This one works in Razor without the JsonPropertyAttribute:
[Display(Name = "Store Name")]
public string Name { get; set; }
}
Razor 视图:
@model MyProject.Models.Store
<div>
@Html.LabelFor(model => model.CompanyCode, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.CompanyCode, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div>
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
</div>
WebAPI 控制器方法:
public HttpResponseMessage GetStore(string companyCode) {
return Request.CreateResponse(HttpStatusCode.OK, new MyProject.Models.Store {
CompanyCode = companyCode,
Name = "New Store"
});
}
UPDATE 由于这两个属性的行为不一致,而且我无法使其正常工作,我决定制作一个带有转换方法的专用 ViewModel class。仅供参考,这是新代码:
public sealed class Store {
[JsonProperty(PropertyName = "company_code")]
public string CompanyCode { get; set; }
public string Name { get; set; }
}
public sealed class StoreModel {
[DisplayName("Company Code")]
public string CompanyCode { get; set; }
[Required]
public string Name { get; set; }
public static StoreModel FromStore(Store store) {
return new StoreModel {
CompanyCode = store.CompanyCode,
Name = store.Name
};
}
public Store ToStore() {
return new Store {
CompanyCode = CompanyCode,
Name = Name
};
}
}
请将 Display 属性更改为 DisplayName:
[DisplayName("Company Code")]
我的完整代码:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[DisplayName("Last Name")]
[JsonProperty(PropertyName = "last_name")]
public string LastName { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var user = new User()
{
Id = 1, Name = "Julio", LastName = "Avellaneda"
};
return View("Index", user);
}
}
public class UsersController : ApiController
{
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, new User
{
Id = 1, Name = "Julio", LastName = "Avellaneda"
});
}
}
如果我在 fiddler 中测试网络 api 端点:
我的观点:
此致,
我有一个模型 class 库,它定义了用于 WebAPI 中的 JSON 序列化以及 ASP.NET MVC 中的模型传输的 DTO。因为它们是这两个函数的模型,所以我的模型 classes 用 DisplayAttribute 和 JsonPropertyAttribute (Newtonsoft.Json) 装饰,以提供人类可读的标签以及完全不同的序列化 属性姓名。我发现用这两个属性装饰的 class 属性丢失了它们的标签,而是显示 属性 名称(例如,"CompanyCode" 而不是 "Company Code")。 DisplayAttribute 和 JsonPropertyAttribute 之间是否存在会导致此问题的已知兼容性问题?也许是没有明确记录的优先顺序?
我真的不想在 MVC 项目中复制我的 classes 只是为了将属性装饰减少到一个。我讨厌重复的代码。这是问题的示例:
public class Store {
// This one doesn't work in Razor:
[Display(Name = "Company Code")]
[JsonProperty(PropertyName = "company_code")]
public string CompanyCode { get; set; }
// This one works in Razor without the JsonPropertyAttribute:
[Display(Name = "Store Name")]
public string Name { get; set; }
}
Razor 视图:
@model MyProject.Models.Store
<div>
@Html.LabelFor(model => model.CompanyCode, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.CompanyCode, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div>
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
</div>
WebAPI 控制器方法:
public HttpResponseMessage GetStore(string companyCode) {
return Request.CreateResponse(HttpStatusCode.OK, new MyProject.Models.Store {
CompanyCode = companyCode,
Name = "New Store"
});
}
UPDATE 由于这两个属性的行为不一致,而且我无法使其正常工作,我决定制作一个带有转换方法的专用 ViewModel class。仅供参考,这是新代码:
public sealed class Store {
[JsonProperty(PropertyName = "company_code")]
public string CompanyCode { get; set; }
public string Name { get; set; }
}
public sealed class StoreModel {
[DisplayName("Company Code")]
public string CompanyCode { get; set; }
[Required]
public string Name { get; set; }
public static StoreModel FromStore(Store store) {
return new StoreModel {
CompanyCode = store.CompanyCode,
Name = store.Name
};
}
public Store ToStore() {
return new Store {
CompanyCode = CompanyCode,
Name = Name
};
}
}
请将 Display 属性更改为 DisplayName:
[DisplayName("Company Code")]
我的完整代码:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[DisplayName("Last Name")]
[JsonProperty(PropertyName = "last_name")]
public string LastName { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var user = new User()
{
Id = 1, Name = "Julio", LastName = "Avellaneda"
};
return View("Index", user);
}
}
public class UsersController : ApiController
{
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, new User
{
Id = 1, Name = "Julio", LastName = "Avellaneda"
});
}
}
如果我在 fiddler 中测试网络 api 端点:
我的观点: