4

Summary

I am posting an object array to my asp.net-mvc backend and I generate the "Key" based on some user input and i just realized that it doesn't work if the user enters a carriage return.

Details:

So I have a form and one of my elements is an array of objects (called Deliverables)

 public class FormPost
 {
       public int Id {get;set;}
       public string ProjectName {get;set;}
       public List<Deliverable> Deliverables {get;set;}
 }

 public class Deliverable
 {
      public int Id {get;set;}
      public string Name {get;set;}
      public DateTime MilestoneDate {get;set;}
 }

I have read Phil Haack's blog post around how to do correct model binding for non sequencial object arrays here.

I am simplifying my question but i am basically using textboxes and the model binding recommendation by using something like this

  <input type="text" name="Deliverables.Index" value="First">
  <input type="text" name="Deliverables[First].Id" value="100">
  <input type="text" name="Deliverables[First].Name" value="Name">
  <input type="text" name="Deliverables[First].MilestoneDate " value="1-Jan-2104">

  <input type="text" name="Deliverables.Index" value="Second">
  <input type="text" name="Deliverables[Second].Id" value="88">
  <input type="text" name="Deliverables[Second].Name" value="Second Name">
  <input type="text" name="Deliverables[Second].MilestoneDate " value="31-Jan-2104">

So in this case I am going to have 2 entries in the Deliverables array given the textboxes above

My question is focused on what are valid values for the Index. In the case above I am using "First" and "Second" which work fine but if i have a carriage return in that string the item fails to post.

My question is "can I really use anything here?" I guess I can strip out the carriage returns on the javascript side but started thinking if there were other characters that would also fail to post.

leora
  • 188,729
  • 360
  • 878
  • 1,366
  • why do you _generate the "Key" based on some user input_? Why not just create the indexer based on the loop? –  Oct 20 '14 at 04:57
  • Absolutely you can have a "carriage return" as part of the key for a name-value pair. All characters have "ascii" representations. I think char 13 is "new line" which is what tends to be represented as "carriage return". But most importantly, in response to your Q, any character that can be stored can be a part of a name/value pair. Even special chars like single or double quotes -- that's why we have escapes within string defs. – Dave Alperovich Oct 20 '14 at 05:25
  • to clarify, its a carriage return for the index name itself (not just any key value pair) – leora Oct 20 '14 at 15:46
  • 2
    @leora. I have tried to recreate you problem by 1. manually including a carriage return using `value="a\rx"` and `name="Deliverables[a\rx].Id"}`, 2. by generating them from a ViewBag property (tried `\r`, `\r\n` and `Environment.NewLine`) and 3. including a ` –  Oct 21 '14 at 03:40
  • @Stephen Muecke - this line seems to fix my problem if that helps identify the issue: originalString.replace(/(\r\n|\n|\r)/gm, ""); – leora Oct 24 '14 at 10:32
  • I don't understand why you would be letting the user generate the key.. use the BeginCollectionItem helper (https://www.nuget.org/packages/BeginCollectionItem/) it generates guids for all the list keys for you and makes the whole process of posting complex object lists much easier. –  Oct 24 '14 at 11:17
  • I am not sure where the carriage return is that is causing form post failure. Is it on the `.Index` or `.Id` input values? If it's on `.Index`, then why are you assigning a value with a carriage return in it? It indeed fails to post when there is a carriage return. Note this field should be `hidden` so that your users cannot miss it up and you can assign a valid unique value for it. `` – Alaa Masoud Oct 24 '14 at 12:30
  • @leora. I don't believe the carriage return and/or new line itself is the issue (it posts back fine so long as the key is used both as the `value` of the `Index` property and as the indexer within the `name` attribute). The real question is why are you using a user defined indexer that contains a carriage returns. Typically for existing items you use the loops indexer `for (int i = 0; i < myCollection.Count;i++) { ...` For dynamically created new items a good solution is to use `(new Date()).getTime()` to generate a unique key. –  Oct 24 '14 at 20:29
  • have a look at [link](http://stackoverflow.com/questions/895659/how-do-i-block-or-restrict-special-characters-from-input-fields-with-jquery), answer from KevSheedy – harishr Oct 26 '14 at 16:11

2 Answers2

2

The best practice for this should be to use numbers as the index of your array, that would save you a lot of trouble. A second good practice would be not to allow the user input to set your keys, but if it has to be done, you may use replace as you mentioned with some Regular Expressions to avoid the app to crash.

Kutyel
  • 8,575
  • 3
  • 30
  • 61
0

In the pipeline request ASP.NET MVC takes in a FormCollection object. This is a key / value pair dictionary.

My educated guess is that it would work with anything that is a string type for the key and value pair.

http://msdn.microsoft.com/en-us/library/system.web.mvc.formcollection%28v=vs.118%29.aspx

beautifulcoder
  • 10,832
  • 3
  • 19
  • 29
  • So i found out that they had a carriage return in what they typed. When i removed it then it worked fine to post. Does that make sense on why that would be an issue? – leora Aug 19 '14 at 21:25
  • Where was the carriage return? HTML is designed to be fault tolerant so it might have mucked it up. – beautifulcoder Aug 19 '14 at 22:22
  • I updated the question now that i have isolated the issue to a carriage return. let me know if you have any questions – leora Aug 19 '14 at 22:53