您的位置:首页 > 编程语言 > ASP

ASP.NET MVC---项目中用到的扩展

2011-02-22 16:19 513 查看
摘要:本人用ASP.NET MVC开发网站已经有半年的时间了(半年的web开发经验,之前没有做过web开发,呵呵),项目中摸爬滚打,多少也积累了一些经验。写出来,一是自己的总结,二是各位大拿给提提意见。

1、关于页面中有多个Submit按钮的实现。

  如果您的view要显示一些列表,那么对应的URL可能是这样:/Product/List,view的名字就是List,如果您对应的Action名称也使用List,显然不是很明智,因为这个Action使用一个动词的形式更好,比如:GetList,那么您就需要用到

ActionNameAttribute


,对于的Action写成这样

[ActionName("Test")]
public ActionResult Index()


页面中有多个Submit按钮,提交的时候如何确定执行哪个Action呢?我们可以和ActionNameAttribute一样继承ActionNameSelectorAttribute,通过这个选择器来实现页面多个Submit按钮的提交。

因为被点击的Submit标签(name和value值)会post到服务器(可用状态下),所以在view里面给每一个Submit的name属性设置一个值即可。对于的Action写法如下:

[AcceptVerbs(HttpVerbs.Post), MultiSubmitButtonSelector("SearchTest")]
public ActionResult SearchTest()


MultiSubmitButtonSelector的实现和MVC已有的ActionNameAttribute实现类似,具体代码如下:

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class MultiSubmitButtonSelectorAttribute : ActionNameSelectorAttribute
{
public string SubmitButtonName { private set; get; }

public MultiSubmitButtonSelectorAttribute(string submitButtonName) { SubmitButtonName = submitButtonName; }

public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
{
if (string.IsNullOrEmpty(SubmitButtonName))
{
return false;
}
return controllerContext.HttpContext.Request.Form[SubmitButtonName] != null;
}
}


即:遍历Controller中所有具有ActionNameSelectorAttribute特性的Action,用其标注的SubmitButtonName对post进来的数据进行取值操作,如果有值,说明Submit对应的正是这个Action。如果遍历结束,依然找不到需要执行的Action,那么会执行该Form要提交到的Action。

这样就解决了,一个Form里面有多个submit的情况,需要注意的是,当submit被点击之后不能将其变为不可用,否则无法将该submit提交到服务器端,也就找不到对应的Action了。

2、生成并导出Excel(CSV)

这样的方法,默认的框架里面并没有提供,我们要自己动手。我在项目里面使用的生成Excel(CSV)的算法请看这里。你可以这样定义一个Action:

public void ExportExcel()
{
//生成Excel代码
}


然后输出Excel文件,这样做并不是很好,不利于单元测试。

而MVC框架非常容易扩展,我们只需要继承ActionResult,实现里面的方法:public override void ExecuteResult(ControllerContext context),和其它的ActionResult一样即可。实例代码如下:

HandleErrorExtensionsAttribute

public class HandleErrorExtensionsAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
LogError(filterContext);

if (filterContext.HttpContext.Request.IsAjaxRequest())
HandleAjaxError(filterContext);
else
base.OnException(filterContext);
}

/// <summary>
/// 记录错误日志
/// </summary>
/// <param name="filterContext"></param>
private void LogError(ExceptionContext filterContext)
{
ILog log = LogHelper.GetInstance();

string errorMsg = string.Format("Controller: {0}|Action: {1}|id: {2}|Message: {3}|StackTrace:{4}",
filterContext.RouteData.Values["controller"], filterContext.RouteData.Values["action"],
filterContext.RouteData.Values["id"], filterContext.Exception.Message, filterContext.Exception.StackTrace);

log.AddLog(errorMsg, DateTime.Now);
}

/// <summary>
/// 处理Ajax请求的错误
/// </summary>
/// 多数代码来自MVC框架,只是将ActionResult改成json
/// <param name="filterContext"></param>
private void HandleAjaxError(ExceptionContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}

// If custom errors are disabled, we need to let the normal ASP.NET exception handler
// execute so that the user can see useful debugging information.
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}

Exception exception = filterContext.Exception;

// If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
// ignore it.
if (new HttpException(null, exception).GetHttpCode() != 500)
{
return;
}

if (!ExceptionType.IsInstanceOfType(exception))
{
return;
}

filterContext.Result = new JsonResult() { Data = string.Format("系统发送错误, {0}", filterContext.Exception.Message) };
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;

// Certain versions of IIS will sometimes use their own error page when
// they detect a server error. Setting this property indicates that we
// want it to try to render ASP.NET MVC's error page instead.
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}


对于代码:filterContext.HttpContext.Request.IsAjaxRequest()是MVC提供的判断一个请求是不是AJAX请求的方法,代码很简单,自己看一下就行了。之所以这样判断是因为现在的JavaScript类库在进行AJAX请求的时候都会在head里面加入表示是AJAX请求的信息。

其余代码很清楚,就不多解释了。

一期的东西就写这么多暂时,MVC是一个很灵活,扩展性很好的框架,只要需要,你完全可以自定义很多东西。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: