El problema que tengo es que &X-Requested-With=XMLHttpRequest&_=1462736803425 se sigue agregando a mi url porque está aparte de la cadena de consulta. ¿Hay alguna manera de evitar que se convierta en una cadena de consulta y haga Ajax.BeginForm sin hacer un 'pirateo'?

@using (Ajax.BeginForm("Search", "Filter", new { Area = "Music" }, new AjaxOptions { HttpMethod = "Get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "body-wrapper", OnSuccess = "updateHistory" }, new { @id = "search-form" }))
{
       <div>
           <i class="fa fa-search"></i>
           <input type="search" placeholder="Search" id="search" name="searchString" />
       </div>
}

public ActionResult Search(string searchString)
{
    //do stuff
    return PartialView();
}

En la página de vista parcial, obtengo la ruta y la consulta:

@Html.HiddenFor(x => Request.Url.PathAndQuery)

El valor de Request.Url.PathAndQuery es: http://localhost:1526/Music/Search?searchString=maid&X-Requested-With=XMLHttpRequest&_=1462736803425

Y luego actualice la url usando History.js:

function pushState(target) {
    manualStateChange = false;
    History.pushState(null, null, $("#Request_Url_PathAndQuery").val());
}

enter image description here

5
Martin Dawson 8 may. 2016 a las 22:53

3 respuestas

La mejor respuesta

Con lo que me fui es esto, aunque es un truco y no es realmente deseable, así que si alguien encuentra una mejor manera, por favor dígalo. Elimina el parámetro de cadena de consulta de la url, funciona porque xhr siempre se agrega al final.

function pushState(target) {
    //Remove the queryString parameter of xhr that gets appened in 117 of ajax-unobtrusive.js
    var index = target.indexOf("?X-Requested-With");
    if (index === -1) 
        index = target.indexOf("&X-Requested-With");

    target = target.replace(target.substring(index), "");

    manualStateChange = false;
    History.pushState(null, $("input#Title").val(), target);
}

Editar. Nueva respuesta basada en el comentario de Mike:

@using (Html.BeginForm("Index", "Search", new { area = "Media" }, FormMethod.Get, new { @id = "search", data_url = Url.Action("SetSearchTags", "Search", new { Area = "Media" }) }))
{
    <i class="fa fa-search"></i>
    <input type="search" placeholder="Search" id="search" name="searchString" />

    <div id="filter" name="filter">
        <span><strong>Syntax</strong></span>

        @foreach (var item in SearchContext.SearchFilters)
        {
            <div id="filter-@item">
                @Html.DisplayFor(x => item)
            </div>
        }
    </div>
}

$("form#search").submit(function (event) {
    event.preventDefault();

    var $form = $(this);
    var searchString = $form.find("input[type='search']").val();
    var url = $form.attr("action");
    var method = $form.attr("method");

    $.ajax({
        url: url,
        data: { searchString: searchString },
        method: method,
        success: function (data) {
            $('#body-content').html(data);
            updateHistory(true);
        }
    });
});

function updateHistory(useQuery) {
    var path = (useQuery === true) ? $("#Request_Url_PathAndQuery").val() : $("#Request_Url_AbsolutePath").val();

    pushState(path);
};

Básicamente, donde sea que necesite parámetros de cadena de consulta, solo tendré que hacerlo manualmente en jquery y no usar ayudantes.

0
Martin Dawson 14 may. 2016 a las 17:21

Sin alterar el archivo fuente de "jquery-ajax- unobtrusive.js ", no es fácil. El problema aquí está en la línea 117:

options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

Es agregar esos datos antes de enviar la solicitud. Eso es un poco desagradable, especialmente porque ese valor debería ser un encabezado HTTP, no parte de los datos, en mi opinión.

podría ser una forma de eliminarlo agregando una opción beforeSend a la solicitud ajax del formulario. A saber, te gustaría definir una función:

function removeExtraData(jqXHR, settings) {
  if (settings.data.hasOwnProperty('X-Requested-With')) {
    delete settings.data['X-Requested-With']; // or settings.data['X-Requested-With'] = undefined;
  }
}

Luego puede usar eso agregando un atributo HTML data-ajax-begin con el valor removeExtraData a su formulario. No lo he verificado, y han pasado algunos años desde que usé WebForms, por lo que no tengo una configuración para probar.

La parte _=1462736803425 de la URL se agrega automáticamente por jQuery porque la solicitud está configurada para que no se almacene en caché. Aparentemente puede deshacerse de eso agregando un atributo HTML a su formulario con el nombre data-ajax-cache y el valor true. Por supuesto, eso puede terminar almacenando en caché su solicitud, lo que puede no ser deseable.

4
Heretic Monkey 10 may. 2016 a las 20:45

Creo que puede resolver esto sobrescribiendo la ruta de URL.

En Application_BeginRequest (), puede verificar cualquier condición que necesite y usar context.RewritePath () y eliminar los parámetros innecesarios.

Algo como esto:

    protected override void Application_BeginRequest(object sender, EventArgs e)
    {
        base.Application_BeginRequest(sender, e);
        var urlpath = HttpContext.Current.Request.Url.PathAndQuery; //Modify this based on condition
        if(<condition>)
            Context.RewritePath(<updatedpath>);
    }

Esto puede resolver su problema, pero realmente no puedo decir si este es un buen enfoque.

0
Krishna Chaithanya Muthyala 11 may. 2016 a las 15:54