2010-12-27 11 views
5

Aby obsługiwać starszą aplikację działającą w terenie, potrzebuję mojej aplikacji ASP.NET MVC do zwrócenia pustej odpowiedzi, która również ma Content-Type. Jeden z IIS, ASP.NET lub ASP.NET MVC usuwa mój Content-Type, gdy wysyłam odpowiedź zerową. Czy jest jakiś sposób obejścia tego?Ustawianie zawartości-Typ pustej odpowiedzi w ASP.NET MVC

(Choć nie wymagając pustą odpowiedź z zestawem Content-Type byłoby oczywiście idealnym rozwiązaniem, gdy klienci są już tam, a wiele z nich nie może zostać zmodernizowane.)

EDIT: Ponieważ nie było prośba o kod: Przekazuję prośbę z nowej aplikacji internetowej do tej, na której polegają starsi klienci. Aby to zrobić, mam podklasę o nazwie ActionResult o nazwie LegacyResult, którą można po prostu zwrócić dla metod, które muszą być obsługiwane przez stare oprogramowanie. Jest to istotny element jego kodu:

public override void ExecuteResult(ControllerContext context) 
    { 
     using (var legacyResponse = GetLegacyResponse(context)) 
     { 
      var clientResponse = context.HttpContext.Response; 
      clientResponse.Buffer = false; 
      clientResponse.ContentType = legacyResponse.ContentType; /* Yes, I checked that legacyResponse.ContentType is never string.IsNullOrEmpty */ 
      if (legacyResponse.ContentLength >= 0) clientResponse.AddHeader("Content-Length", legacyResponse.ContentLength.ToString()); 

      var legacyInput = legacyResponse.GetResponseStream(); 
      using (var clientOutput = clientResponse.OutputStream) 
      { 
       var rgb = new byte[32768]; 
       int cb; 
       while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0) 
       { 
        clientOutput.Write(rgb, 0, cb); 
       } 
       clientOutput.Flush(); 
      } 
     } 
    } 

Jeśli legacyInput ma dane, a następnie Content-Type jest ustawiony prawidłowo. W przeciwnym razie nie jest. Mogę faktycznie zablokować stary backend, aby wysłać pustą odpowiedź v. Niepustą na dokładnie to samo żądanie i obserwować różnicę w Fiddler.

EDIT 2: wywiercenie z reflektorem ujawnia, że ​​jeśli nagłówki nie zostały napisane w czasie, HttpResponse.Flush nazywa, następnie Flush zapisuje je we własnym zakresie nagłówków. Problem polega na tym, że wypisuje tylko niewielki podzbiór nagłówków. Jednym z brakujących jest Content-Type. Wygląda więc na to, że jeśli uda mi się wymusić nagłówki w strumieniu, mogę uniknąć tego problemu.

+0

Pokaż swój kod, proszę. –

+0

Zastanawiam się, czy to Flushing the empty stream? Co się stanie, jeśli skomentujesz wszystko po ustawieniu 'ContentType'? –

+0

Komentowanie wszystkiego po "ContentType" nie ma znaczenia; zachowanie jest takie samo. To kończy się, ponieważ 'Flush' nadal jest wywoływany, ale przez gdziekolwiek w stosie ASP.NET. (Innymi słowy, wygląda na to, że linia mogłaby zostać usunięta bez żadnych skutków ubocznych, ale to też nie zmienia zachowania). –

Odpowiedz

8

Trzeba oszukać odpowiedź do pisania nagłówków, przez fałszywie informując go tam treści, a następnie suppressing it:

/// [inside the writing block] 
var didWrite = false; 
while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0) 
{ 
    didWrite = true; 
    clientOutput.Write(rgb, 0, cb); 
} 
if (!didWrite) 
{ 
    // The stream needs a non-zero content length to write the correct headers, but... 
    clientResponse.AddHeader("Content-Length", "1"); 
    // ...this actually writes a "Content-Length: 0" header with the other headers. 
    clientResponse.SuppressContent = true; 
}