Модель ASP.NET MVC 3 не имеет информации о обратной передаче - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть вид с несколькими частичными видами, которые я связываю с моей моделью.По какой-то причине, когда я публикую сообщение, модель пуста, и я не уверен, почему.

Ниже моя ViewModel.

public class IndexViewModel
{
    public bool AdvancedSearchOption { get; set; }
    public bool ForceAdvanced { get; set; }
    public bool ForceSimple { get; set; }
    public string SimpleSearchCriteria { get; set; }
    public string CustomerNumberCriteria { get; set; }
    public string AccountNumberCriteria { get; set; }
    public string NameCriteria { get; set; }
    public string PhoneNumberCriteria { get; set; }
}

Вот мой контроллер.Я заполняю все значения модели представления, потому что я хотел видеть, попали ли значения в частичные представления.Они попадают туда, поэтому проблемы возникают только по почте.

public class HomeController : Controller
{
    private ISecurityRepository SecurityRep;

    public HomeController(ISecurityRepository repo)
    {
        SecurityRep = repo;
    }

    public ActionResult Index()
    {
        IndexViewModel temp = new IndexViewModel();
        temp.AdvancedSearchOption = SecurityRep.DefaultToAdvancedSearch(User.Identity.Name);
        temp.ForceAdvanced = false;
        temp.ForceSimple = false;
        temp.SimpleSearchCriteria = "Testing";
        temp.AccountNumberCriteria = "Acct";
        temp.CustomerNumberCriteria = "Cust";
        temp.NameCriteria = "Name";
        temp.PhoneNumberCriteria = "Phone";
        return View(temp);
    }

    public ActionResult SimpleSearch()
    {
        IndexViewModel temp = new IndexViewModel();
        temp.AdvancedSearchOption = SecurityRep.DefaultToAdvancedSearch(User.Identity.Name);
        temp.ForceAdvanced = false;
        temp.ForceSimple = true;
        temp.SimpleSearchCriteria = "Testing";
        temp.AccountNumberCriteria = "Acct";
        temp.CustomerNumberCriteria = "Cust";
        temp.NameCriteria = "Name";
        temp.PhoneNumberCriteria = "Phone";
        return View("Index",temp);
    }

    public ActionResult AdvancedSearch()
    {
        IndexViewModel temp = new IndexViewModel();
        temp.AdvancedSearchOption = SecurityRep.DefaultToAdvancedSearch(User.Identity.Name);
        temp.ForceAdvanced = true;
        temp.ForceSimple = false;
        temp.SimpleSearchCriteria = "Testing";
        temp.AccountNumberCriteria= "Acct";
        temp.CustomerNumberCriteria= "Cust";
        temp.NameCriteria= "Name";
        temp.PhoneNumberCriteria = "Phone";
        return View("Index", temp);
    }

    [HttpPost]
    public ActionResult Index(IndexViewModel vm, FormCollection formCollection)
    {
        return View();
    }
}

Вот мой взгляд

@model TRIOSoftware.Magnum.Models.IndexViewModel

@{
    ViewBag.Title = "Search";
}

@if ((@Model.AdvancedSearchOption && @Model.ForceSimple != true) || @Model.ForceAdvanced == true)
{
    @Html.Partial("AdvancedSearch")
}
else
{
    @Html.Partial("SimpleSearch")
}

Вот мой частичный вид SimpleSearch.Я думаю, если я смогу заставить это работать, другой пойдет по тому же пути.Я делаю пост в частичном, и я использую jQuery , чтобы сделать это.Я не уверен, что любая из этих вещей может вызвать у меня проблемы или нет.У меня есть только все скрытые предметы, потому что я не знал, не вызывал ли их наличие мои проблемы.

 @model TRIOSoftware.Magnum.Models.IndexViewModel

 <script type="text/javascript">
     $(document).ready(function () {
         $("#DefaultDiv").find("#DefaultAdvanced").click(function () {
             $.post("DefaultSimple");
         });

         $("#SearchSection").find("#SearchButton").click(function () {
             $.post("");
         });
     });
