views:

422

answers:

4

I have a BarEditor.ascx, that can be called from diffent places.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyApp.Models.Bar>" %>
<%= Html.TextBox("a") %>
...

Now consider I need to edit two objects on one page Edit.aspx

    <form action="update">
        <div>
            <% Html.RenderPartial("BarEditor", ViewData["bar"]); %>
        </div>
        <div>
            <% Html.RenderPartial("BarEditor", ViewData["baz"]); %>
        </div>

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

This submits:

a=1&a=2

I need it to be:

bar.a=1&baz.a=2

So we can process it with

public ActionResult Update(Bar bar, Bar baz)
{
    ...
}

What is a best way to write reusable BarEditor.ascx that can generate prefixes for controls names?

A: 

I would pass a string ("baz" or "bar", etc) with my ViewData when calling the user control. Have the html.textbox get its name from the text passed and its value from the value passed.

mikerennick
Let me be more specific...the control could accept a simple class (textboxdata{}) that has two properties: textboxName, textboxValue. Prior to calling RenderPartial, instantiate the object and then pass it to the control. You could create a enumerable list of the "textboxData" objects in your controller, so as to avoid this kind of action in the view.
mikerennick
A: 

You should to learn about Model Mapping in ASP.Net MVC. Everything in the asp.net mvc page will be rendered to html control therefore don't distinguish between controls in <% Html.RenderPartial("BarEditor", ViewData["bar"]); %> and <% Html.RenderPartial("BarEditor", ViewData["baz"]); %>

Linh
A: 

Why not create a model for the view? Your view would then need to be a strongly typed view using the data class FormView.

public class FormView
{
    string Bar {get; set;}
    string Baz {get; set;}
}

Then in your view you can use

<form action="update">
    <div>
        <% Html.RenderPartial("BarEditor", Model.Bar); %>
    </div>
    <div>
        <% Html.RenderPartial("BarEditor", Model.Baz); %>
    </div>

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

Your controller becomes

public ActionResult Update(FormView MyForm)
{
    ... = MyForm.Bar;

    ... = MyForm.Baz;
}
37Stars
alex2k8
37Stars
May be you are talking about some similar scenarios like: <%= Html.TextBox("Bar.a") %>, <%= Html.TextBox("Baz.a") %>. But notice, I am talking about RenderPartial. BTW, I think there is no solution without writing custom RenderPartial.
alex2k8
+2  A: 

just create a ViewModel class for your BarEditor and make it strongly typed to this new class

e.g.

namespace ViewModel {
    public class BarEditor {

        string Prefix { get; set; }
        Models.Bar Bar { get; set; }
    }
}

now you create your textbox in BarEditor.ascx like this

<%= Html.TextBox(Model.Prefix + ".a") %> 

and in your view you include the BarEditor like that

 <form action="update">
    <div>
        <% Html.RenderPartial("BarEditor", new ViewModel.BarEditor { Prefix = "Bar", Bar = ViewData["bar"]}); %>
    </div>
    <div>
        <% Html.RenderPartial("BarEditor", new ViewModel.BarEditor { Prefix = "Baz", Bar = ViewData["baz"]}); %>
    </div>
    <input type="submit" value="Submit" />
 </form>

hth

marc.d
Yes, it looks like some thing like this is a way to go. It also can be a custom RenderPartial implementation. Let's consider this as answer :-)
alex2k8