English 中文(简体)
MVC 模型装订为收藏收藏,而收藏并不以 0 指数开始
原标题:MVC Model Binding to a collection where collection does not begin with a 0 index

我试图对收藏中的某个项目属性进行远程验证。 验证对收藏的第一个项目有效。 http 请求验证方法看起来像 :

/Validation/IsImeiAvailable?ImeiGadgets[0].ImeiNumber=123456789012345

然而,在第二个项目上,url看上去像下面的第二个项目,验证无效

/Validation/IsImeiAvailable?ImeiGadgets[1].ImeiNumber=123456789012345

现在我很确定原因, 是因为这个捆绑的圆圆可以 在一个不以零指数开始的收藏中工作。

我的验证方法签字如下:

public JsonResult IsImeiAvailable([Bind(Prefix = "ImeiGadgets")] Models.ViewModels.ImeiGadget[] imeiGadget)

因为我在收藏中传递一个物品......我不得不像这个一样捆绑......然而我真正传递的东西......只是一个单一的价值。

除了把它绑成一个普通的查询字符串之外 我还能处理这个吗?

谢谢 谢谢

编辑: 这是获得 Imei 变量的快速修正, 但我宁愿使用模型绑定 :

string imeiNumber = Request.Url.AbsoluteUri.Substring(Request.Url.AbsoluteUri.IndexOf("=")+1);

编辑:这是我的ImeiGadget类:

public class ImeiGadget
{
    public int Id { get; set; }

    [Remote("IsImeiAvailable", "Validation")]
    [Required(ErrorMessage = "Please provide the IMEI Number for your Phone")]
    [RegularExpression(@"(D*d){15,17}", ErrorMessage = "An IMEI number must contain between 15 & 17 digits")]
    public string ImeiNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}
最佳回答

您可以写一个自定义模型集 :

public class ImeiNumberModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var modelName = bindingContext.ModelName;
        var request = controllerContext.HttpContext.Request;
        var paramName = request
            .Params
            .Keys
            .Cast<string>()
            .FirstOrDefault(
                x => x.EndsWith(modelName, StringComparison.OrdinalIgnoreCase)
            );

        if (!string.IsNullOrEmpty(paramName))
        {
            return bindingContext
                .ValueProvider
                .GetValue(request[paramName])
                .AttemptedValue;
        }

        return null;
    }
}

然后应用到控制器动作:

public ActionResult IsImeiAvailable(
    [ModelBinder(typeof(ImeiNumberModelBinder))] string imeiNumber
)
{
    return Json(!string.IsNullOrEmpty(imeiNumber), JsonRequestBehavior.AllowGet);
}

现在查询字符串将忽略 ImeiGadgets 部件 。

问题回答

If you are posting the whole collection, but have a nonsequential index, you could consider binding to a dictionary instead http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

如果您只重新张贴单项或使用 Get 链接,那么您应该修改

/Validation/IsImeiAvailable?ImeiNumber=123456789012345

public JsonResult IsImeiAvailable(string imeiNumber)

如果您正在向服务器发送单值以进行验证, 那么您的动作方法只应该接受一个 scalar (单值) 参数, 而不是收藏 。 您的 URL 就会像这样( 假设 { controller} /{ action} /{ id} 的默认路由表) :

/Validation/IsImeiAvailable?ImeiNumber=123456789012345

相应的行动方法签字可以这样看:

/* note that the param name has to matchthe prop name being validated */
public ActionResult IsImeiAvailable(int ImeiNumber)

EDIT: which you could then use to lookup whether that particular ID is available.

如果想要更改参数的名称,可以修改路线表,但这个主题不同。

长话短说是,如果您想要验证 < code> ImeiGadget 的 recollation < /em >, 您就会得到或 POST 的完整收藏。 对于单个值来说, 发送或期待全部收藏是没有道理的 。

UPDATE: Based on new info, I would look at where the remote validation attribute is being placed. It sounds like it might be placed on something like an IEnumerable<IMEiGadgets>, like this:

[Remote("IsImeiAvailable", "Validation", " ImeiNumber  is invalid"]
public IEnumerable<ImeiGadget> ImeiGadgets { get; set;}

能否移动该属性并将其修改为 ImeiGadget 类, 以便变成这样?

[Remote("IsImeiAvailable", "Validation", " ImeiNumber is invalid"]
public int ImeiNumber { get; set;}

从理论上讲,你不必改变 HTML 模板或脚本上的任何内容 才能让这个工作成功,如果你也做我以上回答中建议的修改的话。在理论上是的。

除非您需要在 < 坚固 > 的多个地方 < / 坚固 > 上设置这个约束性功能, 并控制 < code> IsImeiAvailable 验证方法, 否则 < em> 我认为 < /em > 创建 < em > 习惯模式绑定器 是 < 强势 > overhead 。

你为什么不尝试一个简单的解决方案 这样,

// need little optimization?
public JsonResult IsImeiAvailable(string imeiNumber)
{
  var qParam = Request.QueryString.Keys
     .Cast<string>().FirstOrDefault(a => a.EndsWith("ImeiNumber"));

  return Json(!string.IsNullOrEmpty(imeiNumber ?? Request.QueryString[qParam]), JsonRequestBehavior.AllowGet);
}

您可以在 < em> 中添加一个额外的隐藏字段。 Index 后缀允许任意索引。

<强 > 查看:

<form method="post" action="/Home/Create">
    <input type="hidden" name="products.Index" value="cold" />
    <input type="text" name="products[cold].Name" value="Beer" />
    <input type="text" name="products[cold].Price" value="7.32" />

    <input type="hidden" name="products.Index" value="123" />
    <input type="text" name="products[123].Name" value="Chips" />
    <input type="text" name="products[123].Price" value="2.23" />

    <input type="hidden" name="products.Index" value="caliente" />
    <input type="text" name="products[caliente].Name" value="Salsa" />
    <input type="text" name="products[caliente].Price" value="1.23" />

    <input type="submit" />
</form>

<强 > 模式:

public class Product{
    public string Name{get; set;}
    public decimal Price{get; set;}
}

<强 > 主计长:

public ActionResult Create(Product[] Products)
{
    //do something..
}

欲了解更多信息,请查阅





相关问题
WebForms and ASP.NET MVC co-existence

I am trying to make a WebForms project and ASP.NET MVC per this question. One of the things I ve done to make that happen is that I added a namespaces node to the WebForms web.config: <pages ...

Post back complex object from client side

I m using ASP.NET MVC and Entity Framework. I m going to pass a complex entity to the client side and allow the user to modify it, and post it back to the controller. But I don t know how to do that ...

Create an incremental placeholder in NHaml

What I want to reach is a way to add a script and style placeholder in my master. They will include my initial site.css and jquery.js files. Each haml page or partial can then add their own required ...

asp.net mvc automapper parsing

let s say we have something like this public class Person { public string Name {get; set;} public Country Country {get; set;} } public class PersonViewModel { public Person Person {get; ...

structureMap mocks stub help

I have an BLL that does validation on user input then inserts a parent(PorEO) and then inserts children(PorBoxEO). So there are two calls to the same InsertJCDC. One like this=>InsertJCDC(fakePor)...

ASP.NET MVC: How should it work with subversion?

So, I have an asp.net mvc app that is being worked on by multiple developers in differing capacities. This is our first time working on a mvc app and my first time working with .NET. Our app does not ...

System.Web.Mvc.Controller Initialize

i have the following base controller... public class BaseController : Controller { protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (...

热门标签