</script>

 @using (Html.BeginForm("Index","Home"))
 {
     @Html.HiddenFor(m => m.ForceAdvanced)
     @Html.HiddenFor(m => m.AdvancedSearchOption)
     @Html.HiddenFor(m => m.ForceSimple)
     @Html.HiddenFor(m => m.AccountNumberCriteria)
     @Html.HiddenFor(m => m.CustomerNumberCriteria)
     @Html.HiddenFor(m => m.NameCriteria)
     @Html.HiddenFor(m => m.PhoneNumberCriteria)

     <div id="DefaultDiv" style="float:right">
         <a id="DefaultAdvanced" href="#" class="ButtonClass">Default Simple Search</a>
     </div>

     <div style="clear:both; margin: auto; width: 800px">
         <img src="../../Content/images/TRIO_transparent_image.gif"; alt="TRIO Software"; style="margin-left:150px; clear:left"/>
             <div style="clear:left; float: left" class="SearchText">
                  @Html.Label("What's your inquiry?:")
                  @Html.EditorFor(m => m.SimpleSearchCriteria, new { style = "width: 400px" })
             </div>
             <div id="SearchSection" style="float: left" class="SearchText">
                 <a href="#"; id="SearchButton" class="ButtonClass"><img src="../../Content/images/Search.gif"; alt="Search"; style="float:left" /></a>
             </div>
             <p style="clear:left;margin-left:400px">
                 @Html.ActionLink("Advanced Search", "AdvancedSearch", null, new { style = "clear:left" })
             </p>

    </div>
 }

Вот HTML-код при просмотре простого поискового частичного представления:

<div id="main">
    <script type="text/javascript">
        $(document).ready(function () {
            $("#DefaultDiv").find("#DefaultAdvanced").click(function () {
                $.post("DefaultSimple");
            });

            $("#SearchSection").find("#SearchButton").click(function () {
                $.post("");
            });
        });
    </script>

    <form method="post" action="/">
        <input type="hidden" value="False" name="ForceAdvanced" id="ForceAdvanced" data-val-required="The ForceAdvanced field is required." data-val="true">
        <input type="hidden" value="False" name="AdvancedSearchOption" id="AdvancedSearchOption" data-val-required="The AdvancedSearchOption field is required." data-val="true">
        <input type="hidden" value="False" name="ForceSimple" id="ForceSimple" data-val-required="The ForceSimple field is required." data-val="true">
        <input type="hidden" value="Acct" name="AccountNumberCriteria" id="AccountNumberCriteria">
        <input type="hidden" value="Cust" name="CustomerNumberCriteria" id="CustomerNumberCriteria">
        <input type="hidden" value="Name" name="NameCriteria" id="NameCriteria">
        <input type="hidden" value="Phone" name="PhoneNumberCriteria" id="PhoneNumberCriteria">
        <div style="float:right" id="DefaultDiv">
            <a class="ButtonClass ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" href="#" id="DefaultAdvanced" role="button"><span class="ui-button-text">Default Simple Search</span></a>
        </div>
        <div style="clear:both; margin: auto; width: 800px">
            <img style="margin-left:150px; clear:left" alt="TRIO Software" ;="" src="../../Content/images/TRIO_transparent_image.gif">
            <div class="SearchText" style="clear:left; float: left">
               <label for="What_s_your_inquiry_:">What's your inquiry?:</label>
               <input type="text" value="Testing" name="SimpleSearchCriteria" id="SimpleSearchCriteria" class="text-box single-line">
            </div>
            <div class="SearchText" style="float: left" id="SearchSection">
                <a class="ButtonClass ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" id="SearchButton" ;="" href="#" role="button"><span class="ui-button-text"><img style="float:left" alt="Search" ;="" src="../../Content/images/Search.gif"></span></a>
            </div>
            <p style="clear:left;margin-left:400px">
                <a style="clear:left" href="/Home/AdvancedSearch">Advanced Search</a>
            </p>
     </div>
    </form>
</div>

Как мне решить эту проблему?

Ответы [ 3 ]

1 голос
/ 23 февраля 2012

