locked
How to a . (period) in a http bind variable RRS feed

  • Question

  • User781011338 posted

    I have been working with C# MVC for while now but hadn't come across this scenario because my original project utilised database first development. 

    I have the following:

    Model Class:

    public partial class QuestionType : EntityBase
    {
    public string Type { get; set; }
    }

    public partial class Question : EntityBase
    {

    public string QuestionText { get; set; }

    public virtual QuestionType QuestionType { get; set; }

    }

    public class EntityBase
    {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [Display(Name = "Created")]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy h:m:s tt}")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime Created { get; set; }
    [Display(Name = "Last Updated")]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy h:m:s tt}")]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime LastUpdated { get; set; }
    }

    In the contrtoller:

    public IActionResult Create()
    {
    ViewBag.questionTypes = _context.QuestionTypes.ToList();

    return View();
    }

    In the view:

    <form asp-action="Create">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
    <label asp-for="QuestionText" class="control-label"></label>
    <input asp-for="QuestionText" class="form-control" />
    <span asp-validation-for="QuestionText" class="text-danger"></span>
    </div>
    <div class="form-group">
    <label asp-for="QuestionType.Id" class="control-label"></label>

    <select asp-for="QuestionType.Id" asp-items="@(new SelectList(ViewBag.questionTypes,"Id","Type"))">
    <option>Question Type:</option>
    </select>
    <span asp-validation-for="QuestionType.Id" class="text-danger"></span>
    </div>
    <div class="form-group">
    <input type="submit" value="Create" class="btn btn-primary" />
    </div>
    </form>

    And when collecting:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("QuestionText,QuestionType.Id")] Question question)
    {

    ViewBag.questionTypes = _context.QuestionTypes.ToList();

    if (ModelState.IsValid)
    {

    }
    return View(question);
    }

    Now this all works fine if I just use Id instead of QuestionType.Id but that would be leveraging the Id of the Question not the QuestionType and wouldn't work if there were numerous drop down lists. So how do I access the sub member "QuestionType.Id" because it doesn't bind when I reference it in the second create method.

    Thanks in advance.

    Wednesday, April 1, 2020 12:27 AM

Answers

  • User-854763662 posted

    Hi adenjones@gmail.com ,

    Bind attribute specifies which properties of a model should be included in model binding. In your code , you include the  "QuestionType.Id" in the model binding, but there is no property named "QuestionType.Id" in Question model . 

    For binding the id of QuestionType , I suggest you add a  foreign key property in Question model

    public partial class Question : EntityBase
    {
          public string QuestionText { get; set; }
    
          public int QuestionTypeId { get; set; }
          public virtual QuestionType QuestionType { get; set; }
    
    }

    Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("QuestionText,QuestionTypeId")] Question question)
    {}

    View

    <div class="form-group">
         <label asp-for="QuestionTypeId" class="control-label"></label>
    
         <select asp-for="QuestionTypeId" asp-items="@(new SelectList(ViewBag.questionTypes,"Id","Type"))">
            <option>Question Type:</option>
         </select>
         <span asp-validation-for="QuestionTypeId" class="text-danger"></span>
    </div>

    Best Regards,

    Sherry

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, April 2, 2020 6:18 AM

All replies

  • User-474980206 posted

    the Bind attribute does not support dot notation. the Prefix may work for you, but this is the wrong approach. you should have a post back model with the correct binding attributes on each property, rather than try to override the attributes  in the action parameters.

    Wednesday, April 1, 2020 3:46 PM
  • User781011338 posted

    I don't think I understand your response and if I did understand it I probably wouldn't have needed to ask the question in the first place. I believe I have used the correct binding attribute as, if you look at my model, the Id is a property of the QuestionType and I am using the appropriate dot notation to refer to it.

    Wednesday, April 1, 2020 10:59 PM
  • User-854763662 posted

    Hi adenjones@gmail.com ,

    Bind attribute specifies which properties of a model should be included in model binding. In your code , you include the  "QuestionType.Id" in the model binding, but there is no property named "QuestionType.Id" in Question model . 

    For binding the id of QuestionType , I suggest you add a  foreign key property in Question model

    public partial class Question : EntityBase
    {
          public string QuestionText { get; set; }
    
          public int QuestionTypeId { get; set; }
          public virtual QuestionType QuestionType { get; set; }
    
    }

    Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("QuestionText,QuestionTypeId")] Question question)
    {}

    View

    <div class="form-group">
         <label asp-for="QuestionTypeId" class="control-label"></label>
    
         <select asp-for="QuestionTypeId" asp-items="@(new SelectList(ViewBag.questionTypes,"Id","Type"))">
            <option>Question Type:</option>
         </select>
         <span asp-validation-for="QuestionTypeId" class="text-danger"></span>
    </div>

    Best Regards,

    Sherry

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, April 2, 2020 6:18 AM
  • User781011338 posted

    QuestionType is a class which has an Id attribute. I was trying to reference the encapsulated classes field. 

    Friday, April 3, 2020 7:30 AM
  • User781011338 posted

    Thanks Sherry I have added the property and it works fine now

    Sunday, April 5, 2020 5:44 AM