Url.Action не так с Knockout + Asp.Net MVC Core 2.2 - PullRequest
1 голос
/ 03 мая 2019

Я пытаюсь сгенерировать таблицу, содержащую ссылку для каждой строки с нокаутом и Asp.Net Core 2.2.На самом деле я хочу, чтобы вся строка была кликабельной позже, хотя в этом примере я добавил ее как поле таблицы.

Хотя путь для @Url.Action("MyAction", "My") генерируется неправильно.Оба они совершенно пусты.В сгенерированной ссылке не отображаются ни контроллер, ни действие.

<tbody data-bind="foreach: searchResults">
  <tr>
    <td data-bind="text: id"></td>
    <td>
      <a data-bind="attr: { href: '@Url.Action("MyAction", "My")/' + id}">
        Click
      </a>
    </td>
    <td data-bind="text: name"></td>
    <td data-bind="text: date"></td>
  </tr>
</tbody>

«My» - это контроллер «MyController».«MyAction» - это имя метода действия, которое я хочу вызвать при нажатии.У меня есть другой контроллер для другого пути.Вот что я пытаюсь использовать:

[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    private readonly IWebServiceFactory webServiceFactory;

    public MyController(IWebServiceFactory webServiceFactory)
    {
        this.webServiceFactory = webServiceFactory;
    }

    // GET: api/MyAction/{GUID}
    [HttpGet("{id:Guid}")]
    public async Task<IActionResult> MyAction(Guid id)
    {
        var result = await webServiceFactory.GetWebService().GetFileAsync(id);
        var memory = new MemoryStream();
        await result .Stream.CopyToAsync(memory);
        memory.Position = 0;
        return File(memory, "application/unknown", result.FileName);
    }
}

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

Я использую Mvc с маршрутом по умолчанию в Startup.cs:

app.UseMvcWithDefaultRoute();

Это фактический вывод, который я получаю:

<a data-bind="attr: { href: '/' + id }" href="/173a4cec-a258-4ebb-d28e-08d6cee0966c">Click</a>

Что я делаюнеправильно?

1 Ответ

1 голос
/ 07 мая 2019

Чтобы Url.Action не пытался отобразить URL, связанный с MVC-представлением, вместо URL-адреса конечной точки Api,
используйте @Url.RouteUrl с именем маршрута, которое было применено к данному методу действия контроллера Api; например. ApiMyMyActionGuidRoute

[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{   
    [HttpGet("{id:Guid}", Name ="ApiMyMyActionGuidRoute")]
    public async Task<IActionResult> MyAction(Guid id)
    {
        // Your implementation goes here ...
    }
}

По вашему мнению, рендеринг URL через @Url.Route.
Обратите внимание, что вам придется применить фиктивное значение Guid для аргумента id, так как этот аргумент является обязательным для метода действия (MyAction(Guid id)).

Поскольку это значение id применяется через привязку Knockout, сначала необходимо удалить фиктивное значение из сгенерированного URL-адреса, прежде чем применять его в выражении Knockout data-bind.

@{  
    var routeUrl = Url.RouteUrl("ApiMyMyActionGuidRoute", new { id = Guid.Empty });
    // routeUrl = "/api/My/00000000-0000-0000-0000-000000000000"
    routeUrl = routeUrl.Substring(0, routeUrl.LastIndexOf("/"));
    // routeUrl = "/api/My"
}
<p><a data-bind="attr: { href: '@routeUrl/' + id }">Click</a></p>

Будет сгенерирована HTML-разметка ниже с правильным URL-адресом конечной точки Api, к которому Knockout будет применять значение аргумента id.

<p><a data-bind="attr: { href: '/api/My/' + id }">Click</a></p>
...