在我的ASP.NET MVC应用程序中,我正在尝试实现以下概念:
http://.../PersonData/Show?id=A5668A31-9AAC-4A14-B471-7C9BA236961D
应显示由给定ID标识的人员的数据。http://.../PersonData/Show
应显示带有表单的视图,我可以在其中输入ID到文本框中。当我提交表单时,浏览器应导航但不发布到上面给出的URL(即表单的方法设置为GET)。http://.../PersonData/Show?id=
)时,ASP.NET MVC模型验证应显示需要该ID的消息。 (启用或不启用JavaScript。)为了实现这一点,我构建了一个这样的模型:
class Model
{
[Required]
public Guid? Id { get; set; }
}
现在我遇到的问题是,当第一次浏览http://.../PersonData/Show
时,ASP.NET模型验证会立即给出一个错误,即ID是必需的,因为它没有区分提交表单的情况一个ID(?id=
)以及第一次调用该操作的情况(根本没有给出id)。
我的想法:
http://.../PersonData/Search
和http://.../PersonData/Show?id=
)来区分首次浏览和空表单提交。http://.../PersonData/Show
和http://.../PersonData/Show?valueGiven=true&id=
)。Request
对象检查操作方法中的网址参数,如果网址中没有该密钥,则清除ModelState
的{{1}}错误。解决此问题的最佳/建议方法是什么?有没有更好的第四种方法?
(有一件事不起作用是为GET操作添加两个具有相同名称的操作方法:
"id"
ASP.NET MVC似乎不允许这样做。)
更新2013-06-25:抱歉,我的示例中有两个错误,ID应该是[HttpGet]
public void Show() { /* return view with initial browsing logic */ }
[HttpGet]
public void Show(Model model) { /* return view with subsequent browsing logic */ }
,而不是字符串;当然,我在我的action方法中绑定Model,因为我需要评估Guid
属性。
这是我的路由配置:
Required
答案 0 :(得分:1)
如果你没有传递id,那么id将为null。如果你用一个值传递id,id将是“”(即空字符串.. String.Empty)
因此,您无法使用Required属性,因为这会生成错误。您必须在控制器中手动检查值。
更好的方法是使用路由约束创建一个特殊路由来处理带有id的版本。此路由中的id不是可选的,但约束将阻止不选择不具有id的路由。
我现在没有能力为你创建和测试这个案例,但这应该会给你一些东西。也许其他人可以鞭打一些东西。
路线约束的信息可以在这里找到:
http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-route-constraint-cs
答案 1 :(得分:1)
如果我要将这两种方法都作为GET,那么我更喜欢你的第一种方法:搜索页面和传入参数的结果页面。如果我希望用户共享链接,这是我喜欢的方法,因为所有参数都在查询字符串中。
另一方面,如果共享不是真正的问题,我希望有一个GET方法来显示表单,然后将其提交给具有相同名称的action方法的POST版本。
答案 2 :(得分:0)
只需在初始show函数中添加if case
[HttpGet]
public void Show(int? id) {
if(id.HasValue) {
/* return view with subsequent browsing logic */
}
else {
/* return view with initial browsing logic */
}
}
编辑: 这可能有用
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequestMatchAnyAttribute : ActionNameSelectorAttribute
{
public string MatchFormKey { get; set; }
public RequestMatchAnyAttribute(string matchAnyFormKeys)
{
this.MatchFormKey = matchAnyFormKeys;
}
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
return controllerContext.HttpContext.Request[MatchFormKey] != null;
}
}
[HttpGet]
public void Show() {
/* default view */
}
[ActionName("Show")]
[RequestMatchAny("Id")]
[HttpGet]
public void ShowEdit(int? id) {
if(id.HasValue) {
/* return edit view */
}
else {
/* return create view */
}
}