对于想了解MVC4ModelViewController分离成独立项目的读者,本文将是一篇不可错过的文章,我们将详细介绍mvc怎么分层,并且为您提供关于(转)Model-View-Controller
对于想了解MVC4 Model View Controller分离成独立项目的读者,本文将是一篇不可错过的文章,我们将详细介绍mvc怎么分层,并且为您提供关于(转)Model-View-Controller (MVC) with JavaScript、asp.net-mvc – ASP.NET MVC,将Model从View传递给Controller、asp.net-mvc – MVC4将复杂对象从View传递到Controller,新视图不呈现、asp.net-mvc-4 – 如何在MVC4 ViewModel,Controller,View中使用Dictionary?的有价值信息。
本文目录一览:- MVC4 Model View Controller分离成独立项目(mvc怎么分层)
- (转)Model-View-Controller (MVC) with JavaScript
- asp.net-mvc – ASP.NET MVC,将Model从View传递给Controller
- asp.net-mvc – MVC4将复杂对象从View传递到Controller,新视图不呈现
- asp.net-mvc-4 – 如何在MVC4 ViewModel,Controller,View中使用Dictionary?
MVC4 Model View Controller分离成独立项目(mvc怎么分层)
适合人群:了解MVC项目的程序员
开发工具:vs2012
开发语言:C#
小项目或功能比较单一的项目可以直接新建一个MVC基本项目类型即可,但随着需求不断迭代,项目的功能模块越来越多,甚至有些模块可以独立开发,这时就要考虑主项目的M/V/C三大部分分离,便于不同角色的工程师专注自己的部分开发、更新及发布部署。
下面从主项目CSDN开始,逐步实现M/V/C三大部分的分离:
一、新建一个MVC4主项目,项目名称是CSDN,如图示:
假设主项目CSDN是官网站点,即用户输入官网域名直接访问打开的站点,默认打开的页面是首页(http://www.csdn.net/home/index)。新建Home控制器、Index视图,如图示:
打开app_start/routeconfig.cs文件,确认站点默认是否是/home/index
Index视图页面代码如下:
右击主项目,调试启动运行:
浏览器打开的页面如下:
到此,主项目创建完成,并成功运行。
二、分离控制器,新建一个类库项目,命名CSDN.Controllers.Main
重命名默认创建的类文件class1.cs为HomeController.cs,打开文件留意引用的命名空间,与主项目的Home控制器文件对比
所以在刚创建的类库项目CSDN.Controllers.Main中需引用缺少的命名空间system.web
这些DLL引用的路径,请参考主项目对应的文件,右击-属性查看
按以上方法,逐个引用完成后,如图示:
在主项目CSDN中引用已分离出来的控制器类库CSDN.Controllers.Main
修改routeconfig.cs文件代码如下:
删除主项目原来的controller文件夹及其下的控制器文件,
删除后,编译再次运行主项目CSDN,可见和之前打开的首页面是一样的,说明控制器分离成功。
三、分离数据模型Model,这个比较简单了,同上新建一个类库项目CSDN.Models.Main,class1.cs更名为MainModel.cs,如图示:
在分离的控制器项目中引入Model项目,并修改homecontroller中的index方法代码如下:
在view Index.cshtml页面中显示数据模型的信息,先在主项目CSDN中引入CSDN.Models.Main,并修改view文件夹下的webconfig文件,引入数据模型命名空间:
运行主项目CSDN后,浏览器页面显示如下:
四、分离视图View(重点),到此已经完成了控制器、数据模型的分离,如果只有一个官网模块,似乎没必要分离视图,默认在主项目CSDN中也挺好。但是,如果功能模块增加:后台管理Admin、博客Blog、商城Shop等等,则有必要分离各部分的视图在独立的MVC项目中。
以后台管理Admin举例,先在主项目CSDN中添加Areas/Admin,如图:
因为已经分离了controller、model,所以删除Areas/Admin下默认创建的控制器、数据模型文件夹:
现在有必要新建解决方案文件夹Controllers、Models、Views,把相应的独立项目归类到对应的文件夹下:
在Views文件夹下新建一个MVC4基本项目CSDN.Admin,这个就是后台管理项目,同理可删除其下的控制器、数据模型文件夹:
将主项目中的Areas/Admin/AdminAreaRegistration.cs文件剪切到上面的CSDN.Admin项目根目录下,
按以上分离控制器的方法,分离后台管理模块的控制器,在Controllers文件夹下新建类库项目CSDN.Controllers.Admin
在CSDN.Admin项目中新建视图文件Index.cshtml
该项目中需引用控制器项目CSDN.Controllers.Admin,并修改app_start/routeconfig文件代码如下:
直接运行项目CSDN.Admin,页面显示如下:
但这并不是我们最终目的,我们要的是运行主项目CSDN,浏览器输入http://localhost/admin/home/index时,也可以看到如上页面效果。此时还需修改CSDN.Admin/AdminAreaRegistration.cs文件代码
将CSDN.Admin项目中的View文件夹下的视图文件home整个文件夹,复制到主项目CSDN/Areas/Admin/Views下:
在主项目CSDN中引用项目CSDN.Admin,然后运行主项目,默认还是打开之前的官网页面,此时接着在浏览器URL输入/admin/home(或/admin/home/index)回车,即可看到后台管理页面。
源代码下载地址:http://download.csdn.net/detail/cdblh/9840202
此文档下载地址:http://download.csdn.net/detail/cdblh/9840201
还可以继续优化,比如:
1. 手动复制视图文件到主项目中,可以配置生成事件自动完成。
2. 主项目发布后,Areas下的模块可以配置独立的二级域名访问http://admin.csdn.net,代替http://www.csdn.net/admin
3. 还可以
(转)Model-View-Controller (MVC) with JavaScript
原文:http://www.alexatnet.com/content/model-view-controller-mvc-javascript
The article describes an implementation of Model-View-Controller software design pattern in JavaScript.
I like JavaScript programming, because it is the most flexible language in the world. With the JavaScript language developers can create applications either in procedural or object-oriented style. It supports almost all programming styles and techniques that I know. I''ve seen procedural, object-oriented, aspect-oriented JavaScript code snippets. A determined developer can even use functional programming techniques in JavaScript applications.
My goal for this article is to write a simple JavaScript component that can show a power of the language. The component is a kind of the HTML ListBox ("select" HTML tag) control with an editable list of items: the user can select item and remove it or add new items into the list. Component will consist of three classes that implement the Model-View-Controller design pattern.
I hope, this article can be just a good reading for you, but it would be much better if you consider running the example and adapting it to you needs. I believe you have everything to create and run JavaScript programs: brains, hands, text editor (notepad), and Internet browser (IE or Firefox).
The Model-View-Controller pattern, which I''m about to use in the code, requires some description here. As you may know, the name of the pattern is based on the names of its main parts: Model, which stores an application data model; View, which renders Model for an appropriate representation; and Controller, which updates Model. Wikipedia defines typical components of the Model-View-Controller architecture as follows:
- Model: The domain-specific representation of the information on which the application operates. The model is another name for the domain layer. Domain logic adds meaning to raw data (e.g., calculating if today is the user''s birthday, or the totals, taxes and shipping charges for shopping cart items).
- View: Renders the model into a form suitable for interaction, typically a user interface element. MVC is often seen in web applications, where the view is the HTML page and the code which gathers dynamic data for the page.
- Controller: Processes and responds to events, typically user actions, and invokes changes on the model and perhaps the view.
The data of the component is a list of items, in which one particular item can be selected and deleted. So, the model of the component is very simple - it is stored in an array property and selected item property; and here it is:
/** * The Model. Model stores items and notifies * observers about changes. */ var ListModel = function (items) { this._items = items; this._selectedIndex = -1; this.itemAdded = new Event(this); this.itemRemoved = new Event(this); this.selectedIndexChanged = new Event(this); }; ListModel.prototype = { getItems : function () { return [].concat(this._items); }, addItem : function (item) { this._items.push(item); this.itemAdded.notify({item: item}); }, removeItemAt : function (index) { var item = this._items[index]; this._items.splice(index, 1); this.itemRemoved.notify({item: item}); if (index == this._selectedIndex) this.setSelectedIndex(-1); }, getSelectedIndex : function () { return this._selectedIndex; }, setSelectedIndex : function (index) { var previousIndex = this._selectedIndex; this._selectedIndex = index; this.selectedIndexChanged.notify({previous: previousIndex}); } };
Event is a simple class for implementing the Observer pattern:
var Event = function (sender) { this._sender = sender; this._listeners = []; }; Event.prototype = { attach : function (listener) { this._listeners.push(listener); }, notify : function (args) { for (var i = 0; i < this._listeners.length; i++) { this._listeners[i](this._sender, args); } } };
The View class requires defining controls for interacting with. There are numerous alternatives of interface for the task, but I prefer a most simple one. I want my items to be in a Listbox control and two buttons below it: "plus" button for adding items and "minus" for removing selected item. The support for selecting an item is provided by Listbox''s native functionality. A View class is tightly bound with a Controller class, which "... handles the input event from the user interface, often via a registered handler or callback" (from wikipedia.org).
Here are the View and Controller classes:
var ListView = function (model, controller, elements) { this._model = model; this._controller = controller; this._elements = elements; var _this = this; // attach model listeners this._model.itemAdded.attach(function () { _this.rebuildList(); }); this._model.itemRemoved.attach(function () { _this.rebuildList(); }); // attach listeners to HTML controls this._elements.list.change(function (e) { _this._controller.updateSelected(e); }); }; ListView.prototype = { show : function () { this.rebuildList(); var e = this._elements; var _this = this; e.addButton.click(function () { _this._controller.addItem() }); e.delButton.click(function () { _this._controller.delItem() }); }, rebuildList : function () { var list = this._elements.list; list.html(''''); var items = this._model.getItems(); for (var key in items) list.append($(''<option>'' + items[key] + ''</option>'')) this._model.setSelectedIndex(-1); } }; var ListController = function (model) { this._model = model; }; ListController.prototype = { addItem : function () { var item = prompt(''Add item:'', ''''); if (item) this._model.addItem(item); }, delItem : function () { var index = this._model.getSelectedIndex(); if (index != -1) this._model.removeItemAt(this._model.getSelectedIndex()); }, updateSelected : function (e) { this._model.setSelectedIndex(e.target.selectedIndex); } };
And of course, the Model, View, and Controller classes should be instantiated. The sample, which you can below, uses the following code to instantiate and configure the classes:
$(function () { var model = new ListModel([''PHP'', ''JavaScript'']); var view = new ListView(model, new ListController(model), { ''list'' : $(''#list''), ''addButton'' : $(''#plusBtn''), ''delButton'' : $(''#minusBtn'') } ); view.show(); }); view source print? <select id="list" size="10"></select><br/> <button id="plusBtn"> + </button> <button id="minusBtn"> - </button>
asp.net-mvc – ASP.NET MVC,将Model从View传递给Controller
public class InputModel { public List<Process> axProc { get; set; } public string ToJson() { return new JavaScriptSerializer().Serialize(this); } } public class Process { public string name { get; set; } public string value { get; set; } }
我在Controller中创建了这个InputModel并将其传递给View:
public ActionResult input() { if (Session["InputModel"] == null) Session["InputModel"] = loadInputModel(); return View(Session["InputModel"]); }
在我的Input.cshtml文件中,我有一些代码来生成输入表单:
@model PROJ.Models.InputModel @using(Html.BeginForm()) { foreach(PROJ.Models.Process p in Model.axProc){ <input type="text" /> @* @Html.TextBoxFor(?? => p.value) *@ } <input type="submit" value="SEND" /> }
现在,当我单击提交按钮时,我想处理放入文本字段的数据.
问题1:我看过这个@ Html.TextBoxFor(),但我真的没有得到这个“stuff => otherstuff”.我得出结论,“otherstuff”应该是我想要写入数据的字段,在这种情况下它可能是“p.value”.但是箭头前面的“东西”是什么?
回到控制器我然后有一个函数用于POST一些调试:
[HttpPost] public ActionResult Input(InputModel m) { DEBUG(m.ToJson()); DEBUG("COUNT: " + m.axProc.Count); return View(m); }
这里Debug只显示如下内容:
{"axProc":[]} COUNT: 0
所以我得到的返回模型是空的.
问题2:我是否在使用@using(Html.BeginForm())做了一些根本性的错误?这不是正确的选择吗?如果是这样,我如何让我的模型充满数据回到控制器?
(我不能在这里使用“@model List< Process>”(因为上面的例子是缩写的,在实际的代码中会有更多的东西).)
我希望有人可以填写我正在忽略的一些细节.
解决方法
@using(Html.BeginForm()) { for(int i=0;i<Model.axProc.Count;i++){ <span> @Html.TextBoxFor(model => model.axProc[i].value) </span> } <input type="submit" value="SEND" /> }
asp.net-mvc – MVC4将复杂对象从View传递到Controller,新视图不呈现
我们使用的模型中大部分数据都是由服务调用填充的,所以显然我们希望将调用保持在最低限度.问题是,当我尝试将模型传递回控制器时,模型中的复杂对象总是变为空.我已经能够使用ajax将数据保留在回调控制器上;但是,我需要操作来返回一个新视图,并且在操作完成后,视图的代码会执行,但是没有重定向(我认为这是ajax的重点,我认为我要求的是一个解决方案将以相同的方式持久保存数据但实际重定向).
这是我的模型:
public class distributionModel { public string typeOfdistribution { get; set; } public Document document { get; set; } public string thumbnailUrl { get; set; } public MergeFieldModel mergeFields { get; set; } } public class MergeFieldModel { public MergeFields documentMergeFields { get; set; } }
这是我正在使用的控制器操作:
public ActionResult Index(distributionModel distributionModel) { distributionModel.mergeFields = new MergeFieldModel() { documentMergeFields = MergeFieldsHelper.GetDocumentMergeFields(distributionModel.document.Id) }; return View("Index",distributionModel); }
我尝试使用href =@Url.Action(“Index”,Model)而不是下面块中的按钮来调用控制器并执行重定向(重定向本身确实有效,但我必须在其中执行另一个服务调用控制器检索与我在调用视图中使用的文档相同的文档)因为模型中的Document对象保持返回为控制器的NULL.
以下是调用控制器并实际返回完整模型的视图部分:我认为我正在寻找的是一种在没有ajax的情况下实现此目的的方法,以便我可以获得重定向到分发/索引页面(这是从distribution / DocumentDetails页面中触发)
<button id="Emaildistribution" data-corners="false" data-theme="a">EMAIL</button> $('#Emaildistribution').click(function () { var model = @Html.Raw(Json.Encode(Model)); $.ajax({ url: '@Url.Action("Index","distribution")',type: 'POST',contentType: 'application/json; charset=utf-8',data: JSON.stringify(model),processData: false,}); });
谢谢,任何帮助将非常感谢.
解决方法
这正是您在ajax调用中所做的:您当前将整个模型转换为json并使用jQuery功能将其再次转换为发布数据.假设您有以下模型,例如:
public class TestModel { public string A { get; set; } public string B { get; set; } }
您的javascript代码将创建一个类似于{A:’值为’,B:’值为B’}的字符串,它将使用jQuery转换为HTTP POST请求:
POST /Controller/Index HTTP/1.1 Host: demo.loc User-Agent: Mozilla/5.0 whatever Content-Type: application/x-www-form-urlencoded; charset=utf-8 A=Value+for+a&B=Value+for+B
因此,将调用Index操作,DefaultModelBinder将值绑定到模型属性.这适用于整数类型,如整数,也适用于复杂类型,例如集合. DefaultModelBinder处理这些类型的转换.
让我们来看看更复杂的模型:
public class ComplexSubModel { public ICollection<string> StringList { get; set; } } public class ComplexModel { public ComplexSubModel SubModel { get; set; } }
DefaultModelBinder还能够绑定以下模型:
POST /Controller/Index HTTP/1.1 Host: demo.loc User-Agent: Mozilla/5.0 whatever Content-Type: application/x-www-form-urlencoded; charset=utf-8 ComplexModel.SubModel.StringList[0]=First+entry&ComplexModel.SubModel.StringList[1]=Second+entry&ComplexModel.SubModel.StringList[2]=Third+entry
这将导致ComplexModel的新实例,其SubModel属性设置为ComplexSubModel的新实例,其属性StringList设置为System.Collection.Generic.List< string>的新实例.包含三个字符串第一个条目,第二个条目和第三个条目
现在您需要做的是将模型属性渲染为隐藏字段,以便它们包含在回发中:
@using (Html.BeginForm()) { @Html.HiddenFor(m => m.SubModel.StringList[0]) @Html.HiddenFor(m => m.SubModel.StringList[1]) @Html.HiddenFor(m => m.SubModel.StringList[2]) }
回发中包含的每个属性都不会为空,但可能是由用户伪造的,因为它们很容易重新传输到服务器,假设它们是在隐藏字段中呈现的.实际上,您无法确定重新传输的值是您之前通过服务调用获取的值.
另一种可能性是将服务调用的结果保存在TempData字典中,该字典实际上将值存储在用户会话中,并在回发操作中重新读取它们时将其销毁,或者直接将值存储在会议:
public ActionResult Index() { // Do service calls #region Variant a TempData["ServiceResultA"] = foo; TempData["ServiceResultB"] = bar; #endregion #region Variant b Session["ServiceResultA"] = foo; Session["ServiceResultB"] = bar; #endregion var model = new distributionModel(); // Set properties and stuff return View("Index",model); } [HttpPost] public ActionResult Index(distributionModel model) { // Read "cached" service calls #region Variant a var foo = (TResultA)TempData["ServiceResultA"]; var bar = (TResultB)TempData["ServiceResultB"]; #endregion #region Variant b var foo = (TResultA)Session["ServiceResultA"]; var bar = (TResultB)Session["ServiceResultB"]; #endregion // Do stuff return RedirectToAction(...); }
这两种变体都有优点和缺点,比如在一个浏览器会话中浏览两个选项卡时可能会出现问题,或者在使用会话状态服务器时需要将类序列化.然而,程序总是一样的:你要么必须这样做
>每次从服务中获取数据时获取数据(价格昂贵)或
>将它们保存在服务器上的任何位置(TempData,Session和stuff)或者其他
>使用表单提交(可以由用户伪造,并不总是很容易).
选择你的毒药.
总结
以上是小编为你收集整理的asp.net-mvc – MVC4将复杂对象从View传递到Controller,新视图不呈现全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
asp.net-mvc-4 – 如何在MVC4 ViewModel,Controller,View中使用Dictionary?
public class EnrollPlanPriceLevelviewmodel { public EnrollPlanPriceLevel EnrollPlanPriceLevels { get; set; } public Dictionary<PriceLevel,decimal> Prices { get; set; } }
我的视图中的代码,但我无法创建查看价格.请帮帮我一个人!
@{ int i = 0; foreach (FCA.Model.PriceLevel p in ViewBag.PriceLevelID) { i = i + 1; <div> @Html.TextBoxFor(model => model.Prices[p],new { @placeholder = "Price" }) </div> } }
我想在Controller中调用Dictionary对象值如何?
解决方法
public class EnrollPlanPriceLevelviewmodel { public EnrollPlanPriceLevel EnrollPlanPriceLevels { get; set; } public Dictionary<string,decimal> Prices { get; set; } }
我的Controller的Get方法应该像这样初始化’Key’和Values.这样您就可以在View中遍历每个keyvalue对.
控制器的GET方法:
public ActionResult Create() { var model = new EnrollPlanPriceLevelviewmodel(); model.Prices = new Dictionary<string,decimal>(); foreach (PriceLevel p in db.PriceLevelRepository.GetAll().ToList()) { model.Prices.Add(p.PriceLevelID.ToString(),0); } return View(model); }
像这样使用Dictionary查看:
<div> @{ foreach (var kvpair in Model.Prices) { <div> @Html.TextBoxFor(model => model.Prices[kvpair.Key],new { @placeholder = "Price" }) @Html.ValidationMessageFor(model => model.Prices[kvpair.Key]) </div> } } </div>
Controller的POST方法:显示字典的值
今天关于MVC4 Model View Controller分离成独立项目和mvc怎么分层的分享就到这里,希望大家有所收获,若想了解更多关于(转)Model-View-Controller (MVC) with JavaScript、asp.net-mvc – ASP.NET MVC,将Model从View传递给Controller、asp.net-mvc – MVC4将复杂对象从View传递到Controller,新视图不呈现、asp.net-mvc-4 – 如何在MVC4 ViewModel,Controller,View中使用Dictionary?等相关知识,可以在本站进行查询。
本文标签: