我对ASP.NET MVC很新,所以如果这是我应该知道的,请原谅我。我还没有看到任何明显的文档,所以这里有:
我有一个LINQ to Entities数据模型和一个MVC项目。我使用了很多javascript / jquery,所以选择通过WebAPI从客户端访问我的数据作为json对象。但是,我不想将所有实体对象属性传递给客户端,因此我在我的MVC项目中添加了单独的模型,我在其中处理MVC模型验证和绑定到我的视图。另外,为了在我的jquery中使用它,我创建了模型的json版本。
这只是项目的开始,我不想错误地开始它。在我的业务层中为每个实体提供三个版本的模型将是一场噩梦!我确信我的项目的整体结构是非常常见的,但是看不到许多开发人员解决这种代码重复问题。必须有更好的方法来实施它。
有什么想法?真的很感激任何意见。
答案 0 :(得分:1)
在回答上面的评论时 - 您可以将javascript viewmodel创建为标准的js对象。我倾向于使用Knockout.js,所以它看起来像这样:
jsController.Resource = function (data) {
self.UserId = ko.observable(data.UserId);
self.FullName = ko.observable(data.Name);
self.RoleName = ko.observable(data.RoleName);
self.RoleId = ko.observable(data.RoleId);
}
然后使用ajax post方法将其发布到您的MVC操作
jsController.addToUndertaking = function (resource, isAsync) {
mylog.log("UndertakingId at post = " + jsController.undertakingId);
var action = $.ajax({
type: "POST",
url: "/TeamMember/AddUserToUndertaking",
data: resource,
cache: false,
async: isAsync
});
action.done(function () {
resource.AllocatedToUndertaking(true);
//Do other funky stuff
});
};
创建MVC操作,使其接受表单集合:
public ActionResult AddUserToUndertaking(FormCollection postedResource)
{
if (Request.IsAjaxRequest() == false)
{
const string msg = "Non ajax request received";
Logger.ErrorFormat(msg);
throw new SecurityException(msg);
}
if (postedResource == null)
{
Logger.Debug("Null resource posted - terminating.");
return new HttpStatusCodeResult(500);
}
var resource = new AllocatedResourceAjaxViewModel(postedResource);
//Do something Funky
return new HttpStatusCodeResult(200);
}
然后从窗体集合中创建MVC视图模型(我倾向于通过将窗体集合作为构造函数方法传递给viewmodel来实现此目的。)
public class AllocatedResourceAjaxViewModel
{
public int UserId { get; set; }
public string Name { get; set; }
public string RoleName { get; set; }
public int RoleId { get; set; }
public AllocatedResourceAjaxViewModel()
{}
public AllocatedResourceAjaxViewModel(NameValueCollection formData)
{
UserId = JsFormDataConverter.Int(formData["UserId"]);
Name = Convert.ToString(formData["FullName"]);
RoleName = Convert.ToString(formData["RoleName"]);
RoleId = JsFormDataConverter.Int(formData["RoleId"]);
}
}
由于你的javascript VM中的null int会导致传递一串'undefined',你需要一个转换器方法来安全地提取非字符串。
public static class JsFormDataConverter
{
public static bool Boolean(string formValue, bool defaultValue = false)
{
if (formValue.ToLower() == "true") return true;
if (formValue.ToLower() == "false") return false;
return defaultValue;
}
public static int Int(string formValue, int defaultValue = 0)
{
int result;
return int.TryParse(formValue, out result)
? result
: defaultValue;
}
}
然后你去。我相信你可以改进上述内容,但这会让你前进。
答案 1 :(得分:0)
我一直以来的工作方式就是你有你的模型,例如订单& OrderLines,它存储您的所有数据,并通过SQL直接从数据库获得水分,或者(通常是现在)通过NHM或实体框架等ORM进行水合。
然后使用ViewModels - 这些用于将数据从应用程序传输到视图 - 直接,即绑定到OrderViewModel的强类型视图或通过返回JsonResult的操作。
OrderViewModel不是Order的重复,因为它只能保存需要在屏幕上显示的数据(如果您有许多不同的视图以不同的方式显示订单,那么有很多可以完全接受不同的ViewModels -one,每个视图只包含每个视图所需的字段)。 ViewModels也不应包含除其他ViewModel之外的任何复杂类型。这有助于防止意外的数据访问(考虑安全性和性能)。
所以给定
public class Order
{
public int Id { get; set; }
public DateTime OrderDate { get; set; }
public User User { get; set; }
public string Description { get; set; }
public List<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{
public int Id { get; set; }
public Order Order { get; set; }
public String Description { get; set; }
public int Quantity { get; set; }
public int Weight { get; set; }
public int Price { get; set; }
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
您可以拥有两个ViewModel
public class OrderViewModel
{
public int ID { get; set; }
public List<OrderLineViewModel> OrderLines { get; set; }
public DateTime OrderDate { get; set; }
public int UserId { get; set; }
public string Description { get; set; }
}
public class OrderLineViewModel
{
public int Id { get; set; }
public int OrderId { get; set; }
public String Description { get; set; }
public int Quantity { get; set; }
public int Weight { get; set; }
public int Price { get; set; }
}
然后可以根据需要将视图模型序列化为JSON,或使用验证属性等标记。