Я думаю, что @ john-h ударил ногтем по голове своим ответом.Однако вы можете уменьшить сложность, которую вы создали для себя.

1) Поскольку ForceSimple и ForceAdvanced являются булевыми, предполагается, что если ForceAdvanced имеет значение true, то это не просто, не так ли?Я не уверен, какая другая логика у вас здесь.

2) Вместо того, чтобы создавать два представления и «отправлять» обратно, чтобы получить правильное, почему бы просто не использовать параметр для установки типа поиска?Или оцените безопасность, чтобы установить, какой из них может выполнять пользователь.Вот пример:

Действия контроллера:

//id is the search type: true is Advanced
public ActionResult Search(bool id) {
    IndexViewModel viewModel = new IndexViewModel {
        /* Do whatever logic here  */
        ForceAdvanced = (id) ? false : true,
        AdvancedSearchOption = id
    };
    return View("search", viewModel);
}

[HttpPost]
public ActionResult Search(IndexViewModel model) {
    //model.SimpleSearchCriteria = "Testing";
    //model.PhoneNumberCriteria = "Phone";
    return View("search", model);
}

Вид поиска:

@using (@Html.BeginForm(new { id = @Model.AdvancedSearchOption })) {
    <div style="clear:left; float: left" class="SearchText">
        @Html.Label("What's your inquiry?:")
        @if (Model.AdvancedSearchOption) {
            <div>
                @* if you really want, load your partial views here *@
                <span>@Html.LabelFor(m => m.NameCriteria)</span>
                @Html.EditorFor(m => m.NameCriteria, new { style = "width: 400px" })
                <span>@Html.LabelFor(m => m.PhoneNumberCriteria)</span>
                @Html.EditorFor(m => m.PhoneNumberCriteria, new { style = "width: 400px" })
            </div>
        }
        else {
             @* if you really want, load your partial views here *@
            @Html.EditorFor(m => m.SimpleSearchCriteria, new { style = "width: 400px" })
        }        
    </div>
    <div>
         <input type="submit" value="Search" />
    </div>   
     @Html.HiddenFor(m => m.ForceAdvanced)
     @Html.HiddenFor(m => m.AdvancedSearchOption)
     @Html.HiddenFor(m => m.ForceSimple)
     @Html.HiddenFor(m => m.AccountNumberCriteria)
     @Html.HiddenFor(m => m.CustomerNumberCriteria)
     @Html.HiddenFor(m => m.NameCriteria)
     @Html.HiddenFor(m => m.PhoneNumberCriteria)    
}
1 голос
/ 22 февраля 2012

Хотя вы выбираете партиал для рендеринга, вы не передаете ему модель.Есть перегруженная версия Html.Partial, которая принимает второй аргумент, который позволяет вам передать ей модель:

@Html.Partial("ViewName", Model);

Так что в вашем случае вы бы использовали это:

@if ((Model.AdvancedSearchOption && Model.ForceSimple != true) || Model.ForceAdvanced == true) 
{ 
    @Html.Partial("AdvancedSearch", Model)  
} 
else 
{ 
    @Html.Partial("SimpleSearch", Model)  
} 

Также обратите внимание, как я удалил @ s, с которыми у вас был префикс Model.Чтобы лучше понять причину, см. Введение в веб-программирование на ASP.NET с использованием синтаксиса Razor и небольшую ссылку на эту же тему, написанную Филом Хааком здесь .

0 голосов
/ 25 февраля 2012

Я попытался явно отправить модель в партиалы, но безуспешно.Я считаю, что частичные представления получают родительскую модель по умолчанию, если ничего не указано, поэтому все, что мне нужно было сделать, это указать тип модели в моих частичках, и я получил информацию.

Я наконец понял этос большим количеством проб и ошибок.Моя проблема была вызвана тем, что я пытался использовать jQuery , чтобы сделать сообщение.Должны быть некоторые другие вещи, которые вам нужно сделать, чтобы обновить модель, делая это таким образом.Как только я изменил его и поместил элемент управления вводом в форму для сообщения, я получил все свои данные из родительского и частичного представления в контроллере